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