Statistics
| Branch: | Revision:

ffmpeg / libavcodec / mimic.c @ 2d2b5a14

History | View | Annotate | Download (15.1 KB)

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 "get_bits.h"
28
#include "bytestream.h"
29
#include "dsputil.h"
30
#include "thread.h"
31

    
32
#define MIMIC_HEADER_SIZE   20
33

    
34
typedef struct {
35
    AVCodecContext *avctx;
36

    
37
    int             num_vblocks[3];
38
    int             num_hblocks[3];
39

    
40
    void           *swap_buf;
41
    int             swap_buf_size;
42

    
43
    int             cur_index;
44
    int             prev_index;
45

    
46
    AVFrame         buf_ptrs    [16];
47
    AVPicture       flipped_ptrs[16];
48

    
49
    DECLARE_ALIGNED(16, DCTELEM, dct_block)[64];
50

    
51
    GetBitContext   gb;
52
    ScanTable       scantable;
53
    DSPContext      dsp;
54
    VLC             vlc;
55

    
56
    /* Kept in the context so multithreading can have a constant to read from */
57
    int             next_cur_index;
58
    int             next_prev_index;
59
} MimicContext;
60

    
61
static const uint32_t huffcodes[] = {
62
    0x0000000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
63
    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
64
    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000b,
65
    0x0000001b, 0x00000038, 0x00000078, 0x00000079, 0x0000007a, 0x000000f9,
66
    0x000000fa, 0x000003fb, 0x000007f8, 0x000007f9, 0x000007fa, 0x000007fb,
67
    0x00000ff8, 0x00000ff9, 0x00000001, 0x00000039, 0x0000007b, 0x000000fb,
68
    0x000001f8, 0x000001f9, 0x00000ffa, 0x00000ffb, 0x00001ff8, 0x00001ff9,
69
    0x00001ffa, 0x00001ffb, 0x00003ff8, 0x00003ff9, 0x00003ffa, 0x00000000,
70
    0x00000004, 0x0000003a, 0x000001fa, 0x00003ffb, 0x00007ff8, 0x00007ff9,
71
    0x00007ffa, 0x00007ffb, 0x0000fff8, 0x0000fff9, 0x0000fffa, 0x0000fffb,
72
    0x0001fff8, 0x0001fff9, 0x0001fffa, 0x00000000, 0x0000000c, 0x000000f8,
73
    0x000001fb, 0x0001fffb, 0x0003fff8, 0x0003fff9, 0x0003fffa, 0x0003fffb,
74
    0x0007fff8, 0x0007fff9, 0x0007fffa, 0x0007fffb, 0x000ffff8, 0x000ffff9,
75
    0x000ffffa, 0x00000000, 0x0000001a, 0x000003f8, 0x000ffffb, 0x001ffff8,
76
    0x001ffff9, 0x001ffffa, 0x001ffffb, 0x003ffff8, 0x003ffff9, 0x003ffffa,
77
    0x003ffffb, 0x007ffff8, 0x007ffff9, 0x007ffffa, 0x007ffffb, 0x00000000,
78
    0x0000003b, 0x000003f9, 0x00fffff8, 0x00fffff9, 0x00fffffa, 0x00fffffb,
79
    0x01fffff8, 0x01fffff9, 0x01fffffa, 0x01fffffb, 0x03fffff8, 0x03fffff9,
80
    0x03fffffa, 0x03fffffb, 0x07fffff8, 0x00000000, 0x000003fa, 0x07fffff9,
81
    0x07fffffa, 0x07fffffb, 0x0ffffff8, 0x0ffffff9, 0x0ffffffa, 0x0ffffffb,
82
    0x1ffffff8, 0x1ffffff9, 0x1ffffffa, 0x1ffffffb, 0x3ffffff8, 0x3ffffff9,
83
    0x3ffffffa,
84
};
85

    
86
static const uint8_t huffbits[] = {
87
     4,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
88
     0,  0,  0,  0,  2,  4,  5,  6,  7,  7,  7,  8,
89
     8, 10, 11, 11, 11, 11, 12, 12,  2,  6,  7,  8,
90
     9,  9, 12, 12, 13, 13, 13, 13, 14, 14, 14,  0,
91
     3,  6,  9, 14, 15, 15, 15, 15, 16, 16, 16, 16,
92
    17, 17, 17,  0,  4,  8,  9, 17, 18, 18, 18, 18,
93
    19, 19, 19, 19, 20, 20, 20,  0,  5, 10, 20, 21,
94
    21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23,  0,
95
     6, 10, 24, 24, 24, 24, 25, 25, 25, 25, 26, 26,
96
    26, 26, 27,  0, 10, 27, 27, 27, 28, 28, 28, 28,
97
    29, 29, 29, 29, 30, 30, 30,
98
};
99

    
100
static const uint8_t col_zag[64] = {
101
     0,  8,  1,  2,  9, 16, 24, 17,
102
    10,  3,  4, 11, 18, 25, 32, 40,
103
    33, 26, 19, 12,  5,  6, 13, 20,
104
    27, 34, 41, 48, 56, 49, 42, 35,
105
    28, 21, 14,  7, 15, 22, 29, 36,
106
    43, 50, 57, 58, 51, 44, 37, 30,
107
    23, 31, 38, 45, 52, 59, 39, 46,
108
    53, 60, 61, 54, 47, 55, 62, 63,
109
};
110

    
111
static av_cold int mimic_decode_init(AVCodecContext *avctx)
112
{
113
    MimicContext *ctx = avctx->priv_data;
114

    
115
    ctx->prev_index = 0;
116
    ctx->cur_index = 15;
117

    
118
    if(init_vlc(&ctx->vlc, 11, FF_ARRAY_ELEMS(huffbits),
119
                 huffbits, 1, 1, huffcodes, 4, 4, 0)) {
120
        av_log(avctx, AV_LOG_ERROR, "error initializing vlc table\n");
121
        return -1;
122
    }
123
    dsputil_init(&ctx->dsp, avctx);
124
    ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable, col_zag);
