Mercurial > libavcodec.hg
annotate 4xm.c @ 1795:920e6381e1fe libavcodec
2 byte shorter userdata for mpeg4
in the past it was startcode,string,00,7F,startcode
now it is startcode,string,stratcode
both are mpeg4 compliant, as according to the standard the userdata lasts until the next 00 00 01 (startcode prefix) but some very primitive decoders which simply skip until the first 00 byte and then expect the next valid startcode might fail with the old variant, just a theory though (didnt test if quicktime can decode it now)
author | michael |
---|---|
date | Sun, 08 Feb 2004 22:52:35 +0000 |
parents | 932d306bf1dc |
children | 129236143f2e |
rev | line source |
---|---|
1293 | 1 /* |
2 * 4XM codec | |
3 * Copyright (c) 2003 Michael Niedermayer | |
4 * | |
5 * This library is free software; you can redistribute it and/or | |
6 * modify it under the terms of the GNU Lesser General Public | |
7 * License as published by the Free Software Foundation; either | |
8 * version 2 of the License, or (at your option) any later version. | |
9 * | |
10 * This library is distributed in the hope that it will be useful, | |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 * Lesser General Public License for more details. | |
14 * | |
15 * You should have received a copy of the GNU Lesser General Public | |
16 * License along with this library; if not, write to the Free Software | |
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 */ | |
19 | |
20 /** | |
21 * @file 4xm.c | |
22 * 4XM codec. | |
23 */ | |
24 | |
25 #include "avcodec.h" | |
26 #include "dsputil.h" | |
27 #include "mpegvideo.h" | |
28 | |
29 //#undef NDEBUG | |
30 //#include <assert.h> | |
31 | |
32 #define BLOCK_TYPE_VLC_BITS 5 | |
33 #define ACDC_VLC_BITS 9 | |
34 | |
35 #define CFRAME_BUFFER_COUNT 100 | |
36 | |
37 static const uint8_t block_type_tab[4][8][2]={ | |
38 { //{8,4,2}x{8,4,2} | |
39 { 0,1}, { 2,2}, { 6,3}, {14,4}, {30,5}, {31,5}, { 0,0} | |
40 },{ //{8,4}x1 | |
41 { 0,1}, { 0,0}, { 2,2}, { 6,3}, {14,4}, {15,4}, { 0,0} | |
42 },{ //1x{8,4} | |
43 { 0,1}, { 2,2}, { 0,0}, { 6,3}, {14,4}, {15,4}, { 0,0} | |
44 },{ //1x2, 2x1 | |
45 { 0,1}, { 0,0}, { 0,0}, { 2,2}, { 6,3}, {14,4}, {15,4} | |
46 } | |
47 }; | |
48 | |
49 static const uint8_t size2index[4][4]={ | |
50 {-1, 3, 1, 1}, | |
51 { 3, 0, 0, 0}, | |
52 { 2, 0, 0, 0}, | |
53 { 2, 0, 0, 0}, | |
54 }; | |
55 | |
56 static const int8_t mv[256][2]={ | |
57 { 0, 0},{ 0, -1},{ -1, 0},{ 1, 0},{ 0, 1},{ -1, -1},{ 1, -1},{ -1, 1}, | |
58 { 1, 1},{ 0, -2},{ -2, 0},{ 2, 0},{ 0, 2},{ -1, -2},{ 1, -2},{ -2, -1}, | |
59 { 2, -1},{ -2, 1},{ 2, 1},{ -1, 2},{ 1, 2},{ -2, -2},{ 2, -2},{ -2, 2}, | |
60 { 2, 2},{ 0, -3},{ -3, 0},{ 3, 0},{ 0, 3},{ -1, -3},{ 1, -3},{ -3, -1}, | |
61 { 3, -1},{ -3, 1},{ 3, 1},{ -1, 3},{ 1, 3},{ -2, -3},{ 2, -3},{ -3, -2}, | |
62 { 3, -2},{ -3, 2},{ 3, 2},{ -2, 3},{ 2, 3},{ 0, -4},{ -4, 0},{ 4, 0}, | |
63 { 0, 4},{ -1, -4},{ 1, -4},{ -4, -1},{ 4, -1},{ 4, 1},{ -1, 4},{ 1, 4}, | |
64 { -3, -3},{ -3, 3},{ 3, 3},{ -2, -4},{ -4, -2},{ 4, -2},{ -4, 2},{ -2, 4}, | |
65 { 2, 4},{ -3, -4},{ 3, -4},{ 4, -3},{ -5, 0},{ -4, 3},{ -3, 4},{ 3, 4}, | |
66 { -1, -5},{ -5, -1},{ -5, 1},{ -1, 5},{ -2, -5},{ 2, -5},{ 5, -2},{ 5, 2}, | |
67 { -4, -4},{ -4, 4},{ -3, -5},{ -5, -3},{ -5, 3},{ 3, 5},{ -6, 0},{ 0, 6}, | |
68 { -6, -1},{ -6, 1},{ 1, 6},{ 2, -6},{ -6, 2},{ 2, 6},{ -5, -4},{ 5, 4}, | |
69 { 4, 5},{ -6, -3},{ 6, 3},{ -7, 0},{ -1, -7},{ 5, -5},{ -7, 1},{ -1, 7}, | |
70 { 4, -6},{ 6, 4},{ -2, -7},{ -7, 2},{ -3, -7},{ 7, -3},{ 3, 7},{ 6, -5}, | |
71 { 0, -8},{ -1, -8},{ -7, -4},{ -8, 1},{ 4, 7},{ 2, -8},{ -2, 8},{ 6, 6}, | |
72 { -8, 3},{ 5, -7},{ -5, 7},{ 8, -4},{ 0, -9},{ -9, -1},{ 1, 9},{ 7, -6}, | |
73 { -7, 6},{ -5, -8},{ -5, 8},{ -9, 3},{ 9, -4},{ 7, -7},{ 8, -6},{ 6, 8}, | |
74 { 10, 1},{-10, 2},{ 9, -5},{ 10, -3},{ -8, -7},{-10, -4},{ 6, -9},{-11, 0}, | |
75 { 11, 1},{-11, -2},{ -2, 11},{ 7, -9},{ -7, 9},{ 10, 6},{ -4, 11},{ 8, -9}, | |
76 { 8, 9},{ 5, 11},{ 7,-10},{ 12, -3},{ 11, 6},{ -9, -9},{ 8, 10},{ 5, 12}, | |
77 {-11, 7},{ 13, 2},{ 6,-12},{ 10, 9},{-11, 8},{ -7, 12},{ 0, 14},{ 14, -2}, | |
78 { -9, 11},{ -6, 13},{-14, -4},{ -5,-14},{ 5, 14},{-15, -1},{-14, -6},{ 3,-15}, | |
79 { 11,-11},{ -7, 14},{ -5, 15},{ 8,-14},{ 15, 6},{ 3, 16},{ 7,-15},{-16, 5}, | |
80 { 0, 17},{-16, -6},{-10, 14},{-16, 7},{ 12, 13},{-16, 8},{-17, 6},{-18, 3}, | |
81 { -7, 17},{ 15, 11},{ 16, 10},{ 2,-19},{ 3,-19},{-11,-16},{-18, 8},{-19, -6}, | |
82 { 2,-20},{-17,-11},{-10,-18},{ 8, 19},{-21, -1},{-20, 7},{ -4, 21},{ 21, 5}, | |
83 { 15, 16},{ 2,-22},{-10,-20},{-22, 5},{ 20,-11},{ -7,-22},{-12, 20},{ 23, -5}, | |
84 { 13,-20},{ 24, -2},{-15, 19},{-11, 22},{ 16, 19},{ 23,-10},{-18,-18},{ -9,-24}, | |
85 { 24,-10},{ -3, 26},{-23, 13},{-18,-20},{ 17, 21},{ -4, 27},{ 27, 6},{ 1,-28}, | |
86 {-11, 26},{-17,-23},{ 7, 28},{ 11,-27},{ 29, 5},{-23,-19},{-28,-11},{-21, 22}, | |
87 {-30, 7},{-17, 26},{-27, 16},{ 13, 29},{ 19,-26},{ 10,-31},{-14,-30},{ 20,-27}, | |
88 {-29, 18},{-16,-31},{-28,-22},{ 21,-30},{-25, 28},{ 26,-29},{ 25,-32},{-32,-32} | |
89 }; | |
90 | |
91 // this is simply the scaled down elementwise product of the standard jpeg quantizer table and the AAN premul table | |
92 static const uint8_t dequant_table[64]={ | |
93 16, 15, 13, 19, 24, 31, 28, 17, | |
94 17, 23, 25, 31, 36, 63, 45, 21, | |
95 18, 24, 27, 37, 52, 59, 49, 20, | |
96 16, 28, 34, 40, 60, 80, 51, 20, | |
97 18, 31, 48, 66, 68, 86, 56, 21, | |
98 19, 38, 56, 59, 64, 64, 48, 20, | |
99 27, 48, 55, 55, 56, 51, 35, 15, | |
100 20, 35, 34, 32, 31, 22, 15, 8, | |
101 }; | |
102 | |
103 static VLC block_type_vlc[4]; | |
104 | |
105 | |
106 typedef struct CFrameBuffer{ | |
107 int allocated_size; | |
108 int size; | |
109 int id; | |
110 uint8_t *data; | |
111 }CFrameBuffer; | |
112 | |
113 typedef struct FourXContext{ | |
114 AVCodecContext *avctx; | |
115 DSPContext dsp; | |
116 AVFrame current_picture, last_picture; | |
117 GetBitContext pre_gb; ///< ac/dc prefix | |
118 GetBitContext gb; | |
119 uint8_t *bytestream; | |
120 uint16_t *wordstream; | |
121 int mv[256]; | |
122 VLC pre_vlc; | |
123 int last_dc; | |
124 DCTELEM __align8 block[6][64]; | |
125 uint8_t *bitstream_buffer; | |
126 int bitstream_buffer_size; | |
127 CFrameBuffer cfrm[CFRAME_BUFFER_COUNT]; | |
128 } FourXContext; | |
129 | |
130 | |
131 #define FIX_1_082392200 70936 | |
132 #define FIX_1_414213562 92682 | |
133 #define FIX_1_847759065 121095 | |
134 #define FIX_2_613125930 171254 | |
135 | |
136 #define MULTIPLY(var,const) (((var)*(const)) >> 16) | |
137 | |
138 static void idct(DCTELEM block[64]){ | |
139 int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; | |
140 int tmp10, tmp11, tmp12, tmp13; | |
141 int z5, z10, z11, z12, z13; | |
142 int i; | |
143 int temp[64]; | |
144 | |
145 for(i=0; i<8; i++){ | |
146 tmp10 = block[8*0 + i] + block[8*4 + i]; | |
147 tmp11 = block[8*0 + i] - block[8*4 + i]; | |
148 | |
149 tmp13 = block[8*2 + i] + block[8*6 + i]; | |
150 tmp12 = MULTIPLY(block[8*2 + i] - block[8*6 + i], FIX_1_414213562) - tmp13; | |
151 | |
152 tmp0 = tmp10 + tmp13; | |
153 tmp3 = tmp10 - tmp13; | |
154 tmp1 = tmp11 + tmp12; | |
155 tmp2 = tmp11 - tmp12; | |
156 | |
157 z13 = block[8*5 + i] + block[8*3 + i]; | |
158 z10 = block[8*5 + i] - block[8*3 + i]; | |
159 z11 = block[8*1 + i] + block[8*7 + i]; | |
160 z12 = block[8*1 + i] - block[8*7 + i]; | |
161 | |
162 tmp7 = z11 + z13; | |
163 tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); | |
164 | |
165 z5 = MULTIPLY(z10 + z12, FIX_1_847759065); | |
166 tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; | |
167 tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; | |
168 | |
169 tmp6 = tmp12 - tmp7; | |
170 tmp5 = tmp11 - tmp6; | |
171 tmp4 = tmp10 + tmp5; | |
172 | |
173 temp[8*0 + i] = tmp0 + tmp7; | |
174 temp[8*7 + i] = tmp0 - tmp7; | |
175 temp[8*1 + i] = tmp1 + tmp6; | |
176 temp[8*6 + i] = tmp1 - tmp6; | |
177 temp[8*2 + i] = tmp2 + tmp5; | |
178 temp[8*5 + i] = tmp2 - tmp5; | |
179 temp[8*4 + i] = tmp3 + tmp4; | |
180 temp[8*3 + i] = tmp3 - tmp4; | |
181 } | |
182 | |
183 for(i=0; i<8*8; i+=8){ | |
184 tmp10 = temp[0 + i] + temp[4 + i]; | |
185 tmp11 = temp[0 + i] - temp[4 + i]; | |
186 | |
187 tmp13 = temp[2 + i] + temp[6 + i]; | |
188 tmp12 = MULTIPLY(temp[2 + i] - temp[6 + i], FIX_1_414213562) - tmp13; | |
189 | |
190 tmp0 = tmp10 + tmp13; | |
191 tmp3 = tmp10 - tmp13; | |
192 tmp1 = tmp11 + tmp12; | |
193 tmp2 = tmp11 - tmp12; | |
194 | |
195 z13 = temp[5 + i] + temp[3 + i]; | |
196 z10 = temp[5 + i] - temp[3 + i]; | |
197 z11 = temp[1 + i] + temp[7 + i]; | |
198 z12 = temp[1 + i] - temp[7 + i]; | |
199 | |
200 tmp7 = z11 + z13; | |
201 tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); | |
202 | |
203 z5 = MULTIPLY(z10 + z12, FIX_1_847759065); | |
204 tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; | |
205 tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; | |
206 | |
207 tmp6 = tmp12 - tmp7; | |
208 tmp5 = tmp11 - tmp6; | |
209 tmp4 = tmp10 + tmp5; | |
210 | |
211 block[0 + i] = (tmp0 + tmp7)>>6; | |
212 block[7 + i] = (tmp0 - tmp7)>>6; | |
213 block[1 + i] = (tmp1 + tmp6)>>6; | |
214 block[6 + i] = (tmp1 - tmp6)>>6; | |
215 block[2 + i] = (tmp2 + tmp5)>>6; | |
216 block[5 + i] = (tmp2 - tmp5)>>6; | |
217 block[4 + i] = (tmp3 + tmp4)>>6; | |
218 block[3 + i] = (tmp3 - tmp4)>>6; | |
219 } | |
220 } | |
221 | |
222 static void init_vlcs(FourXContext *f){ | |
223 static int done = 0; | |
224 int i; | |
225 | |
226 if (!done) { | |
227 done = 1; | |
228 | |
229 for(i=0; i<4; i++){ | |
230 init_vlc(&block_type_vlc[i], BLOCK_TYPE_VLC_BITS, 7, | |
231 &block_type_tab[i][0][1], 2, 1, | |
232 &block_type_tab[i][0][0], 2, 1); | |
233 } | |
234 } | |
235 } | |
236 | |
237 static void init_mv(FourXContext *f){ | |
238 int i; | |
239 | |
240 for(i=0; i<256; i++){ | |
241 f->mv[i] = mv[i][0] + mv[i][1]*f->current_picture.linesize[0]/2; | |
242 } | |
243 } | |
244 | |
245 static inline void mcdc(uint16_t *dst, uint16_t *src, int log2w, int h, int stride, int scale, int dc){ | |
246 int i; | |
247 dc*= 0x10001; | |
248 | |
249 switch(log2w){ | |
250 case 0: | |
251 for(i=0; i<h; i++){ | |
252 dst[0] = scale*src[0] + dc; | |
253 if(scale) src += stride; | |
254 dst += stride; | |
255 } | |
256 break; | |
257 case 1: | |
258 for(i=0; i<h; i++){ | |
259 ((uint32_t*)dst)[0] = scale*((uint32_t*)src)[0] + dc; | |
260 if(scale) src += stride; | |
261 dst += stride; | |
262 } | |
263 break; | |
264 case 2: | |
265 for(i=0; i<h; i++){ | |
266 ((uint32_t*)dst)[0] = scale*((uint32_t*)src)[0] + dc; | |
267 ((uint32_t*)dst)[1] = scale*((uint32_t*)src)[1] + dc; | |
268 if(scale) src += stride; | |
269 dst += stride; | |
270 } | |
271 break; | |
272 case 3: | |
273 for(i=0; i<h; i++){ | |
274 ((uint32_t*)dst)[0] = scale*((uint32_t*)src)[0] + dc; | |
275 ((uint32_t*)dst)[1] = scale*((uint32_t*)src)[1] + dc; | |
276 ((uint32_t*)dst)[2] = scale*((uint32_t*)src)[2] + dc; | |
277 ((uint32_t*)dst)[3] = scale*((uint32_t*)src)[3] + dc; | |
278 if(scale) src += stride; | |
279 dst += stride; | |
280 } | |
281 break; | |
282 default: assert(0); | |
283 } | |
284 } | |
285 | |
286 static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, int log2w, int log2h, int stride){ | |
287 const int index= size2index[log2h][log2w]; | |
288 const int h= 1<<log2h; | |
289 int code= get_vlc2(&f->gb, block_type_vlc[index].table, BLOCK_TYPE_VLC_BITS, 1); | |
290 | |
291 assert(code>=0 && code<=6); | |
292 | |
293 if(code == 0){ | |
294 src += f->mv[ *f->bytestream++ ]; | |
295 mcdc(dst, src, log2w, h, stride, 1, 0); | |
296 }else if(code == 1){ | |
297 log2h--; | |
298 decode_p_block(f, dst , src , log2w, log2h, stride); | |
299 decode_p_block(f, dst + (stride<<log2h), src + (stride<<log2h), log2w, log2h, stride); | |
300 }else if(code == 2){ | |
301 log2w--; | |
302 decode_p_block(f, dst , src , log2w, log2h, stride); | |
303 decode_p_block(f, dst + (1<<log2w), src + (1<<log2w), log2w, log2h, stride); | |
304 }else if(code == 4){ | |
305 src += f->mv[ *f->bytestream++ ]; | |
306 mcdc(dst, src, log2w, h, stride, 1, le2me_16(*f->wordstream++)); | |
307 }else if(code == 5){ | |
308 mcdc(dst, src, log2w, h, stride, 0, le2me_16(*f->wordstream++)); | |
309 }else if(code == 6){ | |
310 if(log2w){ | |
311 dst[0] = le2me_16(*f->wordstream++); | |
312 dst[1] = le2me_16(*f->wordstream++); | |
313 }else{ | |
314 dst[0 ] = le2me_16(*f->wordstream++); | |
315 dst[stride] = le2me_16(*f->wordstream++); | |
316 } | |
317 } | |
318 } | |
319 | |
320 static int get32(void *p){ | |
321 return le2me_32(*(uint32_t*)p); | |
322 } | |
323 | |
324 static int decode_p_frame(FourXContext *f, uint8_t *buf, int length){ | |
325 int x, y; | |
326 const int width= f->avctx->width; | |
327 const int height= f->avctx->height; | |
328 uint16_t *src= (uint16_t*)f->last_picture.data[0]; | |
329 uint16_t *dst= (uint16_t*)f->current_picture.data[0]; | |
330 const int stride= f->current_picture.linesize[0]>>1; | |
331 const int bitstream_size= get32(buf+8); | |
332 const int bytestream_size= get32(buf+16); | |
333 const int wordstream_size= get32(buf+12); | |
334 | |
335 if(bitstream_size+ bytestream_size+ wordstream_size + 20 != length) | |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1514
diff
changeset
|
336 av_log(f->avctx, AV_LOG_ERROR, "lengths %d %d %d %d\n", bitstream_size, bytestream_size, wordstream_size, |
1293 | 337 bitstream_size+ bytestream_size+ wordstream_size - length); |
338 | |
339 f->bitstream_buffer= av_fast_realloc(f->bitstream_buffer, &f->bitstream_buffer_size, bitstream_size + FF_INPUT_BUFFER_PADDING_SIZE); | |
340 f->dsp.bswap_buf((uint32_t*)f->bitstream_buffer, (uint32_t*)(buf + 20), bitstream_size/4); | |
341 init_get_bits(&f->gb, f->bitstream_buffer, 8*bitstream_size); | |
342 | |
343 f->wordstream= (uint16_t*)(buf + 20 + bitstream_size); | |
344 f->bytestream= buf + 20 + bitstream_size + wordstream_size; | |
345 | |
346 init_mv(f); | |
347 | |
348 for(y=0; y<height; y+=8){ | |
349 for(x=0; x<width; x+=8){ | |
350 decode_p_block(f, dst + x, src + x, 3, 3, stride); | |
351 } | |
352 src += 8*stride; | |
353 dst += 8*stride; | |
354 } | |
355 | |
356 if(bitstream_size != (get_bits_count(&f->gb)+31)/32*4) | |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1514
diff
changeset
|
357 av_log(f->avctx, AV_LOG_ERROR, " %d %d %d bytes left\n", |
1293 | 358 bitstream_size - (get_bits_count(&f->gb)+31)/32*4, |
359 bytestream_size - (f->bytestream - (buf + 20 + bitstream_size + wordstream_size)), | |
360 wordstream_size - (((uint8_t*)f->wordstream) - (buf + 20 + bitstream_size)) | |
361 ); | |
362 | |
363 return 0; | |
364 } | |
365 | |
366 /** | |
367 * decode block and dequantize. | |
368 * Note this is allmost identical to mjpeg | |
369 */ | |
370 static int decode_i_block(FourXContext *f, DCTELEM *block){ | |
371 int code, i, j, level, val; | |
372 | |
373 /* DC coef */ | |
374 val = get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3); | |
375 if (val>>4){ | |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1514
diff
changeset
|
376 av_log(f->avctx, AV_LOG_ERROR, "error dc run != 0\n"); |
1293 | 377 } |
378 | |
379 if(val) | |
380 val = get_xbits(&f->gb, val); | |
381 | |
382 val = val * dequant_table[0] + f->last_dc; | |
383 f->last_dc = | |
384 block[0] = val; | |
385 /* AC coefs */ | |
386 i = 1; | |
387 for(;;) { | |
388 code = get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3); | |
389 | |
390 /* EOB */ | |
391 if (code == 0) | |
392 break; | |
393 if (code == 0xf0) { | |
394 i += 16; | |
395 } else { | |
396 level = get_xbits(&f->gb, code & 0xf); | |
397 i += code >> 4; | |
398 if (i >= 64) { | |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1514
diff
changeset
|
399 av_log(f->avctx, AV_LOG_ERROR, "run %d oveflow\n", i); |
1293 | 400 return 0; |
401 } | |
402 | |
403 j= ff_zigzag_direct[i]; | |
404 block[j] = level * dequant_table[j]; | |
405 i++; | |
406 if (i >= 64) | |
407 break; | |
408 } | |
409 } | |
410 | |
411 return 0; | |
412 } | |
413 | |
414 static inline void idct_put(FourXContext *f, int x, int y){ | |
415 DCTELEM (*block)[64]= f->block; | |
416 int stride= f->current_picture.linesize[0]>>1; | |
417 int i; | |
418 uint16_t *dst = ((uint16_t*)f->current_picture.data[0]) + y * stride + x; | |
1295 | 419 |
420 for(i=0; i<4; i++){ | |
421 block[i][0] += 0x80*8*8; | |
422 idct(block[i]); | |
423 } | |
1293 | 424 |
1295 | 425 if(!(f->avctx->flags&CODEC_FLAG_GRAY)){ |
426 for(i=4; i<6; i++) idct(block[i]); | |
427 } | |
1293 | 428 |
1514 | 429 /* Note transform is: |
430 y= ( 1b + 4g + 2r)/14 | |
431 cb=( 3b - 2g - 1r)/14 | |
432 cr=(-1b - 4g + 5r)/14 | |
433 */ | |
1293 | 434 for(y=0; y<8; y++){ |
435 for(x=0; x<8; x++){ | |
436 DCTELEM *temp= block[(x>>2) + 2*(y>>2)] + 2*(x&3) + 2*8*(y&3); //FIXME optimize | |
1295 | 437 int cb= block[4][x + 8*y]; |
438 int cr= block[5][x + 8*y]; | |
1293 | 439 int cg= (cb + cr)>>1; |
440 int y; | |
441 | |
1295 | 442 cb+=cb; |
1293 | 443 |
444 y = temp[0]; | |
1295 | 445 dst[0 ]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8); |
1293 | 446 y = temp[1]; |
1295 | 447 dst[1 ]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8); |
1293 | 448 y = temp[8]; |
1295 | 449 dst[ stride]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8); |
1293 | 450 y = temp[9]; |
1295 | 451 dst[1+stride]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8); |
1293 | 452 dst += 2; |
453 } | |
454 dst += 2*stride - 2*8; | |
455 } | |
456 } | |
457 | |
458 static int decode_i_mb(FourXContext *f){ | |
459 int i; | |
460 | |
461 f->dsp.clear_blocks(f->block[0]); | |
462 | |
463 for(i=0; i<6; i++){ | |
464 if(decode_i_block(f, f->block[i]) < 0) | |
465 return -1; | |
466 } | |
467 | |
468 return 0; | |
469 } | |
470 | |
471 static uint8_t *read_huffman_tables(FourXContext *f, uint8_t * const buf){ | |
472 int frequency[512]; | |
473 uint8_t flag[512]; | |
474 int up[512]; | |
475 uint8_t len_tab[257]; | |
476 int bits_tab[257]; | |
477 int start, end; | |
478 uint8_t *ptr= buf; | |
479 int j; | |
480 | |
481 memset(frequency, 0, sizeof(frequency)); | |
482 memset(up, -1, sizeof(up)); | |
483 | |
484 start= *ptr++; | |
485 end= *ptr++; | |
486 for(;;){ | |
487 int i; | |
488 | |
489 for(i=start; i<=end; i++){ | |
490 frequency[i]= *ptr++; | |
491 // printf("%d %d %d\n", start, end, frequency[i]); | |
492 } | |
493 start= *ptr++; | |
494 if(start==0) break; | |
495 | |
496 end= *ptr++; | |
497 } | |
498 frequency[256]=1; | |
499 | |
500 while((ptr - buf)&3) ptr++; // 4byte align | |
501 | |
502 // for(j=0; j<16; j++) | |
503 // printf("%2X", ptr[j]); | |
504 | |
505 for(j=257; j<512; j++){ | |
1294 | 506 int min_freq[2]= {256*256, 256*256}; |
507 int smallest[2]= {0, 0}; | |
1293 | 508 int i; |
509 for(i=0; i<j; i++){ | |
510 if(frequency[i] == 0) continue; | |
1294 | 511 if(frequency[i] < min_freq[1]){ |
512 if(frequency[i] < min_freq[0]){ | |
513 min_freq[1]= min_freq[0]; smallest[1]= smallest[0]; | |
514 min_freq[0]= frequency[i];smallest[0]= i; | |
515 }else{ | |
516 min_freq[1]= frequency[i];smallest[1]= i; | |
517 } | |
1293 | 518 } |
519 } | |
1294 | 520 if(min_freq[1] == 256*256) break; |
1293 | 521 |
1294 | 522 frequency[j]= min_freq[0] + min_freq[1]; |
1293 | 523 flag[ smallest[0] ]= 0; |
524 flag[ smallest[1] ]= 1; | |
525 up[ smallest[0] ]= | |
526 up[ smallest[1] ]= j; | |
527 frequency[ smallest[0] ]= frequency[ smallest[1] ]= 0; | |
528 } | |
529 | |
530 for(j=0; j<257; j++){ | |
531 int node; | |
532 int len=0; | |
533 int bits=0; | |
534 | |
535 for(node= j; up[node] != -1; node= up[node]){ | |
536 bits += flag[node]<<len; | |
537 len++; | |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1514
diff
changeset
|
538 if(len > 31) av_log(f->avctx, AV_LOG_ERROR, "vlc length overflow\n"); //can this happen at all ? |
1293 | 539 } |
540 | |
541 bits_tab[j]= bits; | |
542 len_tab[j]= len; | |
543 } | |
544 | |
545 init_vlc(&f->pre_vlc, ACDC_VLC_BITS, 257, | |
546 len_tab , 1, 1, | |
547 bits_tab, 4, 4); | |
548 | |
549 return ptr; | |
550 } | |
551 | |
552 static int decode_i_frame(FourXContext *f, uint8_t *buf, int length){ | |
553 int x, y; | |
554 const int width= f->avctx->width; | |
555 const int height= f->avctx->height; | |
556 uint16_t *dst= (uint16_t*)f->current_picture.data[0]; | |
557 const int stride= f->current_picture.linesize[0]>>1; | |
558 const int bitstream_size= get32(buf); | |
1478 | 559 const int token_count __attribute__((unused)) = get32(buf + bitstream_size + 8); |
1293 | 560 int prestream_size= 4*get32(buf + bitstream_size + 4); |
561 uint8_t *prestream= buf + bitstream_size + 12; | |
562 | |
563 if(prestream_size + bitstream_size + 12 != length) | |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1514
diff
changeset
|
564 av_log(f->avctx, AV_LOG_ERROR, "size missmatch %d %d %d\n", prestream_size, bitstream_size, length); |
1293 | 565 |
566 prestream= read_huffman_tables(f, prestream); | |
567 | |
568 init_get_bits(&f->gb, buf + 4, 8*bitstream_size); | |
569 | |
570 prestream_size= length + buf - prestream; | |
1294 | 571 |
1293 | 572 f->bitstream_buffer= av_fast_realloc(f->bitstream_buffer, &f->bitstream_buffer_size, prestream_size + FF_INPUT_BUFFER_PADDING_SIZE); |
573 f->dsp.bswap_buf((uint32_t*)f->bitstream_buffer, (uint32_t*)prestream, prestream_size/4); | |
574 init_get_bits(&f->pre_gb, f->bitstream_buffer, 8*prestream_size); | |
575 | |
576 f->last_dc= 0*128*8*8; | |
577 | |
578 for(y=0; y<height; y+=16){ | |
579 for(x=0; x<width; x+=16){ | |
580 if(decode_i_mb(f) < 0) | |
581 return -1; | |
582 | |
583 idct_put(f, x, y); | |
584 } | |
585 dst += 16*stride; | |
586 } | |
587 | |
588 if(get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3) != 256) | |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1514
diff
changeset
|
589 av_log(f->avctx, AV_LOG_ERROR, "end missmatch\n"); |
1293 | 590 |
591 return 0; | |
592 } | |
593 | |
594 static int decode_frame(AVCodecContext *avctx, | |
595 void *data, int *data_size, | |
596 uint8_t *buf, int buf_size) | |
597 { | |
598 FourXContext * const f = avctx->priv_data; | |
599 AVFrame *picture = data; | |
600 AVFrame *p, temp; | |
601 int i, frame_4cc, frame_size; | |
602 | |
603 *data_size = 0; | |
604 | |
605 /* special case for last picture */ | |
606 if (buf_size == 0) { | |
607 return 0; | |
608 } | |
609 | |
610 frame_4cc= get32(buf); | |
611 if(buf_size != get32(buf+4)+8){ | |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1514
diff
changeset
|
612 av_log(f->avctx, AV_LOG_ERROR, "size missmatch %d %d\n", buf_size, get32(buf+4)); |
1293 | 613 } |
614 | |
615 if(frame_4cc == ff_get_fourcc("cfrm")){ | |
616 int free_index=-1; | |
617 const int data_size= buf_size - 20; | |
618 const int id= get32(buf+12); | |
619 const int whole_size= get32(buf+16); | |
620 CFrameBuffer *cfrm; | |
621 | |
622 for(i=0; i<CFRAME_BUFFER_COUNT; i++){ | |
623 if(f->cfrm[i].id && f->cfrm[i].id < avctx->frame_number) | |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1514
diff
changeset
|
624 av_log(f->avctx, AV_LOG_ERROR, "lost c frame %d\n", f->cfrm[i].id); |
1293 | 625 } |
626 | |
627 for(i=0; i<CFRAME_BUFFER_COUNT; i++){ | |
628 if(f->cfrm[i].id == id) break; | |
629 if(f->cfrm[i].size == 0 ) free_index= i; | |
630 } | |
631 | |
632 if(i>=CFRAME_BUFFER_COUNT){ | |
633 i= free_index; | |
634 f->cfrm[i].id= id; | |
635 } | |
636 cfrm= &f->cfrm[i]; | |
637 | |
638 cfrm->data= av_fast_realloc(cfrm->data, &cfrm->allocated_size, cfrm->size + data_size + FF_INPUT_BUFFER_PADDING_SIZE); | |
639 | |
640 memcpy(cfrm->data + cfrm->size, buf+20, data_size); | |
641 cfrm->size += data_size; | |
642 | |
643 if(cfrm->size >= whole_size){ | |
644 buf= cfrm->data; | |
645 frame_size= cfrm->size; | |
646 | |
647 if(id != avctx->frame_number){ | |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1514
diff
changeset
|
648 av_log(f->avctx, AV_LOG_ERROR, "cframe id missmatch %d %d\n", id, avctx->frame_number); |
1293 | 649 } |
650 | |
651 cfrm->size= cfrm->id= 0; | |
652 frame_4cc= ff_get_fourcc("pfrm"); | |
653 }else | |
654 return buf_size; | |
655 }else{ | |
656 buf= buf + 12; | |
657 frame_size= buf_size - 12; | |
658 } | |
659 | |
660 temp= f->current_picture; | |
661 f->current_picture= f->last_picture; | |
662 f->last_picture= temp; | |
663 | |
664 p= &f->current_picture; | |
665 avctx->coded_frame= p; | |
666 | |
667 avctx->flags |= CODEC_FLAG_EMU_EDGE; // alternatively we would have to use our own buffer management | |
668 | |
669 if(p->data[0]) | |
670 avctx->release_buffer(avctx, p); | |
671 | |
672 p->reference= 1; | |
673 if(avctx->get_buffer(avctx, p) < 0){ | |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1514
diff
changeset
|
674 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); |
1293 | 675 return -1; |
676 } | |
677 | |
678 if(frame_4cc == ff_get_fourcc("ifrm")){ | |
679 p->pict_type= I_TYPE; | |
680 if(decode_i_frame(f, buf, frame_size) < 0) | |
681 return -1; | |
682 }else if(frame_4cc == ff_get_fourcc("pfrm")){ | |
683 p->pict_type= P_TYPE; | |
684 if(decode_p_frame(f, buf, frame_size) < 0) | |
685 return -1; | |
686 }else if(frame_4cc == ff_get_fourcc("snd_")){ | |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1514
diff
changeset
|
687 av_log(avctx, AV_LOG_ERROR, "ignoring snd_ chunk length:%d\n", buf_size); |
1293 | 688 }else{ |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1514
diff
changeset
|
689 av_log(avctx, AV_LOG_ERROR, "ignoring unknown chunk length:%d\n", buf_size); |
1293 | 690 } |
691 | |
692 #if 0 | |
693 for(i=0; i<20; i++){ | |
694 printf("%2X %c ", buf[i], clip(buf[i],16,126)); | |
695 } | |
696 #endif | |
697 | |
698 p->key_frame= p->pict_type == I_TYPE; | |
699 | |
700 *picture= *p; | |
701 *data_size = sizeof(AVPicture); | |
702 | |
703 emms_c(); | |
704 | |
705 return buf_size; | |
706 } | |
707 | |
708 | |
709 static void common_init(AVCodecContext *avctx){ | |
710 FourXContext * const f = avctx->priv_data; | |
711 | |
712 dsputil_init(&f->dsp, avctx); | |
713 | |
714 f->avctx= avctx; | |
715 } | |
716 | |
717 static int decode_init(AVCodecContext *avctx){ | |
718 FourXContext * const f = avctx->priv_data; | |
719 | |
720 common_init(avctx); | |
721 init_vlcs(f); | |
722 | |
723 avctx->pix_fmt= PIX_FMT_RGB565; | |
724 | |
725 return 0; | |
726 } | |
727 | |
728 | |
729 static int decode_end(AVCodecContext *avctx){ | |
730 FourXContext * const f = avctx->priv_data; | |
731 int i; | |
732 | |
733 av_freep(&f->bitstream_buffer); | |
734 f->bitstream_buffer_size=0; | |
735 for(i=0; i<CFRAME_BUFFER_COUNT; i++){ | |
736 av_freep(&f->cfrm[i].data); | |
737 f->cfrm[i].allocated_size= 0; | |
738 } | |
739 free_vlc(&f->pre_vlc); | |
740 | |
741 avcodec_default_free_buffers(avctx); | |
742 | |
743 return 0; | |
744 } | |
745 | |
746 AVCodec fourxm_decoder = { | |
747 "4xm", | |
748 CODEC_TYPE_VIDEO, | |
749 CODEC_ID_4XM, | |
750 sizeof(FourXContext), | |
751 decode_init, | |
752 NULL, | |
753 decode_end, | |
754 decode_frame, | |
755 /*CODEC_CAP_DR1,*/ | |
756 }; | |
757 |