GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavcodec/mimic.c Lines: 130 175 74.3 %
Date: 2019-11-20 04:07:19 Branches: 63 102 61.8 %

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
    if (!avctx->internal->is_copy)
132
2
        ff_free_vlc(&ctx->vlc);
133
134
2
    return 0;
135
}
136
137
2
static av_cold int mimic_decode_init(AVCodecContext *avctx)
138
{
139
2
    MimicContext *ctx = avctx->priv_data;
140
    int ret, i;
141
142
2
    avctx->internal->allocate_progress = 1;
143
144
2
    ctx->prev_index = 0;
145
2
    ctx->cur_index  = 15;
146
147
2
    if ((ret = init_vlc(&ctx->vlc, 11, FF_ARRAY_ELEMS(huffbits),
148
                        huffbits, 1, 1, huffcodes, 4, 4, 0)) < 0) {
149
        av_log(avctx, AV_LOG_ERROR, "error initializing vlc table\n");
150
        return ret;
151
    }
152
2
    ff_blockdsp_init(&ctx->bdsp, avctx);
153
2
    ff_bswapdsp_init(&ctx->bbdsp);
154
2
    ff_hpeldsp_init(&ctx->hdsp, avctx->flags);
155
2
    ff_idctdsp_init(&ctx->idsp, avctx);
156
2
    ff_init_scantable(ctx->idsp.idct_permutation, &ctx->scantable, col_zag);
157
158
34
    for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) {
159
32
        ctx->frames[i].f = av_frame_alloc();
160
32
        if (!ctx->frames[i].f) {
161
            mimic_decode_end(avctx);
162
            return AVERROR(ENOMEM);
163
        }
164
    }
165
166
2
    return 0;
