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 Libav.
6 *
7 * Libav 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 * Libav 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 Libav; 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
35typedef struct {
36    AVCodecContext *avctx;
37
38    int             num_vblocks[3];
39    int             num_hblocks[3];
40
41    void           *swap_buf;
42    int             swap_buf_size;
43
44    int             cur_index;
45    int             prev_index;
46
47    AVFrame         buf_ptrs    [16];
48    AVPicture       flipped_ptrs[16];
49
50    DECLARE_ALIGNED(16, DCTELEM, dct_block)[64];
51
52    GetBitContext   gb;
53    ScanTable       scantable;
54    DSPContext      dsp;
55    VLC             vlc;
56
57    /* Kept in the context so multithreading can have a constant to read from */
58    int             next_cur_index;
59    int             next_prev_index;
60} MimicContext;
61
62static 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
87static 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
101static 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
112static av_cold int mimic_decode_init(AVCodecContext *avctx)
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    dsputil_init(&ctx->dsp, avctx);
125    ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable, col_zag);
126
127    return 0;
128}
129
130static int mimic_decode_update_thread_context(AVCodecContext *avctx, const AVCodecContext *avctx_from)
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
147static 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
184static 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        /* Libav'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
228static 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 */
293static void prepare_avpic(MimicContext *ctx, AVPicture *dst, AVPicture *src)
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
303static int mimic_decode_frame(AVCodecContext *avctx, void *data,
304                              int *data_size, AVPacket *avpkt)
305{
306    const uint8_t *buf = avpkt->data;
307    int buf_size = avpkt->size;
308    MimicContext *ctx = avctx->priv_data;
309    int is_pframe;
310    int width, height;
311    int quality, num_coeffs;
312    int swap_buf_size = buf_size - MIMIC_HEADER_SIZE;
313    int res;
314
315    if(buf_size < MIMIC_HEADER_SIZE) {
316        av_log(avctx, AV_LOG_ERROR, "insufficient data\n");
317        return -1;
318    }
319
320    buf       += 2; /* some constant (always 256) */
321    quality    = bytestream_get_le16(&buf);
322    width      = bytestream_get_le16(&buf);
323    height     = bytestream_get_le16(&buf);
324    buf       += 4; /* some constant */
325    is_pframe  = bytestream_get_le32(&buf);
326    num_coeffs = bytestream_get_byte(&buf);
327    buf       += 3; /* some constant */
328
329    if(!ctx->avctx) {
330        int i;
331
332        if(!(width == 160 && height == 120) &&
333           !(width == 320 && height == 240)) {
334            av_log(avctx, AV_LOG_ERROR, "invalid width/height!\n");
335            return -1;
336        }
337
338        ctx->avctx     = avctx;
339        avctx->width   = width;
340        avctx->height  = height;
341        avctx->pix_fmt = PIX_FMT_YUV420P;
342        for(i = 0; i < 3; i++) {
343            ctx->num_vblocks[i] = -((-height) >> (3 + !!i));
344            ctx->num_hblocks[i] =     width   >> (3 + !!i) ;
345        }
346    } else if(width != ctx->avctx->width || height != ctx->avctx->height) {
347        av_log(avctx, AV_LOG_ERROR, "resolution changing is not supported\n");
348        return -1;
349    }
350
351    if(is_pframe && !ctx->buf_ptrs[ctx->prev_index].data[0]) {
352        av_log(avctx, AV_LOG_ERROR, "decoding must start with keyframe\n");
353        return -1;
354    }
355
356    ctx->buf_ptrs[ctx->cur_index].reference = 1;
357    ctx->buf_ptrs[ctx->cur_index].pict_type = is_pframe ? AV_PICTURE_TYPE_P:AV_PICTURE_TYPE_I;
358    if(ff_thread_get_buffer(avctx, &ctx->buf_ptrs[ctx->cur_index])) {
359        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
360        return -1;
361    }
362
363    ctx->next_prev_index = ctx->cur_index;
364    ctx->next_cur_index  = (ctx->cur_index - 1) & 15;
365
366    prepare_avpic(ctx, &ctx->flipped_ptrs[ctx->cur_index],
367                  (AVPicture*) &ctx->buf_ptrs[ctx->cur_index]);
368
369    ff_thread_finish_setup(avctx);
370
371    av_fast_malloc(&ctx->swap_buf, &ctx->swap_buf_size,
372                                 swap_buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
373    if(!ctx->swap_buf)
374        return AVERROR(ENOMEM);
375
376    ctx->dsp.bswap_buf(ctx->swap_buf,
377                        (const uint32_t*) buf,
378                        swap_buf_size>>2);
379    init_get_bits(&ctx->gb, ctx->swap_buf, swap_buf_size << 3);
380
381    res = decode(ctx, quality, num_coeffs, !is_pframe);
382    ff_thread_report_progress(&ctx->buf_ptrs[ctx->cur_index], INT_MAX, 0);
383    if (!res) {
384        if (!(avctx->active_thread_type & FF_THREAD_FRAME)) {
385            ff_thread_release_buffer(avctx, &ctx->buf_ptrs[ctx->cur_index]);
386            return -1;
387        }
388    }
389
390    *(AVFrame*)data = ctx->buf_ptrs[ctx->cur_index];
391    *data_size = sizeof(AVFrame);
392
393    ctx->prev_index = ctx->next_prev_index;
394    ctx->cur_index  = ctx->next_cur_index;
395
396    /* Only release frames that aren't used for backreferences anymore */
397    if(ctx->buf_ptrs[ctx->cur_index].data[0])
398        ff_thread_release_buffer(avctx, &ctx->buf_ptrs[ctx->cur_index]);
399
400    return buf_size;
401}
402
403static av_cold int mimic_decode_end(AVCodecContext *avctx)
404{
405    MimicContext *ctx = avctx->priv_data;
406    int i;
407
408    av_free(ctx->swap_buf);
409
410    if (avctx->internal->is_copy)
411        return 0;
412
413    for(i = 0; i < 16; i++)
414        if(ctx->buf_ptrs[i].data[0])
415            ff_thread_release_buffer(avctx, &ctx->buf_ptrs[i]);
416    ff_free_vlc(&ctx->vlc);
417
418    return 0;
419}
420
421AVCodec ff_mimic_decoder = {
422    .name           = "mimic",
423    .type           = AVMEDIA_TYPE_VIDEO,
424    .id             = CODEC_ID_MIMIC,
425    .priv_data_size = sizeof(MimicContext),
426    .init           = mimic_decode_init,
427    .close          = mimic_decode_end,
428    .decode         = mimic_decode_frame,
429    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
430    .long_name = NULL_IF_CONFIG_SMALL("Mimic"),
431    .update_thread_context = ONLY_IF_THREADS_ENABLED(mimic_decode_update_thread_context)
432};
433