]> rtime.felk.cvut.cz Git - frescor/ffmpeg.git/blob - libavcodec/mimic.c
Started attempt to fix seek handling - still not completed
[frescor/ffmpeg.git] / libavcodec / mimic.c
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     CODEC_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 };