167
}
168
169
#if HAVE_THREADS
170
static int mimic_decode_update_thread_context(AVCodecContext *avctx, const AVCodecContext *avctx_from)
171
{
172
    MimicContext *dst = avctx->priv_data, *src = avctx_from->priv_data;
173
    int i, ret;
174
175
    if (avctx == avctx_from)
176
        return 0;
177
178
    dst->cur_index  = src->next_cur_index;
179
    dst->prev_index = src->next_prev_index;
180
181
    for (i = 0; i < FF_ARRAY_ELEMS(dst->frames); i++) {
182
        ff_thread_release_buffer(avctx, &dst->frames[i]);
183
        if (i != src->next_cur_index && src->frames[i].f->data[0]) {
184
            ret = ff_thread_ref_frame(&dst->frames[i], &src->frames[i]);
185
            if (ret < 0)
186
                return ret;
187
        }
188
    }
189
190
    return 0;
191
}
192
#endif
193
194
static const int8_t vlcdec_lookup[9][64] = {
195
    {    0, },
196
    {   -1,   1, },
197
    {   -3,   3,   -2,   2, },
198
    {   -7,   7,   -6,   6,   -5,   5,   -4,   4, },
199
    {  -15,  15,  -14,  14,  -13,  13,  -12,  12,
200
       -11,  11,  -10,  10,   -9,   9,   -8,   8, },
201
    {  -31,  31,  -30,  30,  -29,  29,  -28,  28,
202
       -27,  27,  -26,  26,  -25,  25,  -24,  24,
203
       -23,  23,  -22,  22,  -21,  21,  -20,  20,
204
       -19,  19,  -18,  18,  -17,  17,  -16,  16, },
205
    {  -63,  63,  -62,  62,  -61,  61,  -60,  60,
206
       -59,  59,  -58,  58,  -57,  57,  -56,  56,
207
       -55,  55,  -54,  54,  -53,  53,  -52,  52,
208
       -51,  51,  -50,  50,  -49,  49,  -48,  48,
209
       -47,  47,  -46,  46,  -45,  45,  -44,  44,
210
       -43,  43,  -42,  42,  -41,  41,  -40,  40,
211
       -39,  39,  -38,  38,  -37,  37,  -36,  36,
212
       -35,  35,  -34,  34,  -33,  33,  -32,  32, },
213
    { -127, 127, -126, 126, -125, 125, -124, 124,
214
      -123, 123, -122, 122, -121, 121, -120, 120,
215
      -119, 119, -118, 118, -117, 117, -116, 116,
216
      -115, 115, -114, 114, -113, 113, -112, 112,
217
      -111, 111, -110, 110, -109, 109, -108, 108,
218
      -107, 107, -106, 106, -105, 105, -104, 104,
219
      -103, 103, -102, 102, -101, 101, -100, 100,
220
       -99,  99,  -98,  98,  -97,  97,  -96,  96, },
221
    {  -95,  95,  -94,  94,  -93,  93,  -92,  92,
222
       -91,  91,  -90,  90,  -89,  89,  -88,  88,
223
       -87,  87,  -86,  86,  -85,  85,  -84,  84,
224
       -83,  83,  -82,  82,  -81,  81,  -80,  80,
225
       -79,  79,  -78,  78,  -77,  77,  -76,  76,
226
       -75,  75,  -74,  74,  -73,  73,  -72,  72,
227
       -71,  71,  -70,  70,  -69,  69,  -68,  68,
228
       -67,  67,  -66,  66,  -65,  65,  -64,  64, },
229
};
230
231
44548
static int vlc_decode_block(MimicContext *ctx, int num_coeffs, int qscale)
232
{
233
44548
    int16_t *block = ctx->dct_block;
234
    unsigned int pos;
235
236
44548
    ctx->bdsp.clear_block(block);
237
238
44548
    block[0] = get_bits(&ctx->gb, 8) << 3;
239
240
304893
    for (pos = 1; pos < num_coeffs; pos++) {
241
        uint32_t vlc, num_bits;
242
        int value;
243
        int coeff;
244
245
302169
        vlc = get_vlc2(&ctx->gb, ctx->vlc.table, ctx->vlc.bits, 3);
246
302169
        if (!vlc) /* end-of-block code */
247
41824
            return 0;
248
260345
        if (vlc == -1)
249
            return AVERROR_INVALIDDATA;
250
251
        /* pos_add and num_bits are coded in the vlc code */
252
260345
        pos     += vlc & 15; // pos_add
253
260345
        num_bits = vlc >> 4; // num_bits
254
255
260345
        if (pos >= 64)
256
            return AVERROR_INVALIDDATA;
257
258
260345
        value = get_bits(&ctx->gb, num_bits);
259
260
        /* FFmpeg's IDCT behaves somewhat different from the original code, so
261
         * a factor of 4 was added to the input */
262
263
260345
        coeff = ((int8_t*)vlcdec_lookup[num_bits])[value];
264
260345
        if (pos < 3)
265
50048
            coeff *= 16;
266
        else /* TODO Use >> 10 instead of / 1001 */
267
210297
            coeff = (coeff * qscale) / 1001;
268
269
260345
        block[ctx->scantable.permutated[pos]] = coeff;
270
    }
271
272
2724
    return 0;
273
}
274
275
77
static int decode(MimicContext *ctx, int quality, int num_coeffs,
276
                  int is_iframe)
