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