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