Statistics
| Branch: | Revision:

ffmpeg / libavcodec / mimic.c @ 72415b2a

History | View | Annotate | Download (13.7 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 "get_bits.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
    void           *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, FF_ARRAY_ELEMS(huffbits),
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
static const 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
    ctx->dsp.clear_block(block);
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, AVPacket *avpkt)
278
{
279
    const uint8_t *buf = avpkt->data;
280
    int buf_size = avpkt->size;
281
    MimicContext *ctx = avctx->priv_data;
282
    int is_pframe;
283
    int width, height;
284
    int quality, num_coeffs;
285
    int swap_buf_size = buf_size - MIMIC_HEADER_SIZE;
286

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

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

    
301
    if(!ctx->avctx) {
302
        int i;
303

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

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

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

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

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

    
337
    av_fast_malloc(&ctx->swap_buf, &ctx->swap_buf_size,
338
                                 swap_buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
339
    if(!ctx->swap_buf)
340
        return AVERROR(ENOMEM);
341

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

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

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

    
356
    ctx->prev_index = ctx->cur_index;
357
    ctx->cur_index--;
358
    ctx->cur_index &= 15;
359

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

    
364
    return buf_size;
365
}
366

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

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

    
378
    return 0;
379
}
380

    
381
AVCodec mimic_decoder = {
382
    "mimic",
383
    AVMEDIA_TYPE_VIDEO,
384
    CODEC_ID_MIMIC,
385
    sizeof(MimicContext),
386
    mimic_decode_init,
387
    NULL,
388
    mimic_decode_end,
389
    mimic_decode_frame,
390
    CODEC_CAP_DR1,
391
    .long_name = NULL_IF_CONFIG_SMALL("Mimic"),
392
};