xref: /third_party/ffmpeg/libavcodec/mimic.c (revision cabdff1a)
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
44typedef 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
72static VLC block_vlc;
73
74static 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
86static 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
95static 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
106static 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
123static 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
129static 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
156static 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
180static 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
217static 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
261static 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 */
331static 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
342static 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
440const 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