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  av_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),
359  .capabilities = CODEC_CAP_DR1,
360 };