~ubuntu-branches/ubuntu/jaunty/xvidcap/jaunty-proposed

« back to all changes in this revision

Viewing changes to ffmpeg/libavcodec/mimic.c

  • Committer: Bazaar Package Importer
  • Author(s): Lionel Le Folgoc, Andrew Starr-Bochicchio, Lionel Le Folgoc
  • Date: 2008-12-26 00:10:06 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20081226001006-2040ls9680bd1blt
Tags: 1.1.7-0.2ubuntu1
[ Andrew Starr-Bochicchio ]
* Merge from debian-multimedia (LP: #298547), Ubuntu Changes:
 - For ffmpeg-related build-deps, fix versionized dependencies
   as the ubuntu versioning is different than debian-multimedia's.

[ Lionel Le Folgoc ]
* LP: #311412 is fixed since the 1.1.7~rc1-0.1 revision.
* debian/patches/03_ffmpeg.diff: updated to fix FTBFS due to libswscale API
  change (cherry-pick from Gentoo #234383).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
    .long_name = "Mimic",
 
390
};