125

    
126
    return 0;
127
}
128

    
129
static int mimic_decode_update_thread_context(AVCodecContext *avctx, const AVCodecContext *avctx_from)
130
{
131
    MimicContext *dst = avctx->priv_data, *src = avctx_from->priv_data;
132

    
133
    if (avctx == avctx_from) return 0;
134

    
135
    dst->cur_index  = src->next_cur_index;
136
    dst->prev_index = src->next_prev_index;
137

    
138
    memcpy(dst->buf_ptrs, src->buf_ptrs, sizeof(src->buf_ptrs));
139
    memcpy(dst->flipped_ptrs, src->flipped_ptrs, sizeof(src->flipped_ptrs));
140

    
141
    memset(&dst->buf_ptrs[dst->cur_index], 0, sizeof(AVFrame));
142

    
143
    return 0;
144
}
145

    
146
static const int8_t vlcdec_lookup[9][64] = {
147
    {    0, },
148
    {   -1,   1, },
149
    {   -3,   3,   -2,   2, },
150
    {   -7,   7,   -6,   6,   -5,   5,   -4,   4, },
151
    {  -15,  15,  -14,  14,  -13,  13,  -12,  12,
152
       -11,  11,  -10,  10,   -9,   9,   -8,   8, },
153
    {  -31,  31,  -30,  30,  -29,  29,  -28,  28,
154
       -27,  27,  -26,  26,  -25,  25,  -24,  24,
155
       -23,  23,  -22,  22,  -21,  21,  -20,  20,
156
       -19,  19,  -18,  18,  -17,  17,  -16,  16, },
157
    {  -63,  63,  -62,  62,  -61,  61,  -60,  60,
158
       -59,  59,  -58,  58,  -57,  57,  -56,  56,
159
       -55,  55,  -54,  54,  -53,  53,  -52,  52,
160
       -51,  51,  -50,  50,  -49,  49,  -48,  48,
161
       -47,  47,  -46,  46,  -45,  45,  -44,  44,
162
       -43,  43,  -42,  42,  -41,  41,  -40,  40,
163
       -39,  39,  -38,  38,  -37,  37,  -36,  36,
164
       -35,  35,  -34,  34,  -33,  33,  -32,  32, },
165
    { -127, 127, -126, 126, -125, 125, -124, 124,
166
      -123, 123, -122, 122, -121, 121, -120, 120,
167
      -119, 119, -118, 118, -117, 117, -116, 116,
168
      -115, 115, -114, 114, -113, 113, -112, 112,
169
      -111, 111, -110, 110, -109, 109, -108, 108,
170
      -107, 107, -106, 106, -105, 105, -104, 104,
171
      -103, 103, -102, 102, -101, 101, -100, 100,
172
       -99,  99,  -98,  98,  -97,  97,  -96,  96, },
173
    {  -95,  95,  -94,  94,  -93,  93,  -92,  92,
174
       -91,  91,  -90,  90,  -89,  89,  -88,  88,
175
       -87,  87,  -86,  86,  -85,  85,  -84,  84,
176
       -83,  83,  -82,  82,  -81,  81,  -80,  80,
177
       -79,  79,  -78,  78,  -77,  77,  -76,  76,
178
       -75,  75,  -74,  74,  -73,  73,  -72,  72,
179
       -71,  71,  -70,  70,  -69,  69,  -68,  68,
180
       -67,  67,  -66,  66,  -65,  65,  -64,  64, },
181
};
182

    
183
static int vlc_decode_block(MimicContext *ctx, int num_coeffs, int qscale)
184
{
185
    DCTELEM *block = ctx->dct_block;
186
    unsigned int pos;
187

    
188
    ctx->dsp.clear_block(block);
189

    
190
    block[0] = get_bits(&ctx->gb, 8) << 3;
191

    
192
    for(pos = 1; pos < num_coeffs; pos++) {
193
        uint32_t vlc, num_bits;
194
        int value;
195
        int coeff;
196

    
197
        vlc = get_vlc2(&ctx->gb, ctx->vlc.table, ctx->vlc.bits, 3);
198
        if(!vlc) /* end-of-block code */
199
            return 1;
200
        if(vlc == -1)
201
            return 0;
202

    
203
        /* pos_add and num_bits are coded in the vlc code */
204
        pos +=     vlc&15; // pos_add
205
        num_bits = vlc>>4; // num_bits
206

    
207
        if(pos >= 64)
208
            return 0;
209

    
210
        value = get_bits(&ctx->gb, num_bits);
211

    
212
        /* FFmpeg's IDCT behaves somewhat different from the original code, so
213
         * a factor of 4 was added to the input */
214

    
215
        coeff = vlcdec_lookup[num_bits][value];
216
        if(pos<3)
217
            coeff <<= 4;
218
        else /* TODO Use >> 10 instead of / 1001 */
219
            coeff = (coeff * qscale) / 1001;
220

    
221
        block[ctx->scantable.permutated[pos]] = coeff;
222
    }
223

    
224
    return 1;
225
}
226

    
227
static int decode(MimicContext *ctx, int quality, int num_coeffs,
228
                  int is_iframe)
