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 #include "avcodec.h"
25 #define BITSTREAM_READER_LE
26 #include "get_bits.h"
27 #include "internal.h"
28 
29 typedef struct Escape130Context {
31 
35 
37  int linesize[3];
39 
40 static const uint8_t offset_table[] = { 2, 4, 10, 20 };
41 static const int8_t sign_table[64][4] = {
42  { 0, 0, 0, 0 },
43  { -1, 1, 0, 0 },
44  { 1, -1, 0, 0 },
45  { -1, 0, 1, 0 },
46  { -1, 1, 1, 0 },
47  { 0, -1, 1, 0 },
48  { 1, -1, 1, 0 },
49  { -1, -1, 1, 0 },
50  { 1, 0, -1, 0 },
51  { 0, 1, -1, 0 },
52  { 1, 1, -1, 0 },
53  { -1, 1, -1, 0 },
54  { 1, -1, -1, 0 },
55  { -1, 0, 0, 1 },
56  { -1, 1, 0, 1 },
57  { 0, -1, 0, 1 },
58 
59  { 0, 0, 0, 0 },
60  { 1, -1, 0, 1 },
61  { -1, -1, 0, 1 },
62  { -1, 0, 1, 1 },
63  { -1, 1, 1, 1 },
64  { 0, -1, 1, 1 },
65  { 1, -1, 1, 1 },
66  { -1, -1, 1, 1 },
67  { 0, 0, -1, 1 },
68  { 1, 0, -1, 1 },
69  { -1, 0, -1, 1 },
70  { 0, 1, -1, 1 },
71  { 1, 1, -1, 1 },
72  { -1, 1, -1, 1 },
73  { 0, -1, -1, 1 },
74  { 1, -1, -1, 1 },
75 
76  { 0, 0, 0, 0 },
77  { -1, -1, -1, 1 },
78  { 1, 0, 0, -1 },
79  { 0, 1, 0, -1 },
80  { 1, 1, 0, -1 },
81  { -1, 1, 0, -1 },
82  { 1, -1, 0, -1 },
83  { 0, 0, 1, -1 },
84  { 1, 0, 1, -1 },
85  { -1, 0, 1, -1 },
86  { 0, 1, 1, -1 },
87  { 1, 1, 1, -1 },
88  { -1, 1, 1, -1 },
89  { 0, -1, 1, -1 },
90  { 1, -1, 1, -1 },
91  { -1, -1, 1, -1 },
92 
93  { 0, 0, 0, 0 },
94  { 1, 0, -1, -1 },
95  { 0, 1, -1, -1 },
96  { 1, 1, -1, -1 },
97  { -1, 1, -1, -1 },
98  { 1, -1, -1, -1 }
99 };
100 
101 static const int8_t luma_adjust[] = { -4, -3, -2, -1, 1, 2, 3, 4 };
102 
103 static const int8_t chroma_adjust[2][8] = {
104  { 1, 1, 0, -1, -1, -1, 0, 1 },
105  { 0, 1, 1, 1, 0, -1, -1, -1 }
106 };
107 
108 static const uint8_t chroma_vals[] = {
109  20, 28, 36, 44, 52, 60, 68, 76,
110  84, 92, 100, 106, 112, 116, 120, 124,
111  128, 132, 136, 140, 144, 150, 156, 164,
112  172, 180, 188, 196, 204, 212, 220, 228
113 };
114 
116 {
117  Escape130Context *s = avctx->priv_data;
118  avctx->pix_fmt = AV_PIX_FMT_YUV420P;
119 
120  if ((avctx->width & 1) || (avctx->height & 1)) {
121  av_log(avctx, AV_LOG_ERROR,
122  "Dimensions should be a multiple of two.\n");
123  return AVERROR_INVALIDDATA;
124  }
125 
126  s->old_y_avg = av_malloc(avctx->width * avctx->height / 4);
127  s->buf1 = av_malloc(avctx->width * avctx->height * 3 / 2);
128  s->buf2 = av_malloc(avctx->width * avctx->height * 3 / 2);
129  if (!s->old_y_avg || !s->buf1 || !s->buf2) {
130  av_freep(&s->old_y_avg);
131  av_freep(&s->buf1);
132  av_freep(&s->buf2);
133  av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
134  return AVERROR(ENOMEM);
135  }
136 
137  s->linesize[0] = avctx->width;
138  s->linesize[1] =
139  s->linesize[2] = avctx->width / 2;
140 
141  s->new_y = s->buf1;
142  s->new_u = s->new_y + avctx->width * avctx->height;
143  s->new_v = s->new_u + avctx->width * avctx->height / 4;
144  s->old_y = s->buf2;
145  s->old_u = s->old_y + avctx->width * avctx->height;
146  s->old_v = s->old_u + avctx->width * avctx->height / 4;
147  memset(s->old_y, 0, avctx->width * avctx->height);
148  memset(s->old_u, 0x10, avctx->width * avctx->height / 4);
149  memset(s->old_v, 0x10, avctx->width * avctx->height / 4);
150 
151  return 0;
152 }
153 
155 {
156  Escape130Context *s = avctx->priv_data;
157 
158  av_freep(&s->old_y_avg);
159  av_freep(&s->buf1);
160  av_freep(&s->buf2);
161 
162  return 0;
163 }
164 
166 {
167  int value;
168 
169  if (get_bits_left(gb) < 1+3)
170  return -1;
171 
172  value = get_bits1(gb);
173  if (value)
174  return 0;
175 
176  value = get_bits(gb, 3);
177  if (value)
178  return value;
179 
180  value = get_bits(gb, 8);
181  if (value)
182  return value + 7;
183 
184  value = get_bits(gb, 15);
185  if (value)
186  return value + 262;
187 
188  return -1;
189 }
190 
191 static int escape130_decode_frame(AVCodecContext *avctx, void *data,
192  int *got_frame, AVPacket *avpkt)
193 {
194  int buf_size = avpkt->size;
195  Escape130Context *s = avctx->priv_data;
196  AVFrame *pic = data;
197  GetBitContext gb;
198  int ret;
199 
200  uint8_t *old_y, *old_cb, *old_cr,
201  *new_y, *new_cb, *new_cr;
202  uint8_t *dstY, *dstU, *dstV;
203  unsigned old_y_stride, old_cb_stride, old_cr_stride,
204  new_y_stride, new_cb_stride, new_cr_stride;
205  unsigned total_blocks = avctx->width * avctx->height / 4,
206  block_index, block_x = 0;
207  unsigned y[4] = { 0 }, cb = 0x10, cr = 0x10;
208  int skip = -1, y_avg = 0, i, j;
209  uint8_t *ya = s->old_y_avg;
210 
211  // first 16 bytes are header; no useful information in here
212  if (buf_size <= 16) {
213  av_log(avctx, AV_LOG_ERROR, "Insufficient frame data\n");
214  return AVERROR_INVALIDDATA;
215  }
216 
217  if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
218  return ret;
219 
220  if ((ret = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0)
221  return ret;
222  skip_bits_long(&gb, 16 * 8);
223 
224  new_y = s->new_y;
225  new_cb = s->new_u;
226  new_cr = s->new_v;
227  new_y_stride = s->linesize[0];
228  new_cb_stride = s->linesize[1];
229  new_cr_stride = s->linesize[2];
230  old_y = s->old_y;
231  old_cb = s->old_u;
232  old_cr = s->old_v;
233  old_y_stride = s->linesize[0];
234  old_cb_stride = s->linesize[1];
235  old_cr_stride = s->linesize[2];
236 
237  for (block_index = 0; block_index < total_blocks; block_index++) {
238  // Note that this call will make us skip the rest of the blocks
239  // if the frame ends prematurely.
240  if (skip == -1)
241  skip = decode_skip_count(&gb);
242  if (skip == -1) {
243  av_log(avctx, AV_LOG_ERROR, "Error decoding skip value\n");
244  return AVERROR_INVALIDDATA;
245  }
246 
247  if (skip) {
248  y[0] = old_y[0];
249  y[1] = old_y[1];
250  y[2] = old_y[old_y_stride];
251  y[3] = old_y[old_y_stride + 1];
252  y_avg = ya[0];
253  cb = old_cb[0];
254  cr = old_cr[0];
255  } else {
256  if (get_bits1(&gb)) {
257  unsigned sign_selector = get_bits(&gb, 6);
258  unsigned difference_selector = get_bits(&gb, 2);
259  y_avg = 2 * get_bits(&gb, 5);
260  for (i = 0; i < 4; i++) {
261  y[i] = av_clip(y_avg + offset_table[difference_selector] *
262  sign_table[sign_selector][i], 0, 63);
263  }
264  } else if (get_bits1(&gb)) {
265  if (get_bits1(&gb)) {
266  y_avg = get_bits(&gb, 6);
267  } else {
268  unsigned adjust_index = get_bits(&gb, 3);
269  y_avg = (y_avg + luma_adjust[adjust_index]) & 63;
270  }
271  for (i = 0; i < 4; i++)
272  y[i] = y_avg;
273  }
274 
275  if (get_bits1(&gb)) {
276  if (get_bits1(&gb)) {
277  cb = get_bits(&gb, 5);
278  cr = get_bits(&gb, 5);
279  } else {
280  unsigned adjust_index = get_bits(&gb, 3);
281  cb = (cb + chroma_adjust[0][adjust_index]) & 31;
282  cr = (cr + chroma_adjust[1][adjust_index]) & 31;
283  }
284  }
285  }
286  *ya++ = y_avg;
287 
288  new_y[0] = y[0];
289  new_y[1] = y[1];
290  new_y[new_y_stride] = y[2];
291  new_y[new_y_stride + 1] = y[3];
292  *new_cb = cb;
293  *new_cr = cr;
294 
295  old_y += 2;
296  old_cb++;
297  old_cr++;
298  new_y += 2;
299  new_cb++;
300  new_cr++;
301  block_x++;
302  if (block_x * 2 == avctx->width) {
303  block_x = 0;
304  old_y += old_y_stride * 2 - avctx->width;
305  old_cb += old_cb_stride - avctx->width / 2;
306  old_cr += old_cr_stride - avctx->width / 2;
307  new_y += new_y_stride * 2 - avctx->width;
308  new_cb += new_cb_stride - avctx->width / 2;
309  new_cr += new_cr_stride - avctx->width / 2;
310  }
311 
312  skip--;
313  }
314 
315  new_y = s->new_y;
316  new_cb = s->new_u;
317  new_cr = s->new_v;
318  dstY = pic->data[0];
319  dstU = pic->data[1];
320  dstV = pic->data[2];
321  for (j = 0; j < avctx->height; j++) {
322  for (i = 0; i < avctx->width; i++)
323  dstY[i] = new_y[i] << 2;
324  dstY += pic->linesize[0];
325  new_y += new_y_stride;
326  }
327  for (j = 0; j < avctx->height / 2; j++) {
328  for (i = 0; i < avctx->width / 2; i++) {
329  dstU[i] = chroma_vals[new_cb[i]];
330  dstV[i] = chroma_vals[new_cr[i]];
331  }
332  dstU += pic->linesize[1];
333  dstV += pic->linesize[2];
334  new_cb += new_cb_stride;
335  new_cr += new_cr_stride;
336  }
337 
338  ff_dlog(avctx, "Frame data: provided %d bytes, used %d bytes\n",
339  buf_size, get_bits_count(&gb) >> 3);
340 
341  FFSWAP(uint8_t*, s->old_y, s->new_y);
342  FFSWAP(uint8_t*, s->old_u, s->new_u);
343  FFSWAP(uint8_t*, s->old_v, s->new_v);
344 
345  *got_frame = 1;
346 
347  return buf_size;
348 }
349 
351  .name = "escape130",
352  .long_name = NULL_IF_CONFIG_SMALL("Escape 130"),
353  .type = AVMEDIA_TYPE_VIDEO,
354  .id = AV_CODEC_ID_ESCAPE130,
355  .priv_data_size = sizeof(Escape130Context),
357  .close = escape130_decode_close,
359  .capabilities = AV_CODEC_CAP_DR1,
360 };
static const uint8_t chroma_vals[]
Definition: escape130.c:108
const char * s
Definition: avisynth_c.h:631
#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:171
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:260
memory handling functions
static void skip_bits_long(GetBitContext *s, int n)
Definition: get_bits.h:217
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
int size
Definition: avcodec.h:1424
uint8_t * old_v
Definition: escape130.c:34
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1722
AVCodec.
Definition: avcodec.h:3472
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:154
uint8_t
#define av_cold
Definition: attributes.h:74
#define av_malloc(s)
uint8_t * old_u
Definition: escape130.c:33
uint8_t * new_v
Definition: escape130.c:34
uint8_t * new_y
Definition: escape130.c:32
uint8_t * data
Definition: avcodec.h:1423
static int get_bits_count(const GetBitContext *s)
Definition: get_bits.h:212
#define ff_dlog(a,...)
bitstream reader API header.
static const int8_t chroma_adjust[2][8]
Definition: escape130.c:103
#define av_log(a,...)
static const int8_t sign_table[64][4]
Definition: escape130.c:41
static int escape130_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: escape130.c:191
static int get_bits_left(GetBitContext *gb)
Definition: get_bits.h:588
#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:175
const char * name
Name of the codec implementation.
Definition: avcodec.h:3479
Libavcodec external API header.
float y
int width
picture width / height.
Definition: avcodec.h:1681
GLsizei GLboolean const GLfloat * value
Definition: opengl_enc.c:109
uint8_t * buf1
Definition: escape130.c:36
static int decode_skip_count(GetBitContext *gb)
Definition: escape130.c:165
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:199
static const int8_t luma_adjust[]
Definition: escape130.c:101
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition: get_bits.h:441
main external API structure.
Definition: avcodec.h:1502
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: utils.c:1040
AVCodec ff_escape130_decoder
Definition: escape130.c:350
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:304
uint8_t * old_y
Definition: escape130.c:32
uint8_t * buf2
Definition: escape130.c:36
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:182
static int decode(AVCodecContext *avctx, void *data, int *got_sub, AVPacket *avpkt)
Definition: ccaption_dec.c:523
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:63
common internal api header.
void * priv_data
Definition: avcodec.h:1544
static const uint8_t offset_table[]
Definition: escape130.c:40
static av_cold int escape130_decode_init(AVCodecContext *avctx)
Definition: escape130.c:115
int linesize[3]
Definition: escape130.c:37
#define av_freep(p)
uint8_t * old_y_avg
Definition: escape130.c:30
#define FFSWAP(type, a, b)
Definition: common.h:84
static double cr(void *priv, double x, double y)
Definition: vf_geq.c:98
This structure stores compressed data.
Definition: avcodec.h:1400
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: avcodec.h:857
uint8_t * new_u
Definition: escape130.c:33