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