229
{
230
    int y, x, plane, cur_row = 0;
231

    
232
    for(plane = 0; plane < 3; plane++) {
233
        const int is_chroma = !!plane;
234
        const int qscale = av_clip(10000-quality,is_chroma?1000:2000,10000)<<2;
235
        const int stride = ctx->flipped_ptrs[ctx->cur_index].linesize[plane];
236
        const uint8_t *src = ctx->flipped_ptrs[ctx->prev_index].data[plane];
237
        uint8_t       *dst = ctx->flipped_ptrs[ctx->cur_index ].data[plane];
238

    
239
        for(y = 0; y < ctx->num_vblocks[plane]; y++) {
240
            for(x = 0; x < ctx->num_hblocks[plane]; x++) {
241

    
242
                /* Check for a change condition in the current block.
243
                 * - iframes always change.
244
                 * - Luma plane changes on get_bits1 == 0
245
                 * - Chroma planes change on get_bits1 == 1 */
246
                if(is_iframe || get_bits1(&ctx->gb) == is_chroma) {
247

    
248
                    /* Luma planes may use a backreference from the 15 last
249
                     * frames preceding the previous. (get_bits1 == 1)
250
                     * Chroma planes don't use backreferences. */
251
                    if(is_chroma || is_iframe || !get_bits1(&ctx->gb)) {
252

    
253
                        if(!vlc_decode_block(ctx, num_coeffs, qscale))
254
                            return 0;
255
                        ctx->dsp.idct_put(dst, stride, ctx->dct_block);
256
                    } else {
257
                        unsigned int backref = get_bits(&ctx->gb, 4);
258
                        int index = (ctx->cur_index+backref)&15;
259
                        uint8_t *p = ctx->flipped_ptrs[index].data[0];
260

    
261
                        ff_thread_await_progress(&ctx->buf_ptrs[index], cur_row, 0);
262
                        if(p) {
263
                            p += src -
264
                                ctx->flipped_ptrs[ctx->prev_index].data[plane];
265
                            ctx->dsp.put_pixels_tab[1][0](dst, p, stride, 8);
266
                        } else {
267
                            av_log(ctx->avctx, AV_LOG_ERROR,
268
                                     "No such backreference! Buggy sample.\n");
269
                        }
270
                    }
271
                } else {
272
                    ff_thread_await_progress(&ctx->buf_ptrs[ctx->prev_index], cur_row, 0);
273
                    ctx->dsp.put_pixels_tab[1][0](dst, src, stride, 8);
274
                }
275
                src += 8;
276
                dst += 8;
277
            }
278
            src += (stride - ctx->num_hblocks[plane])<<3;
279
            dst += (stride - ctx->num_hblocks[plane])<<3;
280

    
281
            ff_thread_report_progress(&ctx->buf_ptrs[ctx->cur_index], cur_row++, 0);
282
        }
283
    }
284

    
285
    return 1;
286
}
287

    
288
/**
289
 * Flip the buffer upside-down and put it in the YVU order to match the
290
 * way Mimic encodes frames.
291
 */
