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