FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
escape130.c
Go to the documentation of this file.
1 /*
2  * Escape 130 video decoder
3  * Copyright (C) 2008 Eli Friedman (eli.friedman <at> gmail.com)
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "libavutil/attributes.h"
23 #include "libavutil/mem.h"
24 
25 #define BITSTREAM_READER_LE
26 #include "avcodec.h"
27 #include "get_bits.h"
28 #include "internal.h"
29 
30 typedef struct Escape130Context {
32 
36 
38  int linesize[3];
40 
41 static const uint8_t offset_table[] = { 2, 4, 10, 20 };
42 static const int8_t sign_table[64][4] = {
43  { 0, 0, 0, 0 },
44  { -1, 1, 0, 0 },
45  { 1, -1, 0, 0 },
46  { -1, 0, 1, 0 },
47  { -1, 1, 1, 0 },
48  { 0, -1, 1, 0 },
49  { 1, -1, 1, 0 },
50  { -1, -1, 1, 0 },
51  { 1, 0, -1, 0 },
52  { 0, 1, -1, 0 },
53  { 1, 1, -1, 0 },
54  { -1, 1, -1, 0 },
55  { 1, -1, -1, 0 },
56  { -1, 0, 0, 1 },
57  { -1, 1, 0, 1 },
58  { 0, -1, 0, 1 },
59 
60  { 0, 0, 0, 0 },
61  { 1, -1, 0, 1 },
62  { -1, -1, 0, 1 },
63  { -1, 0, 1, 1 },
64  { -1, 1, 1, 1 },
65  { 0, -1, 1, 1 },
66  { 1, -1, 1, 1 },
67  { -1, -1, 1, 1 },
68  { 0, 0, -1, 1 },
69  { 1, 0, -1, 1 },
70  { -1, 0, -1, 1 },
71  { 0, 1, -1, 1 },
72  { 1, 1, -1, 1 },
73  { -1, 1, -1, 1 },
74  { 0, -1, -1, 1 },
75  { 1, -1, -1, 1 },
76 
77  { 0, 0, 0, 0 },
78  { -1, -1, -1, 1 },
79  { 1, 0, 0, -1 },
80  { 0, 1, 0, -1 },
81  { 1, 1, 0, -1 },
82  { -1, 1, 0, -1 },
83  { 1, -1, 0, -1 },
84  { 0, 0, 1, -1 },
85  { 1, 0, 1, -1 },
86  { -1, 0, 1, -1 },
87  { 0, 1, 1, -1 },
88  { 1, 1, 1, -1 },
89  { -1, 1, 1, -1 },
90  { 0, -1, 1, -1 },
91  { 1, -1, 1, -1 },
92  { -1, -1, 1, -1 },
93 
94  { 0, 0, 0, 0 },
95  { 1, 0, -1, -1 },
96  { 0, 1, -1, -1 },
97  { 1, 1, -1, -1 },
98  { -1, 1, -1, -1 },
99  { 1, -1, -1, -1 }
100 };
101 
102 static const int8_t luma_adjust[] = { -4, -3, -2, -1, 1, 2, 3, 4 };
103 
104 static const int8_t chroma_adjust[2][8] = {
105  { 1, 1, 0, -1, -1, -1, 0, 1 },
106  { 0, 1, 1, 1, 0, -1, -1, -1 }
107 };
108 
109 static const uint8_t chroma_vals[] = {
110  20, 28, 36, 44, 52, 60, 68, 76,
111  84, 92, 100, 106, 112, 116, 120, 124,
112  128, 132, 136, 140, 144, 150, 156, 164,
113  172, 180, 188, 196, 204, 212, 220, 228
114 };
115 
117 {
118  Escape130Context *s = avctx->priv_data;
119  avctx->pix_fmt = AV_PIX_FMT_YUV420P;
120 
121  if ((avctx->width & 1) || (avctx->height & 1)) {
122  av_log(avctx, AV_LOG_ERROR,
123  "Dimensions should be a multiple of two.\n");
124  return AVERROR_INVALIDDATA;
125  }
126 
127  s->old_y_avg = av_malloc(avctx->width * avctx->height / 4);
128  s->buf1 = av_malloc(avctx->width * avctx->height * 3 / 2);
129  s->buf2 = av_malloc(avctx->width * avctx->height * 3 / 2);
130  if (!s->old_y_avg || !s->buf1 || !s->buf2) {
131  av_freep(&s->old_y_avg);
132  av_freep(&s->buf1);
133  av_freep(&s->buf2);
134  av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
135  return AVERROR(ENOMEM);
136  }
137 
138  s->linesize[0] = avctx->width;
139  s->linesize[1] =
140  s->linesize[2] = avctx->width / 2;
141 
142  s->new_y = s->buf1;
143  s->new_u = s->new_y + avctx->width * avctx->height;
144  s->new_v = s->new_u + avctx->width * avctx->height / 4;
145  s->old_y = s->buf2;
146  s->old_u = s->old_y + avctx->width * avctx->height;
147  s->old_v = s->old_u + avctx->width * avctx->height / 4;
148  memset(s->old_y, 0, avctx->width * avctx->height);
149  memset(s->old_u, 0x10, avctx->width * avctx->height / 4);
150  memset(s->old_v, 0x10, avctx->width * avctx->height / 4);
151 
152  return 0;
153 }
154 
156 {
157  Escape130Context *s = avctx->priv_data;
158 
159  av_freep(&s->old_y_avg);
160  av_freep(&s->buf1);
161  av_freep(&s->buf2);
162 
163  return 0;
164 }
165 
167 {
168  int value;
169 
170  if (get_bits_left(gb) < 1+3)
171  return -1;
172 
173  value = get_bits1(gb);
174  if (value)
175  return 0;
176 
177  value = get_bits(gb, 3);
178  if (value)
179  return value;
180 
181  value = get_bits(gb, 8);
182  if (value)
183  return value + 7;
184 
185  value = get_bits(gb, 15);
186  if (value)
187  return value + 262;
188 
189  return -1;
190 }
191 
192 static int escape130_decode_frame(AVCodecContext *avctx, void *data,
193  int *got_frame, AVPacket *avpkt)
194 {
195  int buf_size = avpkt->size;
196  Escape130Context *s = avctx->priv_data;
197  AVFrame *pic = data;
198  GetBitContext gb;
199  int ret;
200 
201  uint8_t *old_y, *old_cb, *old_cr,
202  *new_y, *new_cb, *new_cr;
203  uint8_t *dstY, *dstU, *dstV;
204  unsigned old_y_stride, old_cb_stride, old_cr_stride,
205  new_y_stride, new_cb_stride, new_cr_stride;
206  unsigned total_blocks = avctx->width * avctx->height / 4,
207  block_index, block_x = 0;
208  unsigned y[4] = { 0 }, cb = 0x10, cr = 0x10;
209  int skip = -1, y_avg = 0, i, j;
210  uint8_t *ya = s->old_y_avg;
211 
212  // first 16 bytes are header; no useful information in here
213  if (buf_size <= 16) {
214  av_log(avctx, AV_LOG_ERROR, "Insufficient frame data\n");
215  return AVERROR_INVALIDDATA;
216  }
217 
218  if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
219  return ret;
220 
221  if ((ret = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0)
222  return ret;
223  skip_bits_long(&gb, 16 * 8);
224 
225  new_y = s->new_y;
226  new_cb = s->new_u;
227  new_cr = s->new_v;
228  new_y_stride = s->linesize[0];
229  new_cb_stride = s->linesize[1];
230  new_cr_stride = s->linesize[2];
231  old_y = s->old_y;
232  old_cb = s->old_u;
233  old_cr = s->old_v;
234  old_y_stride = s->linesize[0];
235  old_cb_stride = s->linesize[1];
236  old_cr_stride = s->linesize[2];
237 
238  for (block_index = 0; block_index < total_blocks; block_index++) {
239  // Note that this call will make us skip the rest of the blocks
240  // if the frame ends prematurely.
241  if (skip == -1)
242  skip = decode_skip_count(&gb);
243  if (skip == -1) {
244  av_log(avctx, AV_LOG_ERROR, "Error decoding skip value\n");
245  return AVERROR_INVALIDDATA;
246  }
247 
248  if (skip) {
249  y[0] = old_y[0];
250  y[1] = old_y[1];
251  y[2] = old_y[old_y_stride];
252  y[3] = old_y[old_y_stride + 1];
253  y_avg = ya[0];
254  cb = old_cb[0];
255  cr = old_cr[0];
256  } else {
257  if (get_bits1(&gb)) {
258  unsigned sign_selector = get_bits(&gb, 6);
259  unsigned difference_selector = get_bits(&gb, 2);
260  y_avg = 2 * get_bits(&gb, 5);
261  for (i = 0; i < 4; i++) {
262  y[i] = av_clip(y_avg + offset_table[difference_selector] *
263  sign_table[sign_selector][i], 0, 63);
264  }
265  } else if (get_bits1(&gb)) {
266  if (get_bits1(&gb)) {
267  y_avg = get_bits(&gb, 6);
268  } else {
269  unsigned adjust_index = get_bits(&gb, 3);
270  y_avg = (y_avg + luma_adjust[adjust_index]) & 63;
271  }
272  for (i = 0; i < 4; i++)
273  y[i] = y_avg;
274  }
275 
276  if (get_bits1(&gb)) {
277  if (get_bits1(&gb)) {
278  cb = get_bits(&gb, 5);
279  cr = get_bits(&gb, 5);
280  } else {
281  unsigned adjust_index = get_bits(&gb, 3);
282  cb = (cb + chroma_adjust[0][adjust_index]) & 31;
283  cr = (cr + chroma_adjust[1][adjust_index]) & 31;
284  }
285  }
286  }
287  *ya++ = y_avg;
288 
289  new_y[0] = y[0];
290  new_y[1] = y[1];
291  new_y[new_y_stride] = y[2];
292  new_y[new_y_stride + 1] = y[3];
293  *new_cb = cb;
294  *new_cr = cr;
295 
296  old_y += 2;
297  old_cb++;
298  old_cr++;
299  new_y += 2;
300  new_cb++;
301  new_cr++;
302  block_x++;
303  if (block_x * 2 == avctx->width) {
304  block_x = 0;
305  old_y += old_y_stride * 2 - avctx->width;
306  old_cb += old_cb_stride - avctx->width / 2;
307  old_cr += old_cr_stride - avctx->width / 2;
308  new_y += new_y_stride * 2 - avctx->width;
309  new_cb += new_cb_stride - avctx->width / 2;
310  new_cr += new_cr_stride - avctx->width / 2;
311  }
312 
313  skip--;
314  }
315 
316  new_y = s->new_y;
317  new_cb = s->new_u;
318  new_cr = s->new_v;
319  dstY = pic->data[0];
320  dstU = pic->data[1];
321  dstV = pic->data[2];
322  for (j = 0; j < avctx->height; j++) {
323  for (i = 0; i < avctx->width; i++)
324  dstY[i] = new_y[i] << 2;
325  dstY += pic->linesize[0];
326  new_y += new_y_stride;
327  }
328  for (j = 0; j < avctx->height / 2; j++) {
329  for (i = 0; i < avctx->width / 2; i++) {
330  dstU[i] = chroma_vals[new_cb[i]];
331  dstV[i] = chroma_vals[new_cr[i]];
332  }
333  dstU += pic->linesize[1];
334  dstV += pic->linesize[2];
335  new_cb += new_cb_stride;
336  new_cr += new_cr_stride;
337  }
338 
339  ff_dlog(avctx, "Frame data: provided %d bytes, used %d bytes\n",
340  buf_size, get_bits_count(&gb) >> 3);
341 
342  FFSWAP(uint8_t*, s->old_y, s->new_y);
343  FFSWAP(uint8_t*, s->old_u, s->new_u);
344  FFSWAP(uint8_t*, s->old_v, s->new_v);
345 
346  *got_frame = 1;
347 
348  return buf_size;
349 }
350 
352  .name = "escape130",
353  .long_name = NULL_IF_CONFIG_SMALL("Escape 130"),
354  .type = AVMEDIA_TYPE_VIDEO,
355  .id = AV_CODEC_ID_ESCAPE130,
356  .priv_data_size = sizeof(Escape130Context),
358  .close = escape130_decode_close,
360  .capabilities = AV_CODEC_CAP_DR1,
361 };
static const uint8_t chroma_vals[]
Definition: escape130.c:109
const char * s
Definition: avisynth_c.h:768
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
This structure describes decoded (raw) audio or video data.
Definition: frame.h:184
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:101
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:247
Memory handling functions.
static void skip_bits_long(GetBitContext *s, int n)
Definition: get_bits.h:204
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
int size
Definition: avcodec.h:1602
uint8_t * old_v
Definition: escape130.c:35
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1904
AVCodec.
Definition: avcodec.h:3600
Macro definitions for various function/variable attributes.
static double cb(void *priv, double x, double y)
Definition: vf_geq.c:97
static av_cold int escape130_decode_close(AVCodecContext *avctx)
Definition: escape130.c:155
uint8_t
#define av_cold
Definition: attributes.h:82
#define av_malloc(s)
uint8_t * old_u
Definition: escape130.c:34
uint8_t * new_v
Definition: escape130.c:35
uint8_t * new_y
Definition: escape130.c:33
uint8_t * data
Definition: avcodec.h:1601
static int get_bits_count(const GetBitContext *s)
Definition: get_bits.h:199
#define ff_dlog(a,...)
bitstream reader API header.
static const int8_t chroma_adjust[2][8]
Definition: escape130.c:104
#define av_log(a,...)
static const int8_t sign_table[64][4]
Definition: escape130.c:42
static int escape130_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: escape130.c:192
static int get_bits_left(GetBitContext *gb)
Definition: get_bits.h:568
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
#define AVERROR(e)
Definition: error.h:43
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:176
const char * name
Name of the codec implementation.
Definition: avcodec.h:3607
int width
picture width / height.
Definition: avcodec.h:1863
GLsizei GLboolean const GLfloat * value
Definition: opengl_enc.c:109
uint8_t * buf1
Definition: escape130.c:37
static int decode_skip_count(GetBitContext *gb)
Definition: escape130.c:166
Libavcodec external API header.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:215
static const int8_t luma_adjust[]
Definition: escape130.c:102
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition: get_bits.h:437
main external API structure.
Definition: avcodec.h:1676
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: utils.c:947
AVCodec ff_escape130_decoder
Definition: escape130.c:351
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:299
uint8_t * old_y
Definition: escape130.c:33
uint8_t * buf2
Definition: escape130.c:37
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:198
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:62
common internal api header.
void * priv_data
Definition: avcodec.h:1718
static const uint8_t offset_table[]
Definition: escape130.c:41
static av_cold int escape130_decode_init(AVCodecContext *avctx)
Definition: escape130.c:116
int linesize[3]
Definition: escape130.c:38
#define av_freep(p)
static int decode(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *pkt)
Definition: ffmpeg.c:2035
uint8_t * old_y_avg
Definition: escape130.c:31
#define FFSWAP(type, a, b)
Definition: common.h:99
static double cr(void *priv, double x, double y)
Definition: vf_geq.c:98
This structure stores compressed data.
Definition: avcodec.h:1578
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: avcodec.h:959
uint8_t * new_u
Definition: escape130.c:34