GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavcodec/mimic.c Lines: 128 165 77.6 %
Date: 2020-07-13 04:22:34 Branches: 62 96 64.6 %

Line Branch Exec Source
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
117
2
static av_cold int mimic_decode_end(AVCodecContext *avctx)
118
{
119
2
    MimicContext *ctx = avctx->priv_data;
120
    int i;
121
122
2
    av_freep(&ctx->swap_buf);
123
2
    ctx->swap_buf_size = 0;
124
125
34
    for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) {
126
32
        if (ctx->frames[i].f)
127
32
            ff_thread_release_buffer(avctx, &ctx->frames[i]);
128
32
        av_frame_free(&ctx->frames[i].f);
129
    }
130
131
2
    ff_free_vlc(&ctx->vlc);
132
133
2
    return 0;
134
}
135
136
2
static av_cold int mimic_decode_init(AVCodecContext *avctx)
137
{
138
2
    MimicContext *ctx = avctx->priv_data;
139
    int ret, i;
140
141
2
    ctx->prev_index = 0;
142
2
    ctx->cur_index  = 15;
143
144
2
    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
2
    ff_blockdsp_init(&ctx->bdsp, avctx);
150
2
    ff_bswapdsp_init(&ctx->bbdsp);
151
2
    ff_hpeldsp_init(&ctx->hdsp, avctx->flags);
152
2
    ff_idctdsp_init(&ctx->idsp, avctx);
153
2
    ff_init_scantable(ctx->idsp.idct_permutation, &ctx->scantable, col_zag);
154
155
34
    for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) {
156
32
        ctx->frames[i].f = av_frame_alloc();
157
32
        if (!ctx->frames[i].f) {
158
            mimic_decode_end(avctx);
159
            return AVERROR(ENOMEM);
160
        }
161
    }
162
163
2
    return 0;
164
}
165
166
#if HAVE_THREADS
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
228
44548
static int vlc_decode_block(MimicContext *ctx, int num_coeffs, int qscale)
229
{
230
44548
    int16_t *block = ctx->dct_block;
231
    unsigned int pos;
232
233
44548
    ctx->bdsp.clear_block(block);
234
235
44548
    block[0] = get_bits(&ctx->gb, 8) << 3;
236
237
304893
    for (pos = 1; pos < num_coeffs; pos++) {
238
        uint32_t vlc, num_bits;
239
        int value;
240
        int coeff;
241
242
302169
        vlc = get_vlc2(&ctx->gb, ctx->vlc.table, ctx->vlc.bits, 3);
243
302169
        if (!vlc) /* end-of-block code */
244
41824
            return 0;
245
260345
        if (vlc == -1)
246
            return AVERROR_INVALIDDATA;
247
248
        /* pos_add and num_bits are coded in the vlc code */
249
260345
        pos     += vlc & 15; // pos_add
250
260345
        num_bits = vlc >> 4; // num_bits
251
252
260345
        if (pos >= 64)
253
            return AVERROR_INVALIDDATA;
254
255
260345
        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
260345
        coeff = ((int8_t*)vlcdec_lookup[num_bits])[value];
261
260345
        if (pos < 3)
262
50048
            coeff *= 16;
263
        else /* TODO Use >> 10 instead of / 1001 */
264
210297
            coeff = (coeff * qscale) / 1001;
265
266
260345
        block[ctx->scantable.permutated[pos]] = coeff;
267
    }
268
269
2724
    return 0;
270
}
271
272
77
static int decode(MimicContext *ctx, int quality, int num_coeffs,
273
                  int is_iframe)