292
static void prepare_avpic(MimicContext *ctx, AVPicture *dst, AVPicture *src)
293
{
294
    int i;
295
    dst->data[0] = src->data[0]+( ctx->avctx->height    -1)*src->linesize[0];
296
    dst->data[1] = src->data[2]+((ctx->avctx->height>>1)-1)*src->linesize[2];
297
    dst->data[2] = src->data[1]+((ctx->avctx->height>>1)-1)*src->linesize[1];
298
    for(i = 0; i < 3; i++)
299
        dst->linesize[i] = -src->linesize[i];
300
}
301

    
302
static int mimic_decode_frame(AVCodecContext *avctx, void *data,
303
                              int *data_size, AVPacket *avpkt)
304
{
305
    const uint8_t *buf = avpkt->data;
306
    int buf_size = avpkt->size;
307
    MimicContext *ctx = avctx->priv_data;
308
    int is_pframe;
309
    int width, height;
310
    int quality, num_coeffs;
311
    int swap_buf_size = buf_size - MIMIC_HEADER_SIZE;
312

    
313
    if(buf_size < MIMIC_HEADER_SIZE) {
314
        av_log(avctx, AV_LOG_ERROR, "insufficient data\n");
315
        return -1;
316
    }
317

    
318
    buf       += 2; /* some constant (always 256) */
319
    quality    = bytestream_get_le16(&buf);
320
    width      = bytestream_get_le16(&buf);
321
    height     = bytestream_get_le16(&buf);
322
    buf       += 4; /* some constant */
323
    is_pframe  = bytestream_get_le32(&buf);
324
    num_coeffs = bytestream_get_byte(&buf);
325
    buf       += 3; /* some constant */
326

    
327
    if(!ctx->avctx) {
328
        int i;
329

    
330
        if(!(width == 160 && height == 120) &&
331
           !(width == 320 && height == 240)) {
332
            av_log(avctx, AV_LOG_ERROR, "invalid width/height!\n");
333
            return -1;
334
        }
335

    
336
        ctx->avctx     = avctx;
337
        avctx->width   = width;
338
        avctx->height  = height;
339
        avctx->pix_fmt = PIX_FMT_YUV420P;
340
        for(i = 0; i < 3; i++) {
341
            ctx->num_vblocks[i] = -((-height) >> (3 + !!i));
342
            ctx->num_hblocks[i] =     width   >> (3 + !!i) ;
343
        }
344
    } else if(width != ctx->avctx->width || height != ctx->avctx->height) {
345
        av_log(avctx, AV_LOG_ERROR, "resolution changing is not supported\n");
346
        return -1;
347
    }
348

    
349
    if(is_pframe && !ctx->buf_ptrs[ctx->prev_index].data[0]) {
350
        av_log(avctx, AV_LOG_ERROR, "decoding must start with keyframe\n");
351
        return -1;
352
    }
353

    
354
    ctx->buf_ptrs[ctx->cur_index].reference = 1;
355
    ctx->buf_ptrs[ctx->cur_index].pict_type = is_pframe ? FF_P_TYPE:FF_I_TYPE;
356
    if(ff_thread_get_buffer(avctx, &ctx->buf_ptrs[ctx->cur_index])) {
357
        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
358
        return -1;
359
    }
360

    
361
    ctx->next_prev_index = ctx->cur_index;
362
    ctx->next_cur_index  = (ctx->cur_index - 1) & 15;
363

    
364
    prepare_avpic(ctx, &ctx->flipped_ptrs[ctx->cur_index],
365
                  (AVPicture*) &ctx->buf_ptrs[ctx->cur_index]);
366

    
367
    ff_thread_finish_setup(avctx);
368

    
369
    av_fast_malloc(&ctx->swap_buf, &ctx->swap_buf_size,
370
                                 swap_buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
371
    if(!ctx->swap_buf)
372
        return AVERROR(ENOMEM);
373

    
374
    ctx->dsp.bswap_buf(ctx->swap_buf,
375
                        (const uint32_t*) buf,
376
                        swap_buf_size>>2);
377
    init_get_bits(&ctx->gb, ctx->swap_buf, swap_buf_size << 3);
378

    
379
    if(!decode(ctx, quality, num_coeffs, !is_pframe)) {
380
        if (avctx->active_thread_type&FF_THREAD_FRAME)
381
            ff_thread_report_progress(&ctx->buf_ptrs[ctx->cur_index], INT_MAX, 0);
382
        else {
383
            ff_thread_release_buffer(avctx, &ctx->buf_ptrs[ctx->cur_index]);
384
            return -1;
385
        }
386
    }
387

    
388
    *(AVFrame*)data = ctx->buf_ptrs[ctx->cur_index];
389
    *data_size = sizeof(AVFrame);
390

    
391
    ctx->prev_index = ctx->next_prev_index;
392
    ctx->cur_index  = ctx->next_cur_index;
393

    
394
    /* Only release frames that aren't used for backreferences anymore */
395
    if(ctx->buf_ptrs[ctx->cur_index].data[0])
396
        ff_thread_release_buffer(avctx, &ctx->buf_ptrs[ctx->cur_index]);
397

    
398
    return buf_size;
399
}
400

    
401
static av_cold int mimic_decode_end(AVCodecContext *avctx)
402
{
403
    MimicContext *ctx = avctx->priv_data;
404
    int i;
405

    
406
    av_free(ctx->swap_buf);
407

    
408
    if(avctx->is_copy) return 0;
409

    
410
    for(i = 0; i < 16; i++)
411
        if(ctx->buf_ptrs[i].data[0])
412
            ff_thread_release_buffer(avctx, &ctx->buf_ptrs[i]);
413
    free_vlc(&ctx->vlc);
414

    
415
    return 0;
416
}
417

    
418
AVCodec ff_mimic_decoder = {
419
    "mimic",
420
    AVMEDIA_TYPE_VIDEO,
421
    CODEC_ID_MIMIC,
422
    sizeof(MimicContext),
423
    mimic_decode_init,
424
    NULL,
425
    mimic_decode_end,
426
    mimic_decode_frame,
427
    CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
428
    .long_name = NULL_IF_CONFIG_SMALL("Mimic"),
429
    .update_thread_context = ONLY_IF_THREADS_ENABLED(mimic_decode_update_thread_context)
430
};