asfdec: also read Metadata Library Object
[FFMpeg-mirror/mplayer-patches.git] / libavcodec / mimic.c
blob8ab1c9e985c506a53c9bbc7ee99f77dd415e6ea4
1 /*
2 * Copyright (C) 2005 Ole André Vadla Ravnås <oleavr@gmail.com>
3 * Copyright (C) 2008 Ramiro Polla
5 * This file is part of Libav.
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.
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.
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
22 #include <stdlib.h>
23 #include <string.h>
24 #include <stdint.h>
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"
33 #define MIMIC_HEADER_SIZE 20
35 typedef struct {
36 AVCodecContext *avctx;
38 int num_vblocks[3];
39 int num_hblocks[3];
41 void *swap_buf;
42 int swap_buf_size;
44 int cur_index;
45 int prev_index;
47 AVFrame buf_ptrs [16];
48 AVPicture flipped_ptrs[16];
50 DECLARE_ALIGNED(16, int16_t, dct_block)[64];
52 GetBitContext gb;
53 ScanTable scantable;
54 DSPContext dsp;
55 VLC vlc;
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;
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,
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,
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,
112 static av_cold int mimic_decode_init(AVCodecContext *avctx)
114 MimicContext *ctx = avctx->priv_data;
115 int ret;
117 ctx->prev_index = 0;
118 ctx->cur_index = 15;
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;
125 ff_dsputil_init(&ctx->dsp, avctx);
126 ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable, col_zag);
128 return 0;
131 static int mimic_decode_update_thread_context(AVCodecContext *avctx, const AVCodecContext *avctx_from)
133 MimicContext *dst = avctx->priv_data, *src = avctx_from->priv_data;
135 if (avctx == avctx_from)
136 return 0;
138 dst->cur_index = src->next_cur_index;
139 dst->prev_index = src->next_prev_index;
141 memcpy(dst->buf_ptrs, src->buf_ptrs, sizeof(src->buf_ptrs));
142 memcpy(dst->flipped_ptrs, src->flipped_ptrs, sizeof(src->flipped_ptrs));
144 memset(&dst->buf_ptrs[dst->cur_index], 0, sizeof(AVFrame));
146 return 0;
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, },
186 static int vlc_decode_block(MimicContext *ctx, int num_coeffs, int qscale)
188 int16_t *block = ctx->dct_block;
189 unsigned int pos;
191 ctx->dsp.clear_block(block);
193 block[0] = get_bits(&ctx->gb, 8) << 3;
195 for (pos = 1; pos < num_coeffs; pos++) {
196 uint32_t vlc, num_bits;
197 int value;
198 int coeff;
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;
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
210 if (pos >= 64)
211 return AVERROR_INVALIDDATA;
213 value = get_bits(&ctx->gb, num_bits);
215 /* Libav's IDCT behaves somewhat different from the original code, so
216 * a factor of 4 was added to the input */
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;
224 block[ctx->scantable.permutated[pos]] = coeff;
227 return 0;
230 static int decode(MimicContext *ctx, int quality, int num_coeffs,
231 int is_iframe)
233 int ret, y, x, plane, cur_row = 0;
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];
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;
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];
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");
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);
282 src += 8;
283 dst += 8;
285 src += (stride - ctx->num_hblocks[plane]) << 3;
286 dst += (stride - ctx->num_hblocks[plane]) << 3;
288 ff_thread_report_progress(&ctx->buf_ptrs[ctx->cur_index],
289 cur_row++, 0);
293 return 0;
297 * Flip the buffer upside-down and put it in the YVU order to match the
298 * way Mimic encodes frames.
300 static void prepare_avpic(MimicContext *ctx, AVPicture *dst, AVFrame *src)
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];
310 static int mimic_decode_frame(AVCodecContext *avctx, void *data,
311 int *got_frame, AVPacket *avpkt)
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;
323 if (buf_size <= MIMIC_HEADER_SIZE) {
324 av_log(avctx, AV_LOG_ERROR, "insufficient data\n");
325 return AVERROR_INVALIDDATA;
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 */
338 if (!ctx->avctx) {
339 int i;
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;
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);
355 } else if (width != ctx->avctx->width || height != ctx->avctx->height) {
356 av_log_missing_feature(avctx, "resolution changing", 1);
357 return AVERROR_PATCHWELCOME;
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;
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;
373 ctx->next_prev_index = ctx->cur_index;
374 ctx->next_cur_index = (ctx->cur_index - 1) & 15;
376 prepare_avpic(ctx, &ctx->flipped_ptrs[ctx->cur_index],
377 &ctx->buf_ptrs[ctx->cur_index]);
379 ff_thread_finish_setup(avctx);
381 av_fast_padded_malloc(&ctx->swap_buf, &ctx->swap_buf_size, swap_buf_size);
382 if (!ctx->swap_buf)
383 return AVERROR(ENOMEM);
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);
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;
399 *(AVFrame*)data = ctx->buf_ptrs[ctx->cur_index];
400 *got_frame = 1;
402 ctx->prev_index = ctx->next_prev_index;
403 ctx->cur_index = ctx->next_cur_index;
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]);
409 return buf_size;
412 static av_cold int mimic_decode_end(AVCodecContext *avctx)
414 MimicContext *ctx = avctx->priv_data;
415 int i;
417 av_free(ctx->swap_buf);
419 if (avctx->internal->is_copy)
420 return 0;
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);
427 return 0;
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)