277
{
278
77
    int ret, y, x, plane, cur_row = 0;
279
280
308
    for (plane = 0; plane < 3; plane++) {
281
231
        const int is_chroma = !!plane;
282
231
        const int qscale    = av_clip(10000 - quality, is_chroma ? 1000 : 2000,
283
                                      10000) << 2;
284
231
        const int stride    = ctx->frames[ctx->cur_index ].f->linesize[plane];
285
231
        const uint8_t *src  = ctx->frames[ctx->prev_index].f->data[plane];
286
231
        uint8_t       *dst  = ctx->frames[ctx->cur_index ].f->data[plane];
287
288
4851
        for (y = 0; y < ctx->num_vblocks[plane]; y++) {
289
143220
            for (x = 0; x < ctx->num_hblocks[plane]; x++) {
290
                /* Check for a change condition in the current block.
291
                 * - iframes always change.
292
                 * - Luma plane changes on get_bits1 == 0
293
                 * - Chroma planes change on get_bits1 == 1 */
294

138600
                if (is_iframe || get_bits1(&ctx->gb) == is_chroma) {
295
                    /* Luma planes may use a backreference from the 15 last
296
                     * frames preceding the previous. (get_bits1 == 1)
297
                     * Chroma planes don't use backreferences. */
298

50491
                    if (is_chroma || is_iframe || !get_bits1(&ctx->gb)) {
299
44548
                        if ((ret = vlc_decode_block(ctx, num_coeffs,
300
                                                    qscale)) < 0) {
301
                            av_log(ctx->avctx, AV_LOG_ERROR, "Error decoding "
302
                                   "block.\n");
303
                            return ret;
304
                        }
305
44548
                        ctx->idsp.idct_put(dst, stride, ctx->dct_block);
306
                    } else {
307
5943
                        unsigned int backref = get_bits(&ctx->gb, 4);
308
5943
                        int index            = (ctx->cur_index + backref) & 15;
309
5943
                        uint8_t *p           = ctx->frames[index].f->data[0];
310
311

5943
                        if (index != ctx->cur_index && p) {
312
5943
                            ff_thread_await_progress(&ctx->frames[index],
313
                                                     cur_row, 0);
314
5943
                            p += src -
315
5943
                                 ctx->frames[ctx->prev_index].f->data[plane];
316
5943
                            ctx->hdsp.put_pixels_tab[1][0](dst, p, stride, 8);
317
                        } else {
318
                            av_log(ctx->avctx, AV_LOG_ERROR,
319
                                     "No such backreference! Buggy sample.\n");
320
                        }
321
                    }
322
                } else {
323
88109
                    ff_thread_await_progress(&ctx->frames[ctx->prev_index],
324
                                             cur_row, 0);
325
88109
                    ctx->hdsp.put_pixels_tab[1][0](dst, src, stride, 8);
326
                }
327
138600
                src += 8;
328
138600
                dst += 8;
329
            }
330
4620
            src += (stride - ctx->num_hblocks[plane]) << 3;
331
4620
            dst += (stride - ctx->num_hblocks[plane]) << 3;
332
333
4620
            ff_thread_report_progress(&ctx->frames[ctx->cur_index],
334
                                      cur_row++, 0);
335
        }
336
    }
337
338
77
    return 0;
339
}
340
341
/**
342
 * Flip the buffer upside-down and put it in the YVU order to revert the
343
 * way Mimic encodes frames.
344
 */
345
77
static void flip_swap_frame(AVFrame *f)
346
{
347
    int i;
348
77
    uint8_t *data_1 = f->data[1];
349
77
    f->data[0] = f->data[0] + ( f->height       - 1) * f->linesize[0];
350
77
    f->data[1] = f->data[2] + ((f->height >> 1) - 1) * f->linesize[2];
351
77
    f->data[2] = data_1     + ((f->height >> 1) - 1) * f->linesize[1];
352
308
    for (i = 0; i < 3; i++)
353
231
        f->linesize[i] *= -1;
354
77
}
355
356
77
static int mimic_decode_frame(AVCodecContext *avctx, void *data,
357
                              int *got_frame, AVPacket *avpkt)
