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