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