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