FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
mimic.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005 Ole André Vadla Ravnås <oleavr@gmail.com>
3  * Copyright (C) 2008 Ramiro Polla
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 <stdlib.h>
23 #include <string.h>
24 #include <stdint.h>
25 
26 #include "avcodec.h"
27 #include "internal.h"
28 #include "get_bits.h"
29 #include "bytestream.h"
30 #include "dsputil.h"
31 #include "hpeldsp.h"
32 #include "thread.h"
33 
34 #define MIMIC_HEADER_SIZE 20
35 
36 typedef struct {
38 
39  int num_vblocks[3];
40  int num_hblocks[3];
41 
42  void *swap_buf;
44 
45  int cur_index;
47 
48  ThreadFrame frames [16];
49  AVPicture flipped_ptrs[16];
50 
51  DECLARE_ALIGNED(16, int16_t, dct_block)[64];
52 
58 
59  /* Kept in the context so multithreading can have a constant to read from */
62 } MimicContext;
63 
64 static const uint32_t huffcodes[] = {
65  0x0000000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
66  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
67  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000b,
68  0x0000001b, 0x00000038, 0x00000078, 0x00000079, 0x0000007a, 0x000000f9,
69  0x000000fa, 0x000003fb, 0x000007f8, 0x000007f9, 0x000007fa, 0x000007fb,
70  0x00000ff8, 0x00000ff9, 0x00000001, 0x00000039, 0x0000007b, 0x000000fb,
71  0x000001f8, 0x000001f9, 0x00000ffa, 0x00000ffb, 0x00001ff8, 0x00001ff9,
72  0x00001ffa, 0x00001ffb, 0x00003ff8, 0x00003ff9, 0x00003ffa, 0x00000000,
73  0x00000004, 0x0000003a, 0x000001fa, 0x00003ffb, 0x00007ff8, 0x00007ff9,
74  0x00007ffa, 0x00007ffb, 0x0000fff8, 0x0000fff9, 0x0000fffa, 0x0000fffb,
75  0x0001fff8, 0x0001fff9, 0x0001fffa, 0x00000000, 0x0000000c, 0x000000f8,
76  0x000001fb, 0x0001fffb, 0x0003fff8, 0x0003fff9, 0x0003fffa, 0x0003fffb,
77  0x0007fff8, 0x0007fff9, 0x0007fffa, 0x0007fffb, 0x000ffff8, 0x000ffff9,
78  0x000ffffa, 0x00000000, 0x0000001a, 0x000003f8, 0x000ffffb, 0x001ffff8,
79  0x001ffff9, 0x001ffffa, 0x001ffffb, 0x003ffff8, 0x003ffff9, 0x003ffffa,
80  0x003ffffb, 0x007ffff8, 0x007ffff9, 0x007ffffa, 0x007ffffb, 0x00000000,
81  0x0000003b, 0x000003f9, 0x00fffff8, 0x00fffff9, 0x00fffffa, 0x00fffffb,
82  0x01fffff8, 0x01fffff9, 0x01fffffa, 0x01fffffb, 0x03fffff8, 0x03fffff9,
83  0x03fffffa, 0x03fffffb, 0x07fffff8, 0x00000000, 0x000003fa, 0x07fffff9,
84  0x07fffffa, 0x07fffffb, 0x0ffffff8, 0x0ffffff9, 0x0ffffffa, 0x0ffffffb,
85  0x1ffffff8, 0x1ffffff9, 0x1ffffffa, 0x1ffffffb, 0x3ffffff8, 0x3ffffff9,
86  0x3ffffffa,
87 };
88 
89 static const uint8_t huffbits[] = {
90  4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
91  0, 0, 0, 0, 2, 4, 5, 6, 7, 7, 7, 8,
92  8, 10, 11, 11, 11, 11, 12, 12, 2, 6, 7, 8,
93  9, 9, 12, 12, 13, 13, 13, 13, 14, 14, 14, 0,
94  3, 6, 9, 14, 15, 15, 15, 15, 16, 16, 16, 16,
95  17, 17, 17, 0, 4, 8, 9, 17, 18, 18, 18, 18,
96  19, 19, 19, 19, 20, 20, 20, 0, 5, 10, 20, 21,
97  21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, 0,
98  6, 10, 24, 24, 24, 24, 25, 25, 25, 25, 26, 26,
99  26, 26, 27, 0, 10, 27, 27, 27, 28, 28, 28, 28,
100  29, 29, 29, 29, 30, 30, 30,
101 };
102 
103 static const uint8_t col_zag[64] = {
104  0, 8, 1, 2, 9, 16, 24, 17,
105  10, 3, 4, 11, 18, 25, 32, 40,
106  33, 26, 19, 12, 5, 6, 13, 20,
107  27, 34, 41, 48, 56, 49, 42, 35,
108  28, 21, 14, 7, 15, 22, 29, 36,
109  43, 50, 57, 58, 51, 44, 37, 30,
110  23, 31, 38, 45, 52, 59, 39, 46,
111  53, 60, 61, 54, 47, 55, 62, 63,
112 };
113 
115 {
116  MimicContext *ctx = avctx->priv_data;
117  int i;
118 
119  av_free(ctx->swap_buf);
120 
121  for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) {
122  if (ctx->frames[i].f)
123  ff_thread_release_buffer(avctx, &ctx->frames[i]);
124  av_frame_free(&ctx->frames[i].f);
125  }
126 
127  if (!avctx->internal->is_copy)
128  ff_free_vlc(&ctx->vlc);
129 
130  return 0;
131 }
132 
134 {
135  MimicContext *ctx = avctx->priv_data;
136  int ret, i;
137 
138  avctx->internal->allocate_progress = 1;
139 
140  ctx->prev_index = 0;
141  ctx->cur_index = 15;
142 
143  if ((ret = init_vlc(&ctx->vlc, 11, FF_ARRAY_ELEMS(huffbits),
144  huffbits, 1, 1, huffcodes, 4, 4, 0)) < 0) {
145  av_log(avctx, AV_LOG_ERROR, "error initializing vlc table\n");
146  return ret;
147  }
148  ff_dsputil_init(&ctx->dsp, avctx);
149  ff_hpeldsp_init(&ctx->hdsp, avctx->flags);
151 
152  for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) {
153  ctx->frames[i].f = av_frame_alloc();
154  if (!ctx->frames[i].f) {
155  mimic_decode_end(avctx);
156  return AVERROR(ENOMEM);
157  }
158  }
159 
160  return 0;
161 }
162 
164 {
165  MimicContext *dst = avctx->priv_data, *src = avctx_from->priv_data;
166  int i, ret;
167 
168  if (avctx == avctx_from)
169  return 0;
170 
171  dst->cur_index = src->next_cur_index;
172  dst->prev_index = src->next_prev_index;
173 
174  memcpy(dst->flipped_ptrs, src->flipped_ptrs, sizeof(src->flipped_ptrs));
175 
176  for (i = 0; i < FF_ARRAY_ELEMS(dst->frames); i++) {
177  ff_thread_release_buffer(avctx, &dst->frames[i]);
178  if (i != src->next_cur_index && src->frames[i].f->data[0]) {
179  ret = ff_thread_ref_frame(&dst->frames[i], &src->frames[i]);
180  if (ret < 0)
181  return ret;
182  }
183  }
184 
185  return 0;
186 }
187 
188 static const int8_t vlcdec_lookup[9][64] = {
189  { 0, },
190  { -1, 1, },
191  { -3, 3, -2, 2, },
192  { -7, 7, -6, 6, -5, 5, -4, 4, },
193  { -15, 15, -14, 14, -13, 13, -12, 12,
194  -11, 11, -10, 10, -9, 9, -8, 8, },
195  { -31, 31, -30, 30, -29, 29, -28, 28,
196  -27, 27, -26, 26, -25, 25, -24, 24,
197  -23, 23, -22, 22, -21, 21, -20, 20,
198  -19, 19, -18, 18, -17, 17, -16, 16, },
199  { -63, 63, -62, 62, -61, 61, -60, 60,
200  -59, 59, -58, 58, -57, 57, -56, 56,
201  -55, 55, -54, 54, -53, 53, -52, 52,
202  -51, 51, -50, 50, -49, 49, -48, 48,
203  -47, 47, -46, 46, -45, 45, -44, 44,
204  -43, 43, -42, 42, -41, 41, -40, 40,
205  -39, 39, -38, 38, -37, 37, -36, 36,
206  -35, 35, -34, 34, -33, 33, -32, 32, },
207  { -127, 127, -126, 126, -125, 125, -124, 124,
208  -123, 123, -122, 122, -121, 121, -120, 120,
209  -119, 119, -118, 118, -117, 117, -116, 116,
210  -115, 115, -114, 114, -113, 113, -112, 112,
211  -111, 111, -110, 110, -109, 109, -108, 108,
212  -107, 107, -106, 106, -105, 105, -104, 104,
213  -103, 103, -102, 102, -101, 101, -100, 100,
214  -99, 99, -98, 98, -97, 97, -96, 96, },
215  { -95, 95, -94, 94, -93, 93, -92, 92,
216  -91, 91, -90, 90, -89, 89, -88, 88,
217  -87, 87, -86, 86, -85, 85, -84, 84,
218  -83, 83, -82, 82, -81, 81, -80, 80,
219  -79, 79, -78, 78, -77, 77, -76, 76,
220  -75, 75, -74, 74, -73, 73, -72, 72,
221  -71, 71, -70, 70, -69, 69, -68, 68,
222  -67, 67, -66, 66, -65, 65, -64, 64, },
223 };
224 
225 static int vlc_decode_block(MimicContext *ctx, int num_coeffs, int qscale)
226 {
227  int16_t *block = ctx->dct_block;
228  unsigned int pos;
229 
230  ctx->dsp.clear_block(block);
231 
232  block[0] = get_bits(&ctx->gb, 8) << 3;
233 
234  for (pos = 1; pos < num_coeffs; pos++) {
235  uint32_t vlc, num_bits;
236  int value;
237  int coeff;
238 
239  vlc = get_vlc2(&ctx->gb, ctx->vlc.table, ctx->vlc.bits, 3);
240  if (!vlc) /* end-of-block code */
241  return 0;
242  if (vlc == -1)
243  return AVERROR_INVALIDDATA;
244 
245  /* pos_add and num_bits are coded in the vlc code */
246  pos += vlc & 15; // pos_add
247  num_bits = vlc >> 4; // num_bits
248 
249  if (pos >= 64)
250  return AVERROR_INVALIDDATA;
251 
252  value = get_bits(&ctx->gb, num_bits);
253 
254  /* FFmpeg's IDCT behaves somewhat different from the original code, so
255  * a factor of 4 was added to the input */
256 
257  coeff = vlcdec_lookup[num_bits][value];
258  if (pos < 3)
259  coeff <<= 4;
260  else /* TODO Use >> 10 instead of / 1001 */
261  coeff = (coeff * qscale) / 1001;
262 
263  block[ctx->scantable.permutated[pos]] = coeff;
264  }
265 
266  return 0;
267 }
268 
269 static int decode(MimicContext *ctx, int quality, int num_coeffs,
270  int is_iframe)
271 {
272  int ret, y, x, plane, cur_row = 0;
273 
274  for (plane = 0; plane < 3; plane++) {
275  const int is_chroma = !!plane;
276  const int qscale = av_clip(10000 - quality, is_chroma ? 1000 : 2000,
277  10000) << 2;
278  const int stride = ctx->flipped_ptrs[ctx->cur_index ].linesize[plane];
279  const uint8_t *src = ctx->flipped_ptrs[ctx->prev_index].data[plane];
280  uint8_t *dst = ctx->flipped_ptrs[ctx->cur_index ].data[plane];
281 
282  for (y = 0; y < ctx->num_vblocks[plane]; y++) {
283  for (x = 0; x < ctx->num_hblocks[plane]; x++) {
284  /* Check for a change condition in the current block.
285  * - iframes always change.
286  * - Luma plane changes on get_bits1 == 0
287  * - Chroma planes change on get_bits1 == 1 */
288  if (is_iframe || get_bits1(&ctx->gb) == is_chroma) {
289  /* Luma planes may use a backreference from the 15 last
290  * frames preceding the previous. (get_bits1 == 1)
291  * Chroma planes don't use backreferences. */
292  if (is_chroma || is_iframe || !get_bits1(&ctx->gb)) {
293  if ((ret = vlc_decode_block(ctx, num_coeffs,
294  qscale)) < 0) {
295  av_log(ctx->avctx, AV_LOG_ERROR, "Error decoding "
296  "block.\n");
297  return ret;
298  }
299  ctx->dsp.idct_put(dst, stride, ctx->dct_block);
300  } else {
301  unsigned int backref = get_bits(&ctx->gb, 4);
302  int index = (ctx->cur_index + backref) & 15;
303  uint8_t *p = ctx->flipped_ptrs[index].data[0];
304 
305  if (index != ctx->cur_index && p) {
306  ff_thread_await_progress(&ctx->frames[index],
307  cur_row, 0);
308  p += src -
309  ctx->flipped_ptrs[ctx->prev_index].data[plane];
310  ctx->hdsp.put_pixels_tab[1][0](dst, p, stride, 8);
311  } else {
312  av_log(ctx->avctx, AV_LOG_ERROR,
313  "No such backreference! Buggy sample.\n");
314  }
315  }
316  } else {
318  cur_row, 0);
319  ctx->hdsp.put_pixels_tab[1][0](dst, src, stride, 8);
320  }
321  src += 8;
322  dst += 8;
323  }
324  src += (stride - ctx->num_hblocks[plane]) << 3;
325  dst += (stride - ctx->num_hblocks[plane]) << 3;
326 
328  cur_row++, 0);
329  }
330  }
331 
332  return 0;
333 }
334 
335 /**
336  * Flip the buffer upside-down and put it in the YVU order to match the
337  * way Mimic encodes frames.
338  */
339 static void prepare_avpic(MimicContext *ctx, AVPicture *dst, AVFrame *src)
340 {
341  int i;
342  dst->data[0] = src->data[0] + ( ctx->avctx->height - 1) * src->linesize[0];
343  dst->data[1] = src->data[2] + ((ctx->avctx->height >> 1) - 1) * src->linesize[2];
344  dst->data[2] = src->data[1] + ((ctx->avctx->height >> 1) - 1) * src->linesize[1];
345  for (i = 0; i < 3; i++)
346  dst->linesize[i] = -src->linesize[i];
347 }
348 
349 static int mimic_decode_frame(AVCodecContext *avctx, void *data,
350  int *got_frame, AVPacket *avpkt)
351 {
352  const uint8_t *buf = avpkt->data;
353  int buf_size = avpkt->size;
354  int swap_buf_size = buf_size - MIMIC_HEADER_SIZE;
355  MimicContext *ctx = avctx->priv_data;
356  GetByteContext gb;
357  int is_pframe;
358  int width, height;
359  int quality, num_coeffs;
360  int res;
361 
362  if (buf_size <= MIMIC_HEADER_SIZE) {
363  av_log(avctx, AV_LOG_ERROR, "insufficient data\n");
364  return AVERROR_INVALIDDATA;
365  }
366 
367  bytestream2_init(&gb, buf, MIMIC_HEADER_SIZE);
368  bytestream2_skip(&gb, 2); /* some constant (always 256) */
369  quality = bytestream2_get_le16u(&gb);
370  width = bytestream2_get_le16u(&gb);
371  height = bytestream2_get_le16u(&gb);
372  bytestream2_skip(&gb, 4); /* some constant */
373  is_pframe = bytestream2_get_le32u(&gb);
374  num_coeffs = bytestream2_get_byteu(&gb);
375  bytestream2_skip(&gb, 3); /* some constant */
376 
377  if (!ctx->avctx) {
378  int i;
379 
380  if (!(width == 160 && height == 120) &&
381  !(width == 320 && height == 240)) {
382  av_log(avctx, AV_LOG_ERROR, "invalid width/height!\n");
383  return AVERROR_INVALIDDATA;
384  }
385 
386  ctx->avctx = avctx;
387  avctx->width = width;
388  avctx->height = height;
389  avctx->pix_fmt = AV_PIX_FMT_YUV420P;
390  for (i = 0; i < 3; i++) {
391  ctx->num_vblocks[i] = FF_CEIL_RSHIFT(height, 3 + !!i);
392  ctx->num_hblocks[i] = width >> (3 + !!i);
393  }
394  } else if (width != ctx->avctx->width || height != ctx->avctx->height) {
395  avpriv_request_sample(avctx, "Resolution changing");
396  return AVERROR_PATCHWELCOME;
397  }
398 
399  if (is_pframe && !ctx->frames[ctx->prev_index].f->data[0]) {
400  av_log(avctx, AV_LOG_ERROR, "decoding must start with keyframe\n");
401  return AVERROR_INVALIDDATA;
402  }
403 
404  ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);
405  ctx->frames[ctx->cur_index].f->pict_type = is_pframe ? AV_PICTURE_TYPE_P :
407  if ((res = ff_thread_get_buffer(avctx, &ctx->frames[ctx->cur_index],
409  return res;
410 
411  ctx->next_prev_index = ctx->cur_index;
412  ctx->next_cur_index = (ctx->cur_index - 1) & 15;
413 
414  prepare_avpic(ctx, &ctx->flipped_ptrs[ctx->cur_index],
415  ctx->frames[ctx->cur_index].f);
416 
417  ff_thread_finish_setup(avctx);
418 
419  av_fast_padded_malloc(&ctx->swap_buf, &ctx->swap_buf_size, swap_buf_size);
420  if (!ctx->swap_buf)
421  return AVERROR(ENOMEM);
422 
423  ctx->dsp.bswap_buf(ctx->swap_buf,
424  (const uint32_t*) (buf + MIMIC_HEADER_SIZE),
425  swap_buf_size >> 2);
426  init_get_bits(&ctx->gb, ctx->swap_buf, swap_buf_size << 3);
427 
428  res = decode(ctx, quality, num_coeffs, !is_pframe);
429  ff_thread_report_progress(&ctx->frames[ctx->cur_index], INT_MAX, 0);
430  if (res < 0) {
431  if (!(avctx->active_thread_type & FF_THREAD_FRAME)) {
432  ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);
433  return res;
434  }
435  }
436 
437  if ((res = av_frame_ref(data, ctx->frames[ctx->cur_index].f)) < 0)
438  return res;
439  *got_frame = 1;
440 
441  ctx->prev_index = ctx->next_prev_index;
442  ctx->cur_index = ctx->next_cur_index;
443 
444  /* Only release frames that aren't used for backreferences anymore */
445  ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);
446 
447  return buf_size;
448 }
449 
451 {
452  MimicContext *ctx = avctx->priv_data;
453  int i;
454 
455  for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) {
456  ctx->frames[i].f = av_frame_alloc();
457  if (!ctx->frames[i].f) {
458  mimic_decode_end(avctx);
459  return AVERROR(ENOMEM);
460  }
461  }
462 
463  return 0;
464 }
465 
467  .name = "mimic",
468  .long_name = NULL_IF_CONFIG_SMALL("Mimic"),
469  .type = AVMEDIA_TYPE_VIDEO,
470  .id = AV_CODEC_ID_MIMIC,
471  .priv_data_size = sizeof(MimicContext),
475  .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
477  .init_thread_copy = ONLY_IF_THREADS_ENABLED(mimic_init_thread_copy),
478 };