Statistics
| Branch: | Revision:

ffmpeg / libavcodec / mimic.c @ 630e1b27

History | View | Annotate | Download (13.6 KB)

1
/*
2
 * Copyright (C) 2005  Ole Andr? Vadla Ravn?s <oleavr@gmail.com>
3
 * Copyright (C) 2008  Ramiro Polla <ramiro@lisha.ufsc.br>
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 "bitstream.h"
28
#include "bytestream.h"
29
#include "dsputil.h"
30

    
31
#define MIMIC_HEADER_SIZE   20
32

    
33
typedef struct {
34
    AVCodecContext *avctx;
35

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

    
39
    uint8_t        *swap_buf;
40
    int             swap_buf_size;
41

    
42
    int             cur_index;
43
    int             prev_index;
44

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

    
48
    DECLARE_ALIGNED_16(DCTELEM, dct_block[64]);
49

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

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

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

    
95
static 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

    
106
static av_cold int mimic_decode_init(AVCodecContext *avctx)
107
{
108
    MimicContext *ctx = avctx->priv_data;
109

    
110
    ctx->prev_index = 0;
111
    ctx->cur_index = 15;
112

    
113
    if(init_vlc(&ctx->vlc, 11, sizeof(huffbits)/sizeof(huffbits[0]),
114
                 huffbits, 1, 1, huffcodes, 4, 4, 0)) {
115
        av_log(avctx, AV_LOG_ERROR, "error initializing vlc table\n");
116
        return -1;
117
    }
118
    dsputil_init(&ctx->dsp, avctx);
119
    ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable, col_zag);
120

    
121
    return 0;
122
}
123

    
124
const static int8_t vlcdec_lookup[9][64] = {
125
    {    0, },
126
    {   -1,   1, },
127
    {   -3,   3,   -2,   2, },
128
    {   -7,   7,   -6,   6,   -5,   5,   -4,   4, },
129
    {  -15,  15,  -14,  14,  -13,  13,  -12,  12,
130
       -11,  11,  -10,  10,   -9,   9,   -8,   8, },
131
    {  -31,  31,  -30,  30,  -29,  29,  -28,  28,
132
       -27,  27,  -26,  26,  -25,  25,  -24,  24,
133
       -23,  23,  -22,  22,  -21,  21,  -20,  20,
134
       -19,  19,  -18,  18,  -17,  17,  -16,  16, },
135
    {  -63,  63,  -62,  62,  -61,  61,  -60,  60,
136
       -59,  59,  -58,  58,  -57,  57,  -56,  56,
137
       -55,  55,  -54,  54,  -53,  53,  -52,  52,
138
       -51,  51,  -50,  50,  -49,  49,  -48,  48,
139
       -47,  47,  -46,  46,  -45,  45,  -44,  44,
140
       -43,  43,  -42,  42,  -41,  41,  -40,  40,
141
       -39,  39,  -38,  38,  -37,  37,  -36,  36,
142
       -35,  35,  -34,  34,  -33,  33,  -32,  32, },
143
    { -127, 127, -126, 126, -125, 125, -124, 124,
144
      -123, 123, -122, 122, -121, 121, -120, 120,
145
      -119, 119, -118, 118, -117, 117, -116, 116,
146
      -115, 115, -114, 114, -113, 113, -112, 112,
147
      -111, 111, -110, 110, -109, 109, -108, 108,
148
      -107, 107, -106, 106, -105, 105, -104, 104,
149
      -103, 103, -102, 102, -101, 101, -100, 100,
150
       -99,  99,  -98,  98,  -97,  97,  -96,  96, },
151
    {  -95,  95,  -94,  94,  -93,  93,  -92,  92,
152
       -91,  91,  -90,  90,  -89,  89,  -88,  88,
153
       -87,  87,  -86,  86,  -85,  85,  -84,  84,
154
       -83,  83,  -82,  82,  -81,  81,  -80,  80,
155
       -79,  79,  -78,  78,  -77,  77,  -76,  76,
156
       -75,  75,  -74,  74,  -73,  73,  -72,  72,
157
       -71,  71,  -70,  70,  -69,  69,  -68,  68,
158
       -67,  67,  -66,  66,  -65,  65,  -64,  64, },
159
};
160

    
161
static int vlc_decode_block(MimicContext *ctx, int num_coeffs, int qscale)
162
{
163
    DCTELEM *block = ctx->dct_block;
164
    unsigned int pos;
165

    
166
    memset(block, 0, 64 * sizeof(DCTELEM));
167

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

    
170
    for(pos = 1; pos < num_coeffs; pos++) {
171
        uint32_t vlc, num_bits;
172
        int value;
173
        int coeff;
174

    
175
        vlc = get_vlc2(&ctx->gb, ctx->vlc.table, ctx->vlc.bits, 3);
176
        if(!vlc) /* end-of-block code */
