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_freep(&ctx->swap_buf);
120  ctx->swap_buf_size = 0;
121 
122  for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) {
123  if (ctx->frames[i].f)
124  ff_thread_release_buffer(avctx, &ctx->frames[i]);
125  av_frame_free(&ctx->frames[i].f);
126  }
127 
128  if (!avctx->internal->is_copy)
129  ff_free_vlc(&ctx->vlc);
130 
131  return 0;
132 }
133 
135 {
136  MimicContext *ctx = avctx->priv_data;
137  int ret, i;
138 
139  avctx->internal->allocate_progress = 1;
140 
141  ctx->prev_index = 0;
142  ctx->cur_index = 15;
143 
144  if ((ret = init_vlc(&ctx->vlc, 11, FF_ARRAY_ELEMS(huffbits),
145  huffbits, 1, 1, huffcodes, 4, 4, 0)) < 0) {
146  av_log(avctx, AV_LOG_ERROR, "error initializing vlc table\n");
147  return ret;
148  }
149  ff_dsputil_init(&ctx->dsp, avctx);
150  ff_hpeldsp_init(&ctx->hdsp, avctx->flags);
152 
153  for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) {
154  ctx->frames[i].f = av_frame_alloc();
155  if (!ctx->frames[i].f) {
156  mimic_decode_end(avctx);
157  return AVERROR(ENOMEM);
158  }
159  }
160 
161  return 0;
162 }
163 
165 {
166  MimicContext *dst = avctx->priv_data, *src = avctx_from->priv_data;
167  int i, ret;
168 
169  if (avctx == avctx_from)
170  return 0;
171 
172  dst->cur_index = src->next_cur_index;
173  dst->prev_index = src->next_prev_index;
174 
175  memcpy(dst->flipped_ptrs, src->flipped_ptrs, sizeof(src->flipped_ptrs));
176 
177  for (i = 0; i < FF_ARRAY_ELEMS(dst->frames); i++) {
178  ff_thread_release_buffer(avctx, &dst->frames[i]);
179  if (i != src->next_cur_index && src->frames[i].f->data[0]) {
180  ret = ff_thread_ref_frame(&dst->frames[i], &src->frames[i]);
181  if (ret < 0)
182  return ret;
183  }
184  }
185 
186  return 0;
187 }
188 
189 static const int8_t vlcdec_lookup[9][64] = {
190  { 0, },
191  { -1, 1, },
192  { -3, 3, -2, 2, },
193  { -7, 7, -6, 6, -5, 5, -4, 4, },
194  { -15, 15, -14, 14, -13, 13, -12, 12,
195  -11, 11, -10, 10, -9, 9, -8, 8, },
196  { -31, 31, -30, 30, -29, 29, -28, 28,
197  -27, 27, -26, 26, -25, 25, -24, 24,
198  -23, 23, -22, 22, -21, 21, -20, 20,
199  -19, 19, -18, 18, -17, 17, -16, 16, },
200  { -63, 63, -62, 62, -61, 61, -60, 60,
201  -59, 59, -58, 58, -57, 57, -56, 56,
202  -55, 55, -54, 54, -53, 53, -52, 52,
203  -51, 51, -50, 50, -49, 49, -48, 48,
204  -47, 47, -46, 46, -45, 45, -44, 44,
205  -43, 43, -42, 42, -41, 41, -40, 40,
206  -39, 39, -38, 38, -37, 37, -36, 36,
207  -35, 35, -34, 34, -33, 33, -32, 32, },
208  { -127, 127, -126, 126, -125, 125, -124, 124,
209  -123, 123, -122, 122, -121, 121, -120, 120,
210  -119, 119, -118, 118, -117, 117, -116, 116,
211  -115, 115, -114, 114, -113, 113, -112, 112,
212  -111, 111, -110, 110, -109, 109, -108, 108,
213  -107, 107, -106, 106, -105, 105, -104, 104,
214  -103, 103, -102, 102, -101, 101, -100, 100,
215  -99, 99, -98, 98, -97, 97, -96, 96, },
216  { -95, 95, -94, 94, -93, 93, -92, 92,
217  -91, 91, -90, 90, -89, 89, -88, 88,
218  -87, 87, -86, 86, -85, 85, -84, 84,
219  -83, 83, -82, 82, -81, 81, -80, 80,
220  -79, 79, -78, 78, -77, 77, -76, 76,
221  -75, 75, -74, 74, -73, 73, -72, 72,
222  -71, 71, -70, 70, -69, 69, -68, 68,
223  -67, 67, -66, 66, -65, 65, -64, 64, },
224 };
225 
226 static int vlc_decode_block(MimicContext *ctx, int num_coeffs, int qscale)
227 {
228  int16_t *block = ctx->dct_block;
229  unsigned int pos;
230 
231  ctx->dsp.clear_block(block);
232 
233  block[0] = get_bits(&ctx->gb, 8) << 3;
234 
235  for (pos = 1; pos < num_coeffs; pos++) {
236  uint32_t vlc, num_bits;
237  int value;
238  int coeff;
239 
240  vlc = get_vlc2(&ctx->gb, ctx->vlc.table, ctx->vlc.bits, 3);
241  if (!vlc) /* end-of-block code */
242  return 0;
243  if (vlc == -1)
244  return AVERROR_INVALIDDATA;
245 
246  /* pos_add and num_bits are coded in the vlc code */
247  pos += vlc & 15; // pos_add
248  num_bits = vlc >> 4; // num_bits
249 
250  if (pos >= 64)
251  return AVERROR_INVALIDDATA;
252 
253  value = get_bits(&ctx->gb, num_bits);
254 
255  /* FFmpeg's IDCT behaves somewhat different from the original code, so
256  * a factor of 4 was added to the input */
257 
258  coeff = vlcdec_lookup[num_bits][value];
259  if (pos < 3)
260  coeff <<= 4;
261  else /* TODO Use >> 10 instead of / 1001 */
262  coeff = (coeff * qscale) / 1001;
263 
264  block[ctx->scantable.permutated[pos]] = coeff;
265  }
266 
267  return 0;
268 }
269 
270 static int decode(MimicContext *ctx, int quality, int num_coeffs,
271  int is_iframe)
272 {
273  int ret, y, x, plane, cur_row = 0;
274 
275  for (plane = 0; plane < 3; plane++) {
276  const int is_chroma = !!plane;
277  const int qscale = av_clip(10000 - quality, is_chroma ? 1000 : 2000,
278  10000) << 2;
279  const int stride = ctx->flipped_ptrs[ctx->cur_index ].linesize[plane];
280  const uint8_t *src = ctx->flipped_ptrs[ctx->prev_index].data[plane];
281  uint8_t *dst = ctx->flipped_ptrs[ctx->cur_index ].data[plane];
282 
283  for (y = 0; y < ctx->num_vblocks[plane]; y++) {
284  for (x = 0; x < ctx->num_hblocks[plane]; x++) {
285  /* Check for a change condition in the current block.
286  * - iframes always change.
287  * - Luma plane changes on get_bits1 == 0
288  * - Chroma planes change on get_bits1 == 1 */
289  if (is_iframe || get_bits1(&ctx->gb) == is_chroma) {
290  /* Luma planes may use a backreference from the 15 last
291  * frames preceding the previous. (get_bits1 == 1)
292  * Chroma planes don't use backreferences. */
293  if (is_chroma || is_iframe || !get_bits1(&ctx->gb)) {
294  if ((ret = vlc_decode_block(ctx, num_coeffs,
295  qscale)) < 0) {
296  av_log(ctx->avctx, AV_LOG_ERROR, "Error decoding "
297  "block.\n");
298  return ret;
299  }
300  ctx->dsp.idct_put(dst, stride, ctx->dct_block);
301  } else {
302  unsigned int backref = get_bits(&ctx->gb, 4);
303  int index = (ctx->cur_index + backref) & 15;
304  uint8_t *p = ctx->flipped_ptrs[index].data[0];
305 
306  if (index != ctx->cur_index && p) {
307  ff_thread_await_progress(&ctx->frames[index],
308  cur_row, 0);
309  p += src -
310  ctx->flipped_ptrs[ctx->prev_index].data[plane];
311  ctx->hdsp.put_pixels_tab[1][0](dst, p, stride, 8);
312  } else {
313  av_log(ctx->avctx, AV_LOG_ERROR,
314  "No such backreference! Buggy sample.\n");
315  }
316  }
317  } else {
319  cur_row, 0);
320  ctx->hdsp.put_pixels_tab[1][0](dst, src, stride, 8);
321  }
322  src += 8;
323  dst += 8;
324  }
325  src += (stride - ctx->num_hblocks[plane]) << 3;
326  dst += (stride - ctx->num_hblocks[plane]) << 3;
327 
329  cur_row++, 0);
330  }
331  }
332 
333  return 0;
334 }
335 
336 /**
337  * Flip the buffer upside-down and put it in the YVU order to match the
338  * way Mimic encodes frames.
339  */
340 static void prepare_avpic(MimicContext *ctx, AVPicture *dst, AVFrame *src)
341 {
342  int i;
343  dst->data[0] = src->data[0] + ( ctx->avctx->height - 1) * src->linesize[0];
344  dst->data[1] = src->data[2] + ((ctx->avctx->height >> 1) - 1) * src->linesize[2];
345  dst->data[2] = src->data[1] + ((ctx->avctx->height >> 1) - 1) * src->linesize[1];
346  for (i = 0; i < 3; i++)
347  dst->linesize[i] = -src->linesize[i];
348 }
349 
350 static int mimic_decode_frame(AVCodecContext *avctx, void *data,
351  int *got_frame, AVPacket *avpkt)
352 {
353  const uint8_t *buf = avpkt->data;
354  int buf_size = avpkt->size;
355  int swap_buf_size = buf_size - MIMIC_HEADER_SIZE;
356  MimicContext *ctx = avctx->priv_data;
357  GetByteContext gb;
358  int is_pframe;
359  int width, height;
360  int quality, num_coeffs;
361  int res;
362 
363  if (buf_size <= MIMIC_HEADER_SIZE) {
364  av_log(avctx, AV_LOG_ERROR, "insufficient data\n");
365  return AVERROR_INVALIDDATA;
366  }
367 
368  bytestream2_init(&gb, buf, MIMIC_HEADER_SIZE);
369  bytestream2_skip(&gb, 2); /* some constant (always 256) */
370  quality = bytestream2_get_le16u(&gb);
371  width = bytestream2_get_le16u(&gb);
372  height = bytestream2_get_le16u(&gb);
373  bytestream2_skip(&gb, 4); /* some constant */
374  is_pframe = bytestream2_get_le32u(&gb);
375  num_coeffs = bytestream2_get_byteu(&gb);
376  bytestream2_skip(&gb, 3); /* some constant */
377 
378  if (!ctx->avctx) {
379  int i;
380 
381  if (!(width == 160 && height == 120) &&
382  !(width == 320 && height == 240)) {
383  av_log(avctx, AV_LOG_ERROR, "invalid width/height!\n");
384  return AVERROR_INVALIDDATA;
385  }
386 
387  ctx->avctx = avctx;
388  avctx->width = width;
389  avctx->height = height;
390  avctx->pix_fmt = AV_PIX_FMT_YUV420P;
391  for (i = 0; i < 3; i++) {
392  ctx->num_vblocks[i] = FF_CEIL_RSHIFT(height, 3 + !!i);
393  ctx->num_hblocks[i] = width >> (3 + !!i);
394  }
395  } else if (width != ctx->avctx->width || height != ctx->avctx->height) {
396  avpriv_request_sample(avctx, "Resolution changing");
397  return AVERROR_PATCHWELCOME;
398  }
399 
400  if (is_pframe && !ctx->frames[ctx->prev_index].f->data[0]) {
401  av_log(avctx, AV_LOG_ERROR, "decoding must start with keyframe\n");
402  return AVERROR_INVALIDDATA;
403  }
404 
405  ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);
406  ctx->frames[ctx->cur_index].f->pict_type = is_pframe ? AV_PICTURE_TYPE_P :
408  if ((res = ff_thread_get_buffer(avctx, &ctx->frames[ctx->cur_index],
410  return res;
411 
412  ctx->next_prev_index = ctx->cur_index;
413  ctx->next_cur_index = (ctx->cur_index - 1) & 15;
414 
415  prepare_avpic(ctx, &ctx->flipped_ptrs[ctx->cur_index],
416  ctx->frames[ctx->cur_index].f);
417 
418  ff_thread_finish_setup(avctx);
419 
420  av_fast_padded_malloc(&ctx->swap_buf, &ctx->swap_buf_size, swap_buf_size);
421  if (!ctx->swap_buf)
422  return AVERROR(ENOMEM);
423 
424  ctx->dsp.bswap_buf(ctx->swap_buf,
425  (const uint32_t*) (buf + MIMIC_HEADER_SIZE),
426  swap_buf_size >> 2);
427  init_get_bits(&ctx->gb, ctx->swap_buf, swap_buf_size << 3);
428 
429  res = decode(ctx, quality, num_coeffs, !is_pframe);
430  ff_thread_report_progress(&ctx->frames[ctx->cur_index], INT_MAX, 0);
431  if (res < 0) {
432  if (!(avctx->active_thread_type & FF_THREAD_FRAME)) {
433  ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);
434  return res;
435  }
436  }
437 
438  if ((res = av_frame_ref(data, ctx->frames[ctx->cur_index].f)) < 0)
439  return res;
440  *got_frame = 1;
441 
442  ctx->prev_index = ctx->next_prev_index;
443  ctx->cur_index = ctx->next_cur_index;
444 
445  /* Only release frames that aren't used for backreferences anymore */
446  ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);
447 
448  return buf_size;
449 }
450 
452 {
453  MimicContext *ctx = avctx->priv_data;
454  int i;
455 
456  for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) {
457  ctx->frames[i].f = av_frame_alloc();
458  if (!ctx->frames[i].f) {
459  mimic_decode_end(avctx);
460  return AVERROR(ENOMEM);
461  }
462  }
463 
464  return 0;
465 }
466 
468  .name = "mimic",
469  .long_name = NULL_IF_CONFIG_SMALL("Mimic"),
470  .type = AVMEDIA_TYPE_VIDEO,
471  .id = AV_CODEC_ID_MIMIC,
472  .priv_data_size = sizeof(MimicContext),
476  .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
478  .init_thread_copy = ONLY_IF_THREADS_ENABLED(mimic_init_thread_copy),
479 };