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