358
{
359
77
    const uint8_t *buf = avpkt->data;
360
77
    int buf_size       = avpkt->size;
361
77
    int swap_buf_size  = buf_size - MIMIC_HEADER_SIZE;
362
77
    MimicContext *ctx  = avctx->priv_data;
363
    GetByteContext gb;
364
    int is_pframe;
365
    int width, height;
366
    int quality, num_coeffs;
367
    int res;
368
369
77
    if (buf_size <= MIMIC_HEADER_SIZE) {
370
        av_log(avctx, AV_LOG_ERROR, "insufficient data\n");
371
        return AVERROR_INVALIDDATA;
372
    }
373
374
77
    bytestream2_init(&gb, buf, MIMIC_HEADER_SIZE);
375
77
    bytestream2_skip(&gb, 2); /* some constant (always 256) */
376
77
    quality    = bytestream2_get_le16u(&gb);
377
77
    width      = bytestream2_get_le16u(&gb);
378
77
    height     = bytestream2_get_le16u(&gb);
379
77
    bytestream2_skip(&gb, 4); /* some constant */
380
77
    is_pframe  = bytestream2_get_le32u(&gb);
381
77
    num_coeffs = bytestream2_get_byteu(&gb);
382
77
    bytestream2_skip(&gb, 3); /* some constant */
383
384
77
    if (!ctx->avctx) {
385
        int i;
386
387

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

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

77
    if (is_pframe && !ctx->frames[ctx->prev_index].f->data[0]) {
409
        av_log(avctx, AV_LOG_ERROR, "decoding must start with keyframe\n");
410
        return AVERROR_INVALIDDATA;
411
    }
412
413
77
    ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);
414
77
    ctx->frames[ctx->cur_index].f->pict_type = is_pframe ? AV_PICTURE_TYPE_P :
415
                                                           AV_PICTURE_TYPE_I;
416
77
    if ((res = ff_thread_get_buffer(avctx, &ctx->frames[ctx->cur_index],
417
                                    AV_GET_BUFFER_FLAG_REF)) < 0)
418
        return res;
419
420
77
    ctx->next_prev_index = ctx->cur_index;
421
77
    ctx->next_cur_index  = (ctx->cur_index - 1) & 15;
422
423
77
    ff_thread_finish_setup(avctx);
424
425
77
    av_fast_padded_malloc(&ctx->swap_buf, &ctx->swap_buf_size, swap_buf_size);
426
77
    if (!ctx->swap_buf)
427
        return AVERROR(ENOMEM);
428
429
77
    ctx->bbdsp.bswap_buf(ctx->swap_buf,
430
77
                         (const uint32_t *) (buf + MIMIC_HEADER_SIZE),
431
                         swap_buf_size >> 2);
432
77
    init_get_bits(&ctx->gb, ctx->swap_buf, swap_buf_size << 3);
433
434
77
    res = decode(ctx, quality, num_coeffs, !is_pframe);
435
77
    ff_thread_report_progress(&ctx->frames[ctx->cur_index], INT_MAX, 0);
436
77
    if (res < 0) {
437
        if (!(avctx->active_thread_type & FF_THREAD_FRAME))
438
            ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);
439
        return res;
440
    }
441
442
77
    if ((res = av_frame_ref(data, ctx->frames[ctx->cur_index].f)) < 0)
443
        return res;
444
77
    *got_frame      = 1;
445
446
77
    flip_swap_frame(data);
447
448
77
    ctx->prev_index = ctx->next_prev_index;
449
77
    ctx->cur_index  = ctx->next_cur_index;
450
451
77
    return buf_size;
452
}
453
454
#if HAVE_THREADS
455
static av_cold int mimic_init_thread_copy(AVCodecContext *avctx)
456
{
457
    MimicContext *ctx = avctx->priv_data;
458
    int i;
459
460
    for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) {
461
        ctx->frames[i].f = av_frame_alloc();
462
        if (!ctx->frames[i].f) {
463
            mimic_decode_end(avctx);
464
            return AVERROR(ENOMEM);
465
        }
466
    }
467
468
    return 0;
469
}
470
#endif
471
472
AVCodec ff_mimic_decoder = {
473
    .name                  = "mimic",
474
    .long_name             = NULL_IF_CONFIG_SMALL("Mimic"),
475
    .type                  = AVMEDIA_TYPE_VIDEO,
476
    .id                    = AV_CODEC_ID_MIMIC,
477
    .priv_data_size        = sizeof(MimicContext),
478
    .init                  = mimic_decode_init,
479
    .close                 = mimic_decode_end,
480
    .decode                = mimic_decode_frame,
481
    .capabilities          = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
482
    .update_thread_context = ONLY_IF_THREADS_ENABLED(mimic_decode_update_thread_context),
483
    .init_thread_copy      = ONLY_IF_THREADS_ENABLED(mimic_init_thread_copy),
484
};