177
            return 1;
178
        if(vlc == -1)
179
            return 0;
180

    
181
        /* pos_add and num_bits are coded in the vlc code */
182
        pos +=     vlc&15; // pos_add
183
        num_bits = vlc>>4; // num_bits
184

    
185
        if(pos >= 64)
186
            return 0;
187

    
188
        value = get_bits(&ctx->gb, num_bits);
189

    
190
        /* FFmpeg's IDCT behaves somewhat different from the original code, so
191
         * a factor of 4 was added to the input */
192

    
193
        coeff = vlcdec_lookup[num_bits][value];
194
        if(pos<3)
195
            coeff <<= 4;
196
        else /* TODO Use >> 10 instead of / 1001 */
197
            coeff = (coeff * qscale) / 1001;
198

    
199
        block[ctx->scantable.permutated[pos]] = coeff;
200
    }
201

    
202
    return 1;
203
}
204

    
205
static int decode(MimicContext *ctx, int quality, int num_coeffs,
206
                  int is_iframe)
207
{
208
    int y, x, plane;
209

    
210
    for(plane = 0; plane < 3; plane++) {
211
        const int is_chroma = !!plane;
212
        const int qscale = av_clip(10000-quality,is_chroma?1000:2000,10000)<<2;
213
        const int stride = ctx->flipped_ptrs[ctx->cur_index].linesize[plane];
214
        const uint8_t *src = ctx->flipped_ptrs[ctx->prev_index].data[plane];
215
        uint8_t       *dst = ctx->flipped_ptrs[ctx->cur_index ].data[plane];
216

    
217
        for(y = 0; y < ctx->num_vblocks[plane]; y++) {
218
            for(x = 0; x < ctx->num_hblocks[plane]; x++) {
219

    
220
                /* Check for a change condition in the current block.
221
                 * - iframes always change.
222
                 * - Luma plane changes on get_bits1 == 0
223
                 * - Chroma planes change on get_bits1 == 1 */
224
                if(is_iframe || get_bits1(&ctx->gb) == is_chroma) {
225

    
226
                    /* Luma planes may use a backreference from the 15 last
227
                     * frames preceding the previous. (get_bits1 == 1)
228
                     * Chroma planes don't use backreferences. */
229
                    if(is_chroma || is_iframe || !get_bits1(&ctx->gb)) {
230

    
231
                        if(!vlc_decode_block(ctx, num_coeffs, qscale))
232
                            return 0;
233
                        ctx->dsp.idct_put(dst, stride, ctx->dct_block);
234
                    } else {
235
                        unsigned int backref = get_bits(&ctx->gb, 4);
236
                        int index = (ctx->cur_index+backref)&15;
237
                        uint8_t *p = ctx->flipped_ptrs[index].data[0];
238

    
239
                        if(p) {
240
                            p += src -
241
                                ctx->flipped_ptrs[ctx->prev_index].data[plane];
242
                            ctx->dsp.put_pixels_tab[1][0](dst, p, stride, 8);
243
                        } else {
244
                            av_log(ctx->avctx, AV_LOG_ERROR,
245
                                     "No such backreference! Buggy sample.\n");
246
                        }
247
                    }
248
                } else {
249
                    ctx->dsp.put_pixels_tab[1][0](dst, src, stride, 8);
250
                }
251
                src += 8;
252
                dst += 8;
253
            }
254
            src += (stride - ctx->num_hblocks[plane])<<3;
255
            dst += (stride - ctx->num_hblocks[plane])<<3;
256
        }
257
    }
258

    
259
    return 1;
260
}
261

    
262
/**
263
 * Flip the buffer upside-down and put it in the YVU order to match the
264
 * way Mimic encodes frames.
265
 */
266
static void prepare_avpic(MimicContext *ctx, AVPicture *dst, AVPicture *src)
267
{
268
    int i;
269
    dst->data[0] = src->data[0]+( ctx->avctx->height    -1)*src->linesize[0];
270
    dst->data[1] = src->data[2]+((ctx->avctx->height>>1)-1)*src->linesize[2];
271
    dst->data[2] = src->data[1]+((ctx->avctx->height>>1)-1)*src->linesize[1];
272
    for(i = 0; i < 3; i++)
273
        dst->linesize[i] = -src->linesize[i];
274
}
275

    
276
static int mimic_decode_frame(AVCodecContext *avctx, void *data,
277
                              int *data_size, const uint8_t *buf, int buf_size)
