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