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