274
{
275
77
    int ret, y, x, plane, cur_row = 0;
276
277
308
    for (plane = 0; plane < 3; plane++) {
278
231
        const int is_chroma = !!plane;
279
231
        const int qscale    = av_clip(10000 - quality, is_chroma ? 1000 : 2000,
280
                                      10000) << 2;
281
231
        const int stride    = ctx->frames[ctx->cur_index ].f->linesize[plane];
282
231
        const uint8_t *src  = ctx->frames[ctx->prev_index].f->data[plane];
283
231
        uint8_t       *dst  = ctx->frames[ctx->cur_index ].f->data[plane];
284
285
4851
        for (y = 0; y < ctx->num_vblocks[plane]; y++) {
286
143220
            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

138600
                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

50491
                    if (is_chroma || is_iframe || !get_bits1(&ctx->gb)) {
296
44548
                        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
44548
                        ctx->idsp.idct_put(dst, stride, ctx->dct_block);
303
                    } else {
304
5943
                        unsigned int backref = get_bits(&ctx->gb, 4);
305
5943
                        int index            = (ctx->cur_index + backref) & 15;
306
5943
                        uint8_t *p           = ctx->frames[index].f->data[0];
307
308

5943
                        if (index != ctx->cur_index && p) {
309
5943
                            ff_thread_await_progress(&ctx->frames[index],
310
                                                     cur_row, 0);
311
5943
                            p += src -
312
5943
                                 ctx->frames[ctx->prev_index].f->data[plane];
313
5943
                            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
88109
                    ff_thread_await_progress(&ctx->frames[ctx->prev_index],
321
                                             cur_row, 0);
322
88109
                    ctx->hdsp.put_pixels_tab[1][0](dst, src, stride, 8);
323
                }
324
138600
                src += 8;
325
138600
                dst += 8;
326
            }
327
4620
            src += (stride - ctx->num_hblocks[plane]) << 3;
328
4620
            dst += (stride - ctx->num_hblocks[plane]) << 3;
329
330
4620
            ff_thread_report_progress(&ctx->frames[ctx->cur_index],
331
                                      cur_row++, 0);
332
        }
333
    }
334
335
77
    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
 */
342
77
static void flip_swap_frame(AVFrame *f)
343
{
344
    int i;
345
77
    uint8_t *data_1 = f->data[1];
346
77
    f->data[0] = f->data[0] + ( f->height       - 1) * f->linesize[0];
347
77
    f->data[1] = f->data[2] + ((f->height >> 1) - 1) * f->linesize[2];
348
77
    f->data[2] = data_1     + ((f->height >> 1) - 1) * f->linesize[1];
349
308
    for (i = 0; i < 3; i++)
350
231
        f->linesize[i] *= -1;
351
77
}
352
353
77
static int mimic_decode_frame(AVCodecContext *avctx, void *data,
354
                              int *got_frame, AVPacket *avpkt)
355
{
356
77
    const uint8_t *buf = avpkt->data;
357
77
    int buf_size       = avpkt->size;
358
77
    int swap_buf_size  = buf_size - MIMIC_HEADER_SIZE;
359
77
    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
77
    if (buf_size <= MIMIC_HEADER_SIZE) {
367
        av_log(avctx, AV_LOG_ERROR, "insufficient data\n");
368
        return AVERROR_INVALIDDATA;
369
    }
370
371
77
    bytestream2_init(&gb, buf, MIMIC_HEADER_SIZE);
372
77
    bytestream2_skip(&gb, 2); /* some constant (always 256) */
373
77
    quality    = bytestream2_get_le16u(&gb);
374
77
    width      = bytestream2_get_le16u(&gb);
375
77
    height     = bytestream2_get_le16u(&gb);
376
77
    bytestream2_skip(&gb, 4); /* some constant */
377
77
    is_pframe  = bytestream2_get_le32u(&gb);
378
77
    num_coeffs = bytestream2_get_byteu(&gb);
379
77
    bytestream2_skip(&gb, 3); /* some constant */
380
381
77
    if (!ctx->avctx) {
382
        int i;
383
384

2
        if (!(width == 160 && height == 120) &&
385
2
            !(width == 320 && height == 240)) {
386
            av_log(avctx, AV_LOG_ERROR, "invalid width/height!\n");
387
            return AVERROR_INVALIDDATA;
388
        }
389
390
2
        res = ff_set_dimensions(avctx, width, height);
391
2
        if (res < 0)
392
            return res;
393
394
2
        ctx->avctx     = avctx;
395
2
        avctx->pix_fmt = AV_PIX_FMT_YUV420P;
396
8
        for (i = 0; i < 3; i++) {
397
6
            ctx->num_vblocks[i] = AV_CEIL_RSHIFT(height,   3 + !!i);
398
6
            ctx->num_hblocks[i] =                width >> (3 + !!i);
399
        }
400

75
    } else if (width != ctx->avctx->width || height != ctx->avctx->height) {
401
        avpriv_request_sample(avctx, "Resolution changing");
402
        return AVERROR_PATCHWELCOME;
403
    }
404
405

77
    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
77
    ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);
411
77
    ctx->frames[ctx->cur_index].f->pict_type = is_pframe ? AV_PICTURE_TYPE_P :
412
                                                           AV_PICTURE_TYPE_I;
413
77
    if ((res = ff_thread_get_buffer(avctx, &ctx->frames[ctx->cur_index],
414
                                    AV_GET_BUFFER_FLAG_REF)) < 0)
415
        return res;
416
417
77
    ctx->next_prev_index = ctx->cur_index;
418
77
    ctx->next_cur_index  = (ctx->cur_index - 1) & 15;
419
420
77
    ff_thread_finish_setup(avctx);
421
422
77
    av_fast_padded_malloc(&ctx->swap_buf, &ctx->swap_buf_size, swap_buf_size);
423
77
    if (!ctx->swap_buf)
424
        return AVERROR(ENOMEM);
425
426
77
    ctx->bbdsp.bswap_buf(ctx->swap_buf,
427
77
                         (const uint32_t *) (buf + MIMIC_HEADER_SIZE),
428
                         swap_buf_size >> 2);
429
77
    init_get_bits(&ctx->gb, ctx->swap_buf, swap_buf_size << 3);
430
431
77
    res = decode(ctx, quality, num_coeffs, !is_pframe);
432
77
    ff_thread_report_progress(&ctx->frames[ctx->cur_index], INT_MAX, 0);
433
77
    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
77
    if ((res = av_frame_ref(data, ctx->frames[ctx->cur_index].f)) < 0)
440
        return res;
441
77
    *got_frame      = 1;
442
443
77
    flip_swap_frame(data);
444
445
77
    ctx->prev_index = ctx->next_prev_index;
446
77
    ctx->cur_index  = ctx->next_cur_index;
447
448
77
    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
};