]> git.sesse.net Git - ffmpeg/blob - libavcodec/mimic.c
Merge remote-tracking branch 'qatar/master'
[ffmpeg] / libavcodec / mimic.c
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 = 3;
355     ctx->buf_ptrs[ctx->cur_index].pict_type = is_pframe ? AV_PICTURE_TYPE_P:AV_PICTURE_TYPE_I;
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     .name           = "mimic",
420     .type           = AVMEDIA_TYPE_VIDEO,
421     .id             = CODEC_ID_MIMIC,
422     .priv_data_size = sizeof(MimicContext),
423     .init           = mimic_decode_init,
424     .close          = mimic_decode_end,
425     .decode         = mimic_decode_frame,
426     .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
427     .long_name = NULL_IF_CONFIG_SMALL("Mimic"),
428     .update_thread_context = ONLY_IF_THREADS_ENABLED(mimic_decode_update_thread_context)
429 };