]> git.sesse.net Git - ffmpeg/blob - libavcodec/mimic.c
Drop DCTELEM typedef
[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 Libav.
6  *
7  * Libav 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  * Libav 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 Libav; 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 "internal.h"
28 #include "get_bits.h"
29 #include "bytestream.h"
30 #include "dsputil.h"
31 #include "thread.h"
32
33 #define MIMIC_HEADER_SIZE   20
34
35 typedef struct {
36     AVCodecContext *avctx;
37
38     int             num_vblocks[3];
39     int             num_hblocks[3];
40
41     void           *swap_buf;
42     int             swap_buf_size;
43
44     int             cur_index;
45     int             prev_index;
46
47     AVFrame         buf_ptrs    [16];
48     AVPicture       flipped_ptrs[16];
49
50     DECLARE_ALIGNED(16, int16_t, dct_block)[64];
51
52     GetBitContext   gb;
53     ScanTable       scantable;
54     DSPContext      dsp;
55     VLC             vlc;
56
57     /* Kept in the context so multithreading can have a constant to read from */
58     int             next_cur_index;
59     int             next_prev_index;
60 } MimicContext;
61
62 static const uint32_t huffcodes[] = {
63     0x0000000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
64     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
65     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000b,
66     0x0000001b, 0x00000038, 0x00000078, 0x00000079, 0x0000007a, 0x000000f9,
67     0x000000fa, 0x000003fb, 0x000007f8, 0x000007f9, 0x000007fa, 0x000007fb,
68     0x00000ff8, 0x00000ff9, 0x00000001, 0x00000039, 0x0000007b, 0x000000fb,
69     0x000001f8, 0x000001f9, 0x00000ffa, 0x00000ffb, 0x00001ff8, 0x00001ff9,
70     0x00001ffa, 0x00001ffb, 0x00003ff8, 0x00003ff9, 0x00003ffa, 0x00000000,
71     0x00000004, 0x0000003a, 0x000001fa, 0x00003ffb, 0x00007ff8, 0x00007ff9,
72     0x00007ffa, 0x00007ffb, 0x0000fff8, 0x0000fff9, 0x0000fffa, 0x0000fffb,
73     0x0001fff8, 0x0001fff9, 0x0001fffa, 0x00000000, 0x0000000c, 0x000000f8,
74     0x000001fb, 0x0001fffb, 0x0003fff8, 0x0003fff9, 0x0003fffa, 0x0003fffb,
75     0x0007fff8, 0x0007fff9, 0x0007fffa, 0x0007fffb, 0x000ffff8, 0x000ffff9,
76     0x000ffffa, 0x00000000, 0x0000001a, 0x000003f8, 0x000ffffb, 0x001ffff8,
77     0x001ffff9, 0x001ffffa, 0x001ffffb, 0x003ffff8, 0x003ffff9, 0x003ffffa,
78     0x003ffffb, 0x007ffff8, 0x007ffff9, 0x007ffffa, 0x007ffffb, 0x00000000,
79     0x0000003b, 0x000003f9, 0x00fffff8, 0x00fffff9, 0x00fffffa, 0x00fffffb,
80     0x01fffff8, 0x01fffff9, 0x01fffffa, 0x01fffffb, 0x03fffff8, 0x03fffff9,
81     0x03fffffa, 0x03fffffb, 0x07fffff8, 0x00000000, 0x000003fa, 0x07fffff9,
82     0x07fffffa, 0x07fffffb, 0x0ffffff8, 0x0ffffff9, 0x0ffffffa, 0x0ffffffb,
83     0x1ffffff8, 0x1ffffff9, 0x1ffffffa, 0x1ffffffb, 0x3ffffff8, 0x3ffffff9,
84     0x3ffffffa,
85 };
86
87 static const uint8_t huffbits[] = {
88      4,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
89      0,  0,  0,  0,  2,  4,  5,  6,  7,  7,  7,  8,
90      8, 10, 11, 11, 11, 11, 12, 12,  2,  6,  7,  8,
91      9,  9, 12, 12, 13, 13, 13, 13, 14, 14, 14,  0,
92      3,  6,  9, 14, 15, 15, 15, 15, 16, 16, 16, 16,
93     17, 17, 17,  0,  4,  8,  9, 17, 18, 18, 18, 18,
94     19, 19, 19, 19, 20, 20, 20,  0,  5, 10, 20, 21,
95     21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23,  0,
96      6, 10, 24, 24, 24, 24, 25, 25, 25, 25, 26, 26,
97     26, 26, 27,  0, 10, 27, 27, 27, 28, 28, 28, 28,
98     29, 29, 29, 29, 30, 30, 30,
99 };
100
101 static const uint8_t col_zag[64] = {
102      0,  8,  1,  2,  9, 16, 24, 17,
103     10,  3,  4, 11, 18, 25, 32, 40,
104     33, 26, 19, 12,  5,  6, 13, 20,
105     27, 34, 41, 48, 56, 49, 42, 35,
106     28, 21, 14,  7, 15, 22, 29, 36,
107     43, 50, 57, 58, 51, 44, 37, 30,
108     23, 31, 38, 45, 52, 59, 39, 46,
109     53, 60, 61, 54, 47, 55, 62, 63,
110 };
111
112 static av_cold int mimic_decode_init(AVCodecContext *avctx)
113 {
114     MimicContext *ctx = avctx->priv_data;
115
116     ctx->prev_index = 0;
117     ctx->cur_index = 15;
118
119     if(init_vlc(&ctx->vlc, 11, FF_ARRAY_ELEMS(huffbits),
120                  huffbits, 1, 1, huffcodes, 4, 4, 0)) {
121         av_log(avctx, AV_LOG_ERROR, "error initializing vlc table\n");
122         return -1;
123     }
124     ff_dsputil_init(&ctx->dsp, avctx);
125     ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable, col_zag);
126
127     return 0;
128 }
129
130 static int mimic_decode_update_thread_context(AVCodecContext *avctx, const AVCodecContext *avctx_from)
131 {
132     MimicContext *dst = avctx->priv_data, *src = avctx_from->priv_data;
133
134     if (avctx == avctx_from) return 0;
135
136     dst->cur_index  = src->next_cur_index;
137     dst->prev_index = src->next_prev_index;
138
139     memcpy(dst->buf_ptrs, src->buf_ptrs, sizeof(src->buf_ptrs));
140     memcpy(dst->flipped_ptrs, src->flipped_ptrs, sizeof(src->flipped_ptrs));
141
142     memset(&dst->buf_ptrs[dst->cur_index], 0, sizeof(AVFrame));
143
144     return 0;
145 }
146
147 static const int8_t vlcdec_lookup[9][64] = {
148     {    0, },
149     {   -1,   1, },
150     {   -3,   3,   -2,   2, },
151     {   -7,   7,   -6,   6,   -5,   5,   -4,   4, },
152     {  -15,  15,  -14,  14,  -13,  13,  -12,  12,
153        -11,  11,  -10,  10,   -9,   9,   -8,   8, },
154     {  -31,  31,  -30,  30,  -29,  29,  -28,  28,
155        -27,  27,  -26,  26,  -25,  25,  -24,  24,
156        -23,  23,  -22,  22,  -21,  21,  -20,  20,
157        -19,  19,  -18,  18,  -17,  17,  -16,  16, },
158     {  -63,  63,  -62,  62,  -61,  61,  -60,  60,
159        -59,  59,  -58,  58,  -57,  57,  -56,  56,
160        -55,  55,  -54,  54,  -53,  53,  -52,  52,
161        -51,  51,  -50,  50,  -49,  49,  -48,  48,
162        -47,  47,  -46,  46,  -45,  45,  -44,  44,
163        -43,  43,  -42,  42,  -41,  41,  -40,  40,
164        -39,  39,  -38,  38,  -37,  37,  -36,  36,
165        -35,  35,  -34,  34,  -33,  33,  -32,  32, },
166     { -127, 127, -126, 126, -125, 125, -124, 124,
167       -123, 123, -122, 122, -121, 121, -120, 120,
168       -119, 119, -118, 118, -117, 117, -116, 116,
169       -115, 115, -114, 114, -113, 113, -112, 112,
170       -111, 111, -110, 110, -109, 109, -108, 108,
171       -107, 107, -106, 106, -105, 105, -104, 104,
172       -103, 103, -102, 102, -101, 101, -100, 100,
173        -99,  99,  -98,  98,  -97,  97,  -96,  96, },
174     {  -95,  95,  -94,  94,  -93,  93,  -92,  92,
175        -91,  91,  -90,  90,  -89,  89,  -88,  88,
176        -87,  87,  -86,  86,  -85,  85,  -84,  84,
177        -83,  83,  -82,  82,  -81,  81,  -80,  80,
178        -79,  79,  -78,  78,  -77,  77,  -76,  76,
179        -75,  75,  -74,  74,  -73,  73,  -72,  72,
180        -71,  71,  -70,  70,  -69,  69,  -68,  68,
181        -67,  67,  -66,  66,  -65,  65,  -64,  64, },
182 };
183
184 static int vlc_decode_block(MimicContext *ctx, int num_coeffs, int qscale)
185 {
186     int16_t *block = ctx->dct_block;
187     unsigned int pos;
188
189     ctx->dsp.clear_block(block);
190
191     block[0] = get_bits(&ctx->gb, 8) << 3;
192
193     for(pos = 1; pos < num_coeffs; pos++) {
194         uint32_t vlc, num_bits;
195         int value;
196         int coeff;
197
198         vlc = get_vlc2(&ctx->gb, ctx->vlc.table, ctx->vlc.bits, 3);
199         if(!vlc) /* end-of-block code */
200             return 1;
201         if(vlc == -1)
202             return 0;
203
204         /* pos_add and num_bits are coded in the vlc code */
205         pos +=     vlc&15; // pos_add
206         num_bits = vlc>>4; // num_bits
207
208         if(pos >= 64)
209             return 0;
210
211         value = get_bits(&ctx->gb, num_bits);
212
213         /* Libav's IDCT behaves somewhat different from the original code, so
214          * a factor of 4 was added to the input */
215
216         coeff = vlcdec_lookup[num_bits][value];
217         if(pos<3)
218             coeff <<= 4;
219         else /* TODO Use >> 10 instead of / 1001 */
220             coeff = (coeff * qscale) / 1001;
221
222         block[ctx->scantable.permutated[pos]] = coeff;
223     }
224
225     return 1;
226 }
227
228 static int decode(MimicContext *ctx, int quality, int num_coeffs,
229                   int is_iframe)
230 {
231     int y, x, plane, cur_row = 0;
232
233     for(plane = 0; plane < 3; plane++) {
234         const int is_chroma = !!plane;
235         const int qscale = av_clip(10000-quality,is_chroma?1000:2000,10000)<<2;
236         const int stride = ctx->flipped_ptrs[ctx->cur_index].linesize[plane];
237         const uint8_t *src = ctx->flipped_ptrs[ctx->prev_index].data[plane];
238         uint8_t       *dst = ctx->flipped_ptrs[ctx->cur_index ].data[plane];
239
240         for(y = 0; y < ctx->num_vblocks[plane]; y++) {
241             for(x = 0; x < ctx->num_hblocks[plane]; x++) {
242
243                 /* Check for a change condition in the current block.
244                  * - iframes always change.
245                  * - Luma plane changes on get_bits1 == 0
246                  * - Chroma planes change on get_bits1 == 1 */
247                 if(is_iframe || get_bits1(&ctx->gb) == is_chroma) {
248
249                     /* Luma planes may use a backreference from the 15 last
250                      * frames preceding the previous. (get_bits1 == 1)
251                      * Chroma planes don't use backreferences. */
252                     if(is_chroma || is_iframe || !get_bits1(&ctx->gb)) {
253
254                         if(!vlc_decode_block(ctx, num_coeffs, qscale))
255                             return 0;
256                         ctx->dsp.idct_put(dst, stride, ctx->dct_block);
257                     } else {
258                         unsigned int backref = get_bits(&ctx->gb, 4);
259                         int index = (ctx->cur_index+backref)&15;
260                         uint8_t *p = ctx->flipped_ptrs[index].data[0];
261
262                         if (index != ctx->cur_index && p) {
263                             ff_thread_await_progress(&ctx->buf_ptrs[index], cur_row, 0);
264                             p += src -
265                                 ctx->flipped_ptrs[ctx->prev_index].data[plane];
266                             ctx->dsp.put_pixels_tab[1][0](dst, p, stride, 8);
267                         } else {
268                             av_log(ctx->avctx, AV_LOG_ERROR,
269                                      "No such backreference! Buggy sample.\n");
270                         }
271                     }
272                 } else {
273                     ff_thread_await_progress(&ctx->buf_ptrs[ctx->prev_index], cur_row, 0);
274                     ctx->dsp.put_pixels_tab[1][0](dst, src, stride, 8);
275                 }
276                 src += 8;
277                 dst += 8;
278             }
279             src += (stride - ctx->num_hblocks[plane])<<3;
280             dst += (stride - ctx->num_hblocks[plane])<<3;
281
282             ff_thread_report_progress(&ctx->buf_ptrs[ctx->cur_index], cur_row++, 0);
283         }
284     }
285
286     return 1;
287 }
288
289 /**
290  * Flip the buffer upside-down and put it in the YVU order to match the
291  * way Mimic encodes frames.
292  */
293 static void prepare_avpic(MimicContext *ctx, AVPicture *dst, AVPicture *src)
294 {
295     int i;
296     dst->data[0] = src->data[0]+( ctx->avctx->height    -1)*src->linesize[0];
297     dst->data[1] = src->data[2]+((ctx->avctx->height>>1)-1)*src->linesize[2];
298     dst->data[2] = src->data[1]+((ctx->avctx->height>>1)-1)*src->linesize[1];
299     for(i = 0; i < 3; i++)
300         dst->linesize[i] = -src->linesize[i];
301 }
302
303 static int mimic_decode_frame(AVCodecContext *avctx, void *data,
304                               int *got_frame, AVPacket *avpkt)
305 {
306     const uint8_t *buf = avpkt->data;
307     int buf_size = avpkt->size;
308     MimicContext *ctx = avctx->priv_data;
309     GetByteContext gb;
310     int is_pframe;
311     int width, height;
312     int quality, num_coeffs;
313     int swap_buf_size = buf_size - MIMIC_HEADER_SIZE;
314     int res;
315
316     if (buf_size <= MIMIC_HEADER_SIZE) {
317         av_log(avctx, AV_LOG_ERROR, "insufficient data\n");
318         return -1;
319     }
320
321     bytestream2_init(&gb, buf, MIMIC_HEADER_SIZE);
322     bytestream2_skip(&gb, 2); /* some constant (always 256) */
323     quality    = bytestream2_get_le16u(&gb);
324     width      = bytestream2_get_le16u(&gb);
325     height     = bytestream2_get_le16u(&gb);
326     bytestream2_skip(&gb, 4); /* some constant */
327     is_pframe  = bytestream2_get_le32u(&gb);
328     num_coeffs = bytestream2_get_byteu(&gb);
329     bytestream2_skip(&gb, 3); /* some constant */
330
331     if(!ctx->avctx) {
332         int i;
333
334         if(!(width == 160 && height == 120) &&
335            !(width == 320 && height == 240)) {
336             av_log(avctx, AV_LOG_ERROR, "invalid width/height!\n");
337             return -1;
338         }
339
340         ctx->avctx     = avctx;
341         avctx->width   = width;
342         avctx->height  = height;
343         avctx->pix_fmt = AV_PIX_FMT_YUV420P;
344         for(i = 0; i < 3; i++) {
345             ctx->num_vblocks[i] = -((-height) >> (3 + !!i));
346             ctx->num_hblocks[i] =     width   >> (3 + !!i) ;
347         }
348     } else if(width != ctx->avctx->width || height != ctx->avctx->height) {
349         av_log(avctx, AV_LOG_ERROR, "resolution changing is not supported\n");
350         return -1;
351     }
352
353     if(is_pframe && !ctx->buf_ptrs[ctx->prev_index].data[0]) {
354         av_log(avctx, AV_LOG_ERROR, "decoding must start with keyframe\n");
355         return -1;
356     }
357
358     ctx->buf_ptrs[ctx->cur_index].reference = 1;
359     ctx->buf_ptrs[ctx->cur_index].pict_type = is_pframe ? AV_PICTURE_TYPE_P:AV_PICTURE_TYPE_I;
360     if(ff_thread_get_buffer(avctx, &ctx->buf_ptrs[ctx->cur_index])) {
361         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
362         return -1;
363     }
364
365     ctx->next_prev_index = ctx->cur_index;
366     ctx->next_cur_index  = (ctx->cur_index - 1) & 15;
367
368     prepare_avpic(ctx, &ctx->flipped_ptrs[ctx->cur_index],
369                   (AVPicture*) &ctx->buf_ptrs[ctx->cur_index]);
370
371     ff_thread_finish_setup(avctx);
372
373     av_fast_padded_malloc(&ctx->swap_buf, &ctx->swap_buf_size, swap_buf_size);
374     if(!ctx->swap_buf)
375         return AVERROR(ENOMEM);
376
377     ctx->dsp.bswap_buf(ctx->swap_buf,
378                         (const uint32_t*) (buf + MIMIC_HEADER_SIZE),
379                         swap_buf_size>>2);
380     init_get_bits(&ctx->gb, ctx->swap_buf, swap_buf_size << 3);
381
382     res = decode(ctx, quality, num_coeffs, !is_pframe);
383     ff_thread_report_progress(&ctx->buf_ptrs[ctx->cur_index], INT_MAX, 0);
384     if (!res) {
385         if (!(avctx->active_thread_type & FF_THREAD_FRAME)) {
386             ff_thread_release_buffer(avctx, &ctx->buf_ptrs[ctx->cur_index]);
387             return -1;
388         }
389     }
390
391     *(AVFrame*)data = ctx->buf_ptrs[ctx->cur_index];
392     *got_frame      = 1;
393
394     ctx->prev_index = ctx->next_prev_index;
395     ctx->cur_index  = ctx->next_cur_index;
396
397     /* Only release frames that aren't used for backreferences anymore */
398     if(ctx->buf_ptrs[ctx->cur_index].data[0])
399         ff_thread_release_buffer(avctx, &ctx->buf_ptrs[ctx->cur_index]);
400
401     return buf_size;
402 }
403
404 static av_cold int mimic_decode_end(AVCodecContext *avctx)
405 {
406     MimicContext *ctx = avctx->priv_data;
407     int i;
408
409     av_free(ctx->swap_buf);
410
411     if (avctx->internal->is_copy)
412         return 0;
413
414     for(i = 0; i < 16; i++)
415         if(ctx->buf_ptrs[i].data[0])
416             ff_thread_release_buffer(avctx, &ctx->buf_ptrs[i]);
417     ff_free_vlc(&ctx->vlc);
418
419     return 0;
420 }
421
422 AVCodec ff_mimic_decoder = {
423     .name                  = "mimic",
424     .type                  = AVMEDIA_TYPE_VIDEO,
425     .id                    = AV_CODEC_ID_MIMIC,
426     .priv_data_size        = sizeof(MimicContext),
427     .init                  = mimic_decode_init,
428     .close                 = mimic_decode_end,
429     .decode                = mimic_decode_frame,
430     .capabilities          = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
431     .long_name             = NULL_IF_CONFIG_SMALL("Mimic"),
432     .update_thread_context = ONLY_IF_THREADS_ENABLED(mimic_decode_update_thread_context)
433 };