]> git.sesse.net Git - ffmpeg/blob - libavcodec/mimic.c
avcodec/vc1: Simplify code setting and using extend_x/y
[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 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     memcpy(dst->flipped_ptrs, src->flipped_ptrs, sizeof(src->flipped_ptrs));
182
183     for (i = 0; i < FF_ARRAY_ELEMS(dst->frames); i++) {
184         ff_thread_release_buffer(avctx, &dst->frames[i]);
185         if (i != src->next_cur_index && src->frames[i].f->data[0]) {
186             ret = ff_thread_ref_frame(&dst->frames[i], &src->frames[i]);
187             if (ret < 0)
188                 return ret;
189         }
190     }
191
192     return 0;
193 }
194
195 static const int8_t vlcdec_lookup[9][64] = {
196     {    0, },
197     {   -1,   1, },
198     {   -3,   3,   -2,   2, },
199     {   -7,   7,   -6,   6,   -5,   5,   -4,   4, },
200     {  -15,  15,  -14,  14,  -13,  13,  -12,  12,
201        -11,  11,  -10,  10,   -9,   9,   -8,   8, },
202     {  -31,  31,  -30,  30,  -29,  29,  -28,  28,
203        -27,  27,  -26,  26,  -25,  25,  -24,  24,
204        -23,  23,  -22,  22,  -21,  21,  -20,  20,
205        -19,  19,  -18,  18,  -17,  17,  -16,  16, },
206     {  -63,  63,  -62,  62,  -61,  61,  -60,  60,
207        -59,  59,  -58,  58,  -57,  57,  -56,  56,
208        -55,  55,  -54,  54,  -53,  53,  -52,  52,
209        -51,  51,  -50,  50,  -49,  49,  -48,  48,
210        -47,  47,  -46,  46,  -45,  45,  -44,  44,
211        -43,  43,  -42,  42,  -41,  41,  -40,  40,
212        -39,  39,  -38,  38,  -37,  37,  -36,  36,
213        -35,  35,  -34,  34,  -33,  33,  -32,  32, },
214     { -127, 127, -126, 126, -125, 125, -124, 124,
215       -123, 123, -122, 122, -121, 121, -120, 120,
216       -119, 119, -118, 118, -117, 117, -116, 116,
217       -115, 115, -114, 114, -113, 113, -112, 112,
218       -111, 111, -110, 110, -109, 109, -108, 108,
219       -107, 107, -106, 106, -105, 105, -104, 104,
220       -103, 103, -102, 102, -101, 101, -100, 100,
221        -99,  99,  -98,  98,  -97,  97,  -96,  96, },
222     {  -95,  95,  -94,  94,  -93,  93,  -92,  92,
223        -91,  91,  -90,  90,  -89,  89,  -88,  88,
224        -87,  87,  -86,  86,  -85,  85,  -84,  84,
225        -83,  83,  -82,  82,  -81,  81,  -80,  80,
226        -79,  79,  -78,  78,  -77,  77,  -76,  76,
227        -75,  75,  -74,  74,  -73,  73,  -72,  72,
228        -71,  71,  -70,  70,  -69,  69,  -68,  68,
229        -67,  67,  -66,  66,  -65,  65,  -64,  64, },
230 };
231
232 static int vlc_decode_block(MimicContext *ctx, int num_coeffs, int qscale)
233 {
234     int16_t *block = ctx->dct_block;
235     unsigned int pos;
236
237     ctx->bdsp.clear_block(block);
238
239     block[0] = get_bits(&ctx->gb, 8) << 3;
240
241     for (pos = 1; pos < num_coeffs; pos++) {
242         uint32_t vlc, num_bits;
243         int value;
244         int coeff;
245
246         vlc = get_vlc2(&ctx->gb, ctx->vlc.table, ctx->vlc.bits, 3);
247         if (!vlc) /* end-of-block code */
248             return 0;
249         if (vlc == -1)
250             return AVERROR_INVALIDDATA;
251
252         /* pos_add and num_bits are coded in the vlc code */
253         pos     += vlc & 15; // pos_add
254         num_bits = vlc >> 4; // num_bits
255
256         if (pos >= 64)
257             return AVERROR_INVALIDDATA;
258
259         value = get_bits(&ctx->gb, num_bits);
260
261         /* FFmpeg's IDCT behaves somewhat different from the original code, so
262          * a factor of 4 was added to the input */
263
264         coeff = vlcdec_lookup[num_bits][value];
265         if (pos < 3)
266             coeff <<= 4;
267         else /* TODO Use >> 10 instead of / 1001 */
268             coeff = (coeff * qscale) / 1001;
269
270         block[ctx->scantable.permutated[pos]] = coeff;
271     }
272
273     return 0;
274 }
275
276 static int decode(MimicContext *ctx, int quality, int num_coeffs,
277                   int is_iframe)
278 {
279     int ret, y, x, plane, cur_row = 0;
280
281     for (plane = 0; plane < 3; plane++) {
282         const int is_chroma = !!plane;
283         const int qscale    = av_clip(10000 - quality, is_chroma ? 1000 : 2000,
284                                       10000) << 2;
285         const int stride    = ctx->flipped_ptrs[ctx->cur_index ].linesize[plane];
286         const uint8_t *src  = ctx->flipped_ptrs[ctx->prev_index].data[plane];
287         uint8_t       *dst  = ctx->flipped_ptrs[ctx->cur_index ].data[plane];
288
289         for (y = 0; y < ctx->num_vblocks[plane]; y++) {
290             for (x = 0; x < ctx->num_hblocks[plane]; x++) {
291                 /* Check for a change condition in the current block.
292                  * - iframes always change.
293                  * - Luma plane changes on get_bits1 == 0
294                  * - Chroma planes change on get_bits1 == 1 */
295                 if (is_iframe || get_bits1(&ctx->gb) == is_chroma) {
296                     /* Luma planes may use a backreference from the 15 last
297                      * frames preceding the previous. (get_bits1 == 1)
298                      * Chroma planes don't use backreferences. */
299                     if (is_chroma || is_iframe || !get_bits1(&ctx->gb)) {
300                         if ((ret = vlc_decode_block(ctx, num_coeffs,
301                                                     qscale)) < 0) {
302                             av_log(ctx->avctx, AV_LOG_ERROR, "Error decoding "
303                                    "block.\n");
304                             return ret;
305                         }
306                         ctx->idsp.idct_put(dst, stride, ctx->dct_block);
307                     } else {
308                         unsigned int backref = get_bits(&ctx->gb, 4);
309                         int index            = (ctx->cur_index + backref) & 15;
310                         uint8_t *p           = ctx->flipped_ptrs[index].data[0];
311
312                         if (index != ctx->cur_index && p) {
313                             ff_thread_await_progress(&ctx->frames[index],
314                                                      cur_row, 0);
315                             p += src -
316                                  ctx->flipped_ptrs[ctx->prev_index].data[plane];
317                             ctx->hdsp.put_pixels_tab[1][0](dst, p, stride, 8);
318                         } else {
319                             av_log(ctx->avctx, AV_LOG_ERROR,
320                                      "No such backreference! Buggy sample.\n");
321                         }
322                     }
323                 } else {
324                     ff_thread_await_progress(&ctx->frames[ctx->prev_index],
325                                              cur_row, 0);
326                     ctx->hdsp.put_pixels_tab[1][0](dst, src, stride, 8);
327                 }
328                 src += 8;
329                 dst += 8;
330             }
331             src += (stride - ctx->num_hblocks[plane]) << 3;
332             dst += (stride - ctx->num_hblocks[plane]) << 3;
333
334             ff_thread_report_progress(&ctx->frames[ctx->cur_index],
335                                       cur_row++, 0);
336         }
337     }
338
339     return 0;
340 }
341
342 /**
343  * Flip the buffer upside-down and put it in the YVU order to match the
344  * way Mimic encodes frames.
345  */
346 static void prepare_avpic(MimicContext *ctx, AVPicture *dst, AVFrame *src)
347 {
348     int i;
349     dst->data[0] = src->data[0] + ( ctx->avctx->height       - 1) * src->linesize[0];
350     dst->data[1] = src->data[2] + ((ctx->avctx->height >> 1) - 1) * src->linesize[2];
351     dst->data[2] = src->data[1] + ((ctx->avctx->height >> 1) - 1) * src->linesize[1];
352     for (i = 0; i < 3; i++)
353         dst->linesize[i] = -src->linesize[i];
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         ctx->avctx     = avctx;
394         avctx->width   = width;
395         avctx->height  = height;
396         avctx->pix_fmt = AV_PIX_FMT_YUV420P;
397         for (i = 0; i < 3; i++) {
398             ctx->num_vblocks[i] = FF_CEIL_RSHIFT(height,   3 + !!i);
399             ctx->num_hblocks[i] =                width >> (3 + !!i);
400         }
401     } else if (width != ctx->avctx->width || height != ctx->avctx->height) {
402         avpriv_request_sample(avctx, "Resolution changing");
403         return AVERROR_PATCHWELCOME;
404     }
405
406     if (is_pframe && !ctx->frames[ctx->prev_index].f->data[0]) {
407         av_log(avctx, AV_LOG_ERROR, "decoding must start with keyframe\n");
408         return AVERROR_INVALIDDATA;
409     }
410
411     ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);
412     ctx->frames[ctx->cur_index].f->pict_type = is_pframe ? AV_PICTURE_TYPE_P :
413                                                            AV_PICTURE_TYPE_I;
414     if ((res = ff_thread_get_buffer(avctx, &ctx->frames[ctx->cur_index],
415                                     AV_GET_BUFFER_FLAG_REF)) < 0)
416         return res;
417
418     ctx->next_prev_index = ctx->cur_index;
419     ctx->next_cur_index  = (ctx->cur_index - 1) & 15;
420
421     prepare_avpic(ctx, &ctx->flipped_ptrs[ctx->cur_index],
422                   ctx->frames[ctx->cur_index].f);
423
424     ff_thread_finish_setup(avctx);
425
426     av_fast_padded_malloc(&ctx->swap_buf, &ctx->swap_buf_size, swap_buf_size);
427     if (!ctx->swap_buf)
428         return AVERROR(ENOMEM);
429
430     ctx->bbdsp.bswap_buf(ctx->swap_buf,
431                          (const uint32_t *) (buf + MIMIC_HEADER_SIZE),
432                          swap_buf_size >> 2);
433     init_get_bits(&ctx->gb, ctx->swap_buf, swap_buf_size << 3);
434
435     res = decode(ctx, quality, num_coeffs, !is_pframe);
436     ff_thread_report_progress(&ctx->frames[ctx->cur_index], INT_MAX, 0);
437     if (res < 0) {
438         if (!(avctx->active_thread_type & FF_THREAD_FRAME)) {
439             ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);
440             return res;
441         }
442     }
443
444     if ((res = av_frame_ref(data, ctx->frames[ctx->cur_index].f)) < 0)
445         return res;
446     *got_frame      = 1;
447
448     ctx->prev_index = ctx->next_prev_index;
449     ctx->cur_index  = ctx->next_cur_index;
450
451     /* Only release frames that aren't used for backreferences anymore */
452     ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);
453
454     return buf_size;
455 }
456
457 static av_cold int mimic_init_thread_copy(AVCodecContext *avctx)
458 {
459     MimicContext *ctx = avctx->priv_data;
460     int i;
461
462     for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) {
463         ctx->frames[i].f = av_frame_alloc();
464         if (!ctx->frames[i].f) {
465             mimic_decode_end(avctx);
466             return AVERROR(ENOMEM);
467         }
468     }
469
470     return 0;
471 }
472
473 AVCodec ff_mimic_decoder = {
474     .name                  = "mimic",
475     .long_name             = NULL_IF_CONFIG_SMALL("Mimic"),
476     .type                  = AVMEDIA_TYPE_VIDEO,
477     .id                    = AV_CODEC_ID_MIMIC,
478     .priv_data_size        = sizeof(MimicContext),
479     .init                  = mimic_decode_init,
480     .close                 = mimic_decode_end,
481     .decode                = mimic_decode_frame,
482     .capabilities          = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
483     .update_thread_context = ONLY_IF_THREADS_ENABLED(mimic_decode_update_thread_context),
484     .init_thread_copy      = ONLY_IF_THREADS_ENABLED(mimic_init_thread_copy),
485 };