summaryrefslogtreecommitdiff
path: root/libavcodec/mimic.c (plain)
blob: 0cc30ab0ede449ec8cea66cc86d939721b9c16e5
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
38typedef 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(16, 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
67static 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
92static 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
106static 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
117static 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 if (!avctx->internal->is_copy)
132 ff_free_vlc(&ctx->vlc);
133
134 return 0;
135}
136
137static 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#if HAVE_THREADS
170static int mimic_decode_update_thread_context(AVCodecContext *avctx, const AVCodecContext *avctx_from)
171{
172 MimicContext *dst = avctx->priv_data, *src = avctx_from->priv_data;
173 int i, ret;
174
175 if (avctx == avctx_from)
176 return 0;
177
178 dst->cur_index = src->next_cur_index;
179 dst->prev_index = src->next_prev_index;
180
181 for (i = 0; i < FF_ARRAY_ELEMS(dst->frames); i++) {
182 ff_thread_release_buffer(avctx, &dst->frames[i]);
183 if (i != src->next_cur_index && src->frames[i].f->data[0]) {
184 ret = ff_thread_ref_frame(&dst->frames[i], &src->frames[i]);
185 if (ret < 0)
186 return ret;
187 }
188 }
189
190 return 0;
191}
192#endif
193
194static 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
231static 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 /* FFmpeg'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
275static 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->frames[ctx->cur_index ].f->linesize[plane];
285 const uint8_t *src = ctx->frames[ctx->prev_index].f->data[plane];
286 uint8_t *dst = ctx->frames[ctx->cur_index ].f->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->frames[index].f->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->frames[ctx->prev_index].f->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 revert the
343 * way Mimic encodes frames.
344 */
345static void flip_swap_frame(AVFrame *f)
346{
347 int i;
348 uint8_t *data_1 = f->data[1];
349 f->data[0] = f->data[0] + ( f->height - 1) * f->linesize[0];
350 f->data[1] = f->data[2] + ((f->height >> 1) - 1) * f->linesize[2];
351 f->data[2] = data_1 + ((f->height >> 1) - 1) * f->linesize[1];
352 for (i = 0; i < 3; i++)
353 f->linesize[i] *= -1;
354}
355
356static int mimic_decode_frame(AVCodecContext *avctx, void *data,
357 int *got_frame, AVPacket *avpkt)
358{
359 const uint8_t *buf = avpkt->data;
360 int buf_size = avpkt->size;
361 int swap_buf_size = buf_size - MIMIC_HEADER_SIZE;
362 MimicContext *ctx = avctx->priv_data;
363 GetByteContext gb;
364 int is_pframe;
365 int width, height;
366 int quality, num_coeffs;
367 int res;
368
369 if (buf_size <= MIMIC_HEADER_SIZE) {
370 av_log(avctx, AV_LOG_ERROR, "insufficient data\n");
371 return AVERROR_INVALIDDATA;
372 }
373
374 bytestream2_init(&gb, buf, MIMIC_HEADER_SIZE);
375 bytestream2_skip(&gb, 2); /* some constant (always 256) */
376 quality = bytestream2_get_le16u(&gb);
377 width = bytestream2_get_le16u(&gb);
378 height = bytestream2_get_le16u(&gb);
379 bytestream2_skip(&gb, 4); /* some constant */
380 is_pframe = bytestream2_get_le32u(&gb);
381 num_coeffs = bytestream2_get_byteu(&gb);
382 bytestream2_skip(&gb, 3); /* some constant */
383
384 if (!ctx->avctx) {
385 int i;
386
387 if (!(width == 160 && height == 120) &&
388 !(width == 320 && height == 240)) {
389 av_log(avctx, AV_LOG_ERROR, "invalid width/height!\n");
390 return AVERROR_INVALIDDATA;
391 }
392
393 ctx->avctx = avctx;
394 avctx->width = width;
395 avctx->height = height;
396 avctx->pix_fmt = AV_PIX_FMT_YUV420P;
397 for (i = 0; i < 3; i++) {
398 ctx->num_vblocks[i] = AV_CEIL_RSHIFT(height, 3 + !!i);
399 ctx->num_hblocks[i] = width >> (3 + !!i);
400 }
401 } else if (width != ctx->avctx->width || height != ctx->avctx->height) {
402 avpriv_request_sample(avctx, "Resolution changing");
403 return AVERROR_PATCHWELCOME;
404 }
405
406 if (is_pframe && !ctx->frames[ctx->prev_index].f->data[0]) {
407 av_log(avctx, AV_LOG_ERROR, "decoding must start with keyframe\n");
408 return AVERROR_INVALIDDATA;
409 }
410
411 ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);
412 ctx->frames[ctx->cur_index].f->pict_type = is_pframe ? AV_PICTURE_TYPE_P :
413 AV_PICTURE_TYPE_I;
414 if ((res = ff_thread_get_buffer(avctx, &ctx->frames[ctx->cur_index],
415 AV_GET_BUFFER_FLAG_REF)) < 0)
416 return res;
417
418 ctx->next_prev_index = ctx->cur_index;
419 ctx->next_cur_index = (ctx->cur_index - 1) & 15;
420
421 ff_thread_finish_setup(avctx);
422
423 av_fast_padded_malloc(&ctx->swap_buf, &ctx->swap_buf_size, swap_buf_size);
424 if (!ctx->swap_buf)
425 return AVERROR(ENOMEM);
426
427 ctx->bbdsp.bswap_buf(ctx->swap_buf,
428 (const uint32_t *) (buf + MIMIC_HEADER_SIZE),
429 swap_buf_size >> 2);
430 init_get_bits(&ctx->gb, ctx->swap_buf, swap_buf_size << 3);
431
432 res = decode(ctx, quality, num_coeffs, !is_pframe);
433 ff_thread_report_progress(&ctx->frames[ctx->cur_index], INT_MAX, 0);
434 if (res < 0) {
435 if (!(avctx->active_thread_type & FF_THREAD_FRAME))
436 ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);
437 return res;
438 }
439
440 if ((res = av_frame_ref(data, ctx->frames[ctx->cur_index].f)) < 0)
441 return res;
442 *got_frame = 1;
443
444 flip_swap_frame(data);
445
446 ctx->prev_index = ctx->next_prev_index;
447 ctx->cur_index = ctx->next_cur_index;
448
449 return buf_size;
450}
451
452#if HAVE_THREADS
453static av_cold int mimic_init_thread_copy(AVCodecContext *avctx)
454{
455 MimicContext *ctx = avctx->priv_data;
456 int i;
457
458 for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) {
459 ctx->frames[i].f = av_frame_alloc();
460 if (!ctx->frames[i].f) {
461 mimic_decode_end(avctx);
462 return AVERROR(ENOMEM);
463 }
464 }
465
466 return 0;
467}
468#endif
469
470AVCodec ff_mimic_decoder = {
471 .name = "mimic",
472 .long_name = NULL_IF_CONFIG_SMALL("Mimic"),
473 .type = AVMEDIA_TYPE_VIDEO,
474 .id = AV_CODEC_ID_MIMIC,
475 .priv_data_size = sizeof(MimicContext),
476 .init = mimic_decode_init,
477 .close = mimic_decode_end,
478 .decode = mimic_decode_frame,
479 .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
480 .update_thread_context = ONLY_IF_THREADS_ENABLED(mimic_decode_update_thread_context),
481 .init_thread_copy = ONLY_IF_THREADS_ENABLED(mimic_init_thread_copy),
482};
483