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 "libavutil/mem_internal.h"
27 #include "libavutil/thread.h"
28 
29 #include "avcodec.h"
30 #include "blockdsp.h"
31 #include "codec_internal.h"
32 #include "internal.h"
33 #include "get_bits.h"
34 #include "bytestream.h"
35 #include "bswapdsp.h"
36 #include "hpeldsp.h"
37 #include "idctdsp.h"
38 #include "thread.h"
39 #include "threadframe.h"
40 
41 #define MIMIC_HEADER_SIZE   20
42 #define MIMIC_VLC_BITS      11
43 
44 typedef struct MimicContext {
45     AVCodecContext *avctx;
46 
47     int             num_vblocks[3];
48     int             num_hblocks[3];
49 
50     void           *swap_buf;
51     int             swap_buf_size;
52 
53     int             cur_index;
54     int             prev_index;
55 
56     ThreadFrame     frames     [16];
57 
58     DECLARE_ALIGNED(32, int16_t, dct_block)[64];
59 
60     GetBitContext   gb;
61     ScanTable       scantable;
62     BlockDSPContext bdsp;
63     BswapDSPContext bbdsp;
64     HpelDSPContext  hdsp;
65     IDCTDSPContext  idsp;
66 
67     /* Kept in the context so multithreading can have a constant to read from */
68     int             next_cur_index;
69     int             next_prev_index;
70 } MimicContext;
71 
72 static VLC block_vlc;
73 
74 static const uint8_t huffsyms[] = {
75     0x10, 0x20, 0x30, 0x00, 0x11, 0x40, 0x50, 0x12, 0x13, 0x21, 0x31, 0x60,
76     0x14, 0x15, 0x16, 0x22, 0x41, 0x17, 0x18, 0x23, 0x24, 0x25, 0x32, 0x42,
77     0x51, 0x61, 0x70, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x26, 0x27,
78     0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x33, 0x34, 0x35, 0x36, 0x37,
79     0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x43, 0x44, 0x45, 0x46, 0x47,
80     0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x52, 0x53, 0x54, 0x55, 0x56,
81     0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x62, 0x63, 0x64, 0x65,
82     0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x71, 0x72, 0x73,
83     0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E,
84 };
85 
86 static const uint8_t huffbits[] = {
87      2,  2,  3,  4,  4,  4,  5,  5,  6,  6,  6,  6,  7,  7,  7,  7,  8,  8,
88      8,  8,  9,  9,  9,  9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12,
89     13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17, 17,
90     17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21,
91     22, 22, 22, 22, 23, 23, 23, 23, 24, 24, 24, 24, 25, 25, 25, 25, 26, 26,
92     26, 26, 27, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30,
93 };
94 
95 static const uint8_t col_zag[64] = {
96      0,  8,  1,  2,  9, 16, 24, 17,
97     10,  3,  4, 11, 18, 25, 32, 40,
98     33, 26, 19, 12,  5,  6, 13, 20,
99     27, 34, 41, 48, 56, 49, 42, 35,
100     28, 21, 14,  7, 15, 22, 29, 36,
101     43, 50, 57, 58, 51, 44, 37, 30,
102     23, 31, 38, 45, 52, 59, 39, 46,
103     53, 60, 61, 54, 47, 55, 62, 63,
104 };
105 
mimic_decode_end(AVCodecContext *avctx)106 static av_cold int mimic_decode_end(AVCodecContext *avctx)
107 {
108     MimicContext *ctx = avctx->priv_data;
109     int i;
110 
111     av_freep(&ctx->swap_buf);
112     ctx->swap_buf_size = 0;
113 
114     for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) {
115         if (ctx->frames[i].f)
116             ff_thread_release_ext_buffer(avctx, &ctx->frames[i]);
117         av_frame_free(&ctx->frames[i].f);
118     }
119 
120     return 0;
121 }
122 
mimic_init_static(void)123 static av_cold void mimic_init_static(void)
124 {
125     INIT_VLC_STATIC_FROM_LENGTHS(&block_vlc, MIMIC_VLC_BITS, FF_ARRAY_ELEMS(huffbits),
126                                  huffbits, 1, huffsyms, 1, 1, 0, 0, 4368);
127 }
128 
mimic_decode_init(AVCodecContext *avctx)129 static av_cold int mimic_decode_init(AVCodecContext *avctx)
130 {
131     static AVOnce init_static_once = AV_ONCE_INIT;
132     MimicContext *ctx = avctx->priv_data;
133     int i;
134 
135     ctx->prev_index = 0;
136     ctx->cur_index  = 15;
137 
138     ff_blockdsp_init(&ctx->bdsp, avctx);
139     ff_bswapdsp_init(&ctx->bbdsp);
140     ff_hpeldsp_init(&ctx->hdsp, avctx->flags);
141     ff_idctdsp_init(&ctx->idsp, avctx);
142     ff_init_scantable(ctx->idsp.idct_permutation, &ctx->scantable, col_zag);
143 
144     for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) {
145         ctx->frames[i].f = av_frame_alloc();
146         if (!ctx->frames[i].f)
147             return AVERROR(ENOMEM);
148     }
149 
150     ff_thread_once(&init_static_once, mimic_init_static);
151 
152     return 0;
153 }
154 
155 #if HAVE_THREADS
mimic_decode_update_thread_context(AVCodecContext *avctx, const AVCodecContext *avctx_from)156 static int mimic_decode_update_thread_context(AVCodecContext *avctx, const AVCodecContext *avctx_from)
157 {
158     MimicContext *dst = avctx->priv_data, *src = avctx_from->priv_data;
159     int i, ret;
160 
161     if (avctx == avctx_from)
162         return 0;
163 
164     dst->cur_index  = src->next_cur_index;
165     dst->prev_index = src->next_prev_index;
166 
167     for (i = 0; i < FF_ARRAY_ELEMS(dst->frames); i++) {
168         ff_thread_release_ext_buffer(avctx, &dst->frames[i]);
169         if (i != src->next_cur_index && src->frames[i].f->data[0]) {
170             ret = ff_thread_ref_frame(&dst->frames[i], &src->frames[i]);
171             if (ret < 0)
172                 return ret;
173         }
174     }
175 
176     return 0;
177 }
178 #endif
179 
180 static const int8_t vlcdec_lookup[9][64] = {
181     {    0, },
182     {   -1,   1, },
183     {   -3,   3,   -2,   2, },
184     {   -7,   7,   -6,   6,   -5,   5,   -4,   4, },
185     {  -15,  15,  -14,  14,  -13,  13,  -12,  12,
186        -11,  11,  -10,  10,   -9,   9,   -8,   8, },
187     {  -31,  31,  -30,  30,  -29,  29,  -28,  28,
188        -27,  27,  -26,  26,  -25,  25,  -24,  24,
189        -23,  23,  -22,  22,  -21,  21,  -20,  20,
190        -19,  19,  -18,  18,  -17,  17,  -16,  16, },
191     {  -63,  63,  -62,  62,  -61,  61,  -60,  60,
192        -59,  59,  -58,  58,  -57,  57,  -56,  56,
193        -55,  55,  -54,  54,  -53,  53,  -52,  52,
194        -51,  51,  -50,  50,  -49,  49,  -48,  48,
195        -47,  47,  -46,  46,  -45,  45,  -44,  44,
196        -43,  43,  -42,  42,  -41,  41,  -40,  40,
197        -39,  39,  -38,  38,  -37,  37,  -36,  36,
198        -35,  35,  -34,  34,  -33,  33,  -32,  32, },
199     { -127, 127, -126, 126, -125, 125, -124, 124,
200       -123, 123, -122, 122, -121, 121, -120, 120,
201       -119, 119, -118, 118, -117, 117, -116, 116,
202       -115, 115, -114, 114, -113, 113, -112, 112,
203       -111, 111, -110, 110, -109, 109, -108, 108,
204       -107, 107, -106, 106, -105, 105, -104, 104,
205       -103, 103, -102, 102, -101, 101, -100, 100,
206        -99,  99,  -98,  98,  -97,  97,  -96,  96, },
207     {  -95,  95,  -94,  94,  -93,  93,  -92,  92,
208        -91,  91,  -90,  90,  -89,  89,  -88,  88,
209        -87,  87,  -86,  86,  -85,  85,  -84,  84,
210        -83,  83,  -82,  82,  -81,  81,  -80,  80,
211        -79,  79,  -78,  78,  -77,  77,  -76,  76,
212        -75,  75,  -74,  74,  -73,  73,  -72,  72,
213        -71,  71,  -70,  70,  -69,  69,  -68,  68,
214        -67,  67,  -66,  66,  -65,  65,  -64,  64, },
215 };
216 
vlc_decode_block(MimicContext *ctx, int num_coeffs, int qscale)217 static int vlc_decode_block(MimicContext *ctx, int num_coeffs, int qscale)
218 {
219     int16_t *block = ctx->dct_block;
220     unsigned int pos;
221 
222     ctx->bdsp.clear_block(block);
223 
224     block[0] = get_bits(&ctx->gb, 8) << 3;
225 
226     for (pos = 1; pos < num_coeffs; pos++) {
227         uint32_t vlc, num_bits;
228         int value;
229         int coeff;
230 
231         vlc = get_vlc2(&ctx->gb, block_vlc.table, MIMIC_VLC_BITS, 3);
232         if (!vlc) /* end-of-block code */
233             return 0;
234         if (vlc == -1)
235             return AVERROR_INVALIDDATA;
236 
237         /* pos_add and num_bits are coded in the vlc code */
238         pos     += vlc & 15; // pos_add
239         num_bits = vlc >> 4; // num_bits
240 
241         if (pos >= 64)
242             return AVERROR_INVALIDDATA;
243 
244         value = get_bits(&ctx->gb, num_bits);
245 
246         /* FFmpeg's IDCT behaves somewhat different from the original code, so
247          * a factor of 4 was added to the input */
248 
249         coeff = ((int8_t*)vlcdec_lookup[num_bits])[value];
250         if (pos < 3)
251             coeff *= 16;
252         else /* TODO Use >> 10 instead of / 1001 */
253             coeff = (coeff * qscale) / 1001;
254 
255         block[ctx->scantable.permutated[pos]] = coeff;
256     }
257 
258     return 0;
259 }
260 
decode(MimicContext *ctx, int quality, int num_coeffs, int is_iframe)261 static int decode(MimicContext *ctx, int quality, int num_coeffs,
262                   int is_iframe)
263 {
264     int ret, y, x, plane, cur_row = 0;
265 
266     for (plane = 0; plane < 3; plane++) {
267         const int is_chroma = !!plane;
268         const int qscale    = av_clip(10000 - quality, is_chroma ? 1000 : 2000,
269                                       10000) << 2;
270         const int stride    = ctx->frames[ctx->cur_index ].f->linesize[plane];
271         const uint8_t *src  = ctx->frames[ctx->prev_index].f->data[plane];
272         uint8_t       *dst  = ctx->frames[ctx->cur_index ].f->data[plane];
273 
274         for (y = 0; y < ctx->num_vblocks[plane]; y++) {
275             for (x = 0; x < ctx->num_hblocks[plane]; x++) {
276                 /* Check for a change condition in the current block.
277                  * - iframes always change.
278                  * - Luma plane changes on get_bits1 == 0
279                  * - Chroma planes change on get_bits1 == 1 */
280                 if (is_iframe || get_bits1(&ctx->gb) == is_chroma) {
281                     /* Luma planes may use a backreference from the 15 last
282                      * frames preceding the previous. (get_bits1 == 1)
283                      * Chroma planes don't use backreferences. */
284                     if (is_chroma || is_iframe || !get_bits1(&ctx->gb)) {
285                         if ((ret = vlc_decode_block(ctx, num_coeffs,
286                                                     qscale)) < 0) {
287                             av_log(ctx->avctx, AV_LOG_ERROR, "Error decoding "
288                                    "block.\n");
289                             return ret;
290                         }
291                         ctx->idsp.idct_put(dst, stride, ctx->dct_block);
292                     } else {
293                         unsigned int backref = get_bits(&ctx->gb, 4);
294                         int index            = (ctx->cur_index + backref) & 15;
295                         uint8_t *p           = ctx->frames[index].f->data[0];
296 
297                         if (index != ctx->cur_index && p) {
298                             ff_thread_await_progress(&ctx->frames[index],
299                                                      cur_row, 0);
300                             p += src -
301                                  ctx->frames[ctx->prev_index].f->data[plane];
302                             ctx->hdsp.put_pixels_tab[1][0](dst, p, stride, 8);
303                         } else {
304                             av_log(ctx->avctx, AV_LOG_ERROR,
305                                      "No such backreference! Buggy sample.\n");
306                         }
307                     }
308                 } else {
309                     ff_thread_await_progress(&ctx->frames[ctx->prev_index],
310                                              cur_row, 0);
311                     ctx->hdsp.put_pixels_tab[1][0](dst, src, stride, 8);
312                 }
313                 src += 8;
314                 dst += 8;
315             }
316             src += (stride - ctx->num_hblocks[plane]) << 3;
317             dst += (stride - ctx->num_hblocks[plane]) << 3;
318 
319             ff_thread_report_progress(&ctx->frames[ctx->cur_index],
320                                       cur_row++, 0);
321         }
322     }
323 
324     return 0;
325 }
326 
327 /**
328  * Flip the buffer upside-down and put it in the YVU order to revert the
329  * way Mimic encodes frames.
330  */
flip_swap_frame(AVFrame *f)331 static void flip_swap_frame(AVFrame *f)
332 {
333     int i;
334     uint8_t *data_1 = f->data[1];
335     f->data[0] = f->data[0] + ( f->height       - 1) * f->linesize[0];
336     f->data[1] = f->data[2] + ((f->height >> 1) - 1) * f->linesize[2];
337     f->data[2] = data_1     + ((f->height >> 1) - 1) * f->linesize[1];
338     for (i = 0; i < 3; i++)
339         f->linesize[i] *= -1;
340 }
341 
mimic_decode_frame(AVCodecContext *avctx, AVFrame *rframe, int *got_frame, AVPacket *avpkt)342 static int mimic_decode_frame(AVCodecContext *avctx, AVFrame *rframe,
343                               int *got_frame, AVPacket *avpkt)
344 {
345     const uint8_t *buf = avpkt->data;
346     int buf_size       = avpkt->size;
347     int swap_buf_size  = buf_size - MIMIC_HEADER_SIZE;
348     MimicContext *ctx  = avctx->priv_data;
349     GetByteContext gb;
350     int is_pframe;
351     int width, height;
352     int quality, num_coeffs;
353     int res;
354 
355     if (buf_size <= MIMIC_HEADER_SIZE) {
356         av_log(avctx, AV_LOG_ERROR, "insufficient data\n");
357         return AVERROR_INVALIDDATA;
358     }
359 
360     bytestream2_init(&gb, buf, MIMIC_HEADER_SIZE);
361     bytestream2_skip(&gb, 2); /* some constant (always 256) */
362     quality    = bytestream2_get_le16u(&gb);
363     width      = bytestream2_get_le16u(&gb);
364     height     = bytestream2_get_le16u(&gb);
365     bytestream2_skip(&gb, 4); /* some constant */
366     is_pframe  = bytestream2_get_le32u(&gb);
367     num_coeffs = bytestream2_get_byteu(&gb);
368     bytestream2_skip(&gb, 3); /* some constant */
369 
370     if (!ctx->avctx) {
371         int i;
372 
373         if (!(width == 160 && height == 120) &&
374             !(width == 320 && height == 240)) {
375             av_log(avctx, AV_LOG_ERROR, "invalid width/height!\n");
376             return AVERROR_INVALIDDATA;
377         }
378 
379         res = ff_set_dimensions(avctx, width, height);
380         if (res < 0)
381             return res;
382 
383         ctx->avctx     = avctx;
384         avctx->pix_fmt = AV_PIX_FMT_YUV420P;
385         for (i = 0; i < 3; i++) {
386             ctx->num_vblocks[i] = AV_CEIL_RSHIFT(height,   3 + !!i);
387             ctx->num_hblocks[i] =                width >> (3 + !!i);
388         }
389     } else if (width != ctx->avctx->width || height != ctx->avctx->height) {
390         avpriv_request_sample(avctx, "Resolution changing");
391         return AVERROR_PATCHWELCOME;
392     }
393 
394     if (is_pframe && !ctx->frames[ctx->prev_index].f->data[0]) {
395         av_log(avctx, AV_LOG_ERROR, "decoding must start with keyframe\n");
396         return AVERROR_INVALIDDATA;
397     }
398 
399     ff_thread_release_ext_buffer(avctx, &ctx->frames[ctx->cur_index]);
400     ctx->frames[ctx->cur_index].f->pict_type = is_pframe ? AV_PICTURE_TYPE_P :
401                                                            AV_PICTURE_TYPE_I;
402     if ((res = ff_thread_get_ext_buffer(avctx, &ctx->frames[ctx->cur_index],
403                                         AV_GET_BUFFER_FLAG_REF)) < 0)
404         return res;
405 
406     ctx->next_prev_index = ctx->cur_index;
407     ctx->next_cur_index  = (ctx->cur_index - 1) & 15;
408 
409     ff_thread_finish_setup(avctx);
410 
411     av_fast_padded_malloc(&ctx->swap_buf, &ctx->swap_buf_size, swap_buf_size);
412     if (!ctx->swap_buf)
413         return AVERROR(ENOMEM);
414 
415     ctx->bbdsp.bswap_buf(ctx->swap_buf,
416                          (const uint32_t *) (buf + MIMIC_HEADER_SIZE),
417                          swap_buf_size >> 2);
418     init_get_bits(&ctx->gb, ctx->swap_buf, swap_buf_size << 3);
419 
420     res = decode(ctx, quality, num_coeffs, !is_pframe);
421     ff_thread_report_progress(&ctx->frames[ctx->cur_index], INT_MAX, 0);
422     if (res < 0) {
423         if (!(avctx->active_thread_type & FF_THREAD_FRAME))
424             ff_thread_release_ext_buffer(avctx, &ctx->frames[ctx->cur_index]);
425         return res;
426     }
427 
428     if ((res = av_frame_ref(rframe, ctx->frames[ctx->cur_index].f)) < 0)
429         return res;
430     *got_frame      = 1;
431 
432     flip_swap_frame(rframe);
433 
434     ctx->prev_index = ctx->next_prev_index;
435     ctx->cur_index  = ctx->next_cur_index;
436 
437     return buf_size;
438 }
439 
440 const FFCodec ff_mimic_decoder = {
441     .p.name                = "mimic",
442     .p.long_name           = NULL_IF_CONFIG_SMALL("Mimic"),
443     .p.type                = AVMEDIA_TYPE_VIDEO,
444     .p.id                  = AV_CODEC_ID_MIMIC,
445     .priv_data_size        = sizeof(MimicContext),
446     .init                  = mimic_decode_init,
447     .close                 = mimic_decode_end,
448     FF_CODEC_DECODE_CB(mimic_decode_frame),
449     .p.capabilities        = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
450     .update_thread_context = ONLY_IF_THREADS_ENABLED(mimic_decode_update_thread_context),
451     .caps_internal         = FF_CODEC_CAP_ALLOCATE_PROGRESS |
452                              FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE,
453 };
454