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