278
{
279
    MimicContext *ctx = avctx->priv_data;
280
    int is_pframe;
281
    int width, height;
282
    int quality, num_coeffs;
283
    int swap_buf_size = buf_size - MIMIC_HEADER_SIZE;
284

    
285
    if(buf_size < MIMIC_HEADER_SIZE) {
286
        av_log(avctx, AV_LOG_ERROR, "insufficient data\n");
287
        return -1;
288
    }
289

    
290
    buf       += 2; /* some constant (always 256) */
291
    quality    = bytestream_get_le16(&buf);
292
    width      = bytestream_get_le16(&buf);
293
    height     = bytestream_get_le16(&buf);
294
    buf       += 4; /* some constant */
295
    is_pframe  = bytestream_get_le32(&buf);
296
    num_coeffs = bytestream_get_byte(&buf);
297
    buf       += 3; /* some constant */
298

    
299
    if(!ctx->avctx) {
300
        int i;
301

    
302
        if(!(width == 160 && height == 120) &&
303
           !(width == 320 && height == 240)) {
304
            av_log(avctx, AV_LOG_ERROR, "invalid width/height!\n");
305
            return -1;
306
        }
307

    
308
        ctx->avctx     = avctx;
309
        avctx->width   = width;
310
        avctx->height  = height;
311
        avctx->pix_fmt = PIX_FMT_YUV420P;
312
        for(i = 0; i < 3; i++) {
313
            ctx->num_vblocks[i] = -((-height) >> (3 + !!i));
314
            ctx->num_hblocks[i] =     width   >> (3 + !!i) ;
315
        }
316
    } else if(width != ctx->avctx->width || height != ctx->avctx->height) {
317
        av_log(avctx, AV_LOG_ERROR, "resolution changing is not supported\n");
318
        return -1;
319
    }
320

    
321
    if(is_pframe && !ctx->buf_ptrs[ctx->prev_index].data[0]) {
322
        av_log(avctx, AV_LOG_ERROR, "decoding must start with keyframe\n");
323
        return -1;
324
    }
325

    
326
    ctx->buf_ptrs[ctx->cur_index].reference = 1;
327
    if(avctx->get_buffer(avctx, &ctx->buf_ptrs[ctx->cur_index])) {
328
        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
329
        return -1;
330
    }
331

    
332
    prepare_avpic(ctx, &ctx->flipped_ptrs[ctx->cur_index],
333
                  (AVPicture*) &ctx->buf_ptrs[ctx->cur_index]);
334

    
335
    ctx->swap_buf = av_fast_realloc(ctx->swap_buf, &ctx->swap_buf_size,
336
                                 swap_buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
337
    if(!ctx->swap_buf)
338
        return AVERROR_NOMEM;
339

    
340
    ctx->dsp.bswap_buf((uint32_t*)ctx->swap_buf,
341
                        (const uint32_t*) buf,
342
                        swap_buf_size>>2);
343
    init_get_bits(&ctx->gb, ctx->swap_buf, swap_buf_size << 3);
344

    
345
    if(!decode(ctx, quality, num_coeffs, !is_pframe)) {
346
        avctx->release_buffer(avctx, &ctx->buf_ptrs[ctx->cur_index]);
347
        return -1;
348
    }
349

    
350
    ctx->buf_ptrs[ctx->cur_index].pict_type = is_pframe ? FF_P_TYPE:FF_I_TYPE;
351
    *(AVFrame*)data = ctx->buf_ptrs[ctx->cur_index];
352
    *data_size = sizeof(AVFrame);
353

    
354
    ctx->prev_index = ctx->cur_index;
355
    ctx->cur_index--;
356
    ctx->cur_index &= 15;
357

    
358
    /* Only release frames that aren't used for backreferences anymore */
359
    if(ctx->buf_ptrs[ctx->cur_index].data[0])
360
        avctx->release_buffer(avctx, &ctx->buf_ptrs[ctx->cur_index]);
361

    
362
    return buf_size;
363
}
364

    
365
static av_cold int mimic_decode_end(AVCodecContext *avctx)
366
{
367
    MimicContext *ctx = avctx->priv_data;
368
    int i;
369

    
370
    av_free(ctx->swap_buf);
371
    for(i = 0; i < 16; i++)
372
        if(ctx->buf_ptrs[i].data[0])
373
            avctx->release_buffer(avctx, &ctx->buf_ptrs[i]);
374
    free_vlc(&ctx->vlc);
375

    
376
    return 0;
377
}
378

    
379
AVCodec mimic_decoder = {
380
    "mimic",
381
    CODEC_TYPE_VIDEO,
382
    CODEC_ID_MIMIC,
383
    sizeof(MimicContext),
384
    mimic_decode_init,
385
    NULL,
386
    mimic_decode_end,
387
    mimic_decode_frame,
388
    CODEC_CAP_DR1,
389
};