Mercurial > libavcodec.hg
annotate asv1.c @ 2497:69adfbbdcdeb libavcodec
- samples from mplayer ftp in the "adv" profile seem to have profile=2,
which isn't the advanced one; and indeed, using adv. profile parser fails.
Using normal parser works, and that's what is done
- attempt at taking care of stride for NORM2 bitplane decoding
- duplication of much code from msmpeg4.c; this code isn't yet used, but
goes down as far as the block layer (mainly Transform Type stuff, the
remains are wild editing without checking). Unusable yet, and lacks the AC
decoding (but a step further in bitstream parsing)
patch by anonymous
author | michael |
---|---|
date | Fri, 04 Feb 2005 02:20:38 +0000 |
parents | f67b63ed036d |
children | 91e094c9dcdc |
rev | line source |
---|---|
1273 | 1 /* |
1433 | 2 * ASUS V1/V2 codec |
1273 | 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 asv1.c | |
1433 | 22 * ASUS V1/V2 codec. |
1273 | 23 */ |
24 | |
25 #include "avcodec.h" | |
26 #include "dsputil.h" | |
27 #include "mpegvideo.h" | |
28 | |
29 //#undef NDEBUG | |
30 //#include <assert.h> | |
31 | |
1433 | 32 #define VLC_BITS 6 |
33 #define ASV2_LEVEL_VLC_BITS 10 | |
34 | |
1273 | 35 typedef struct ASV1Context{ |
36 AVCodecContext *avctx; | |
37 DSPContext dsp; | |
38 AVFrame picture; | |
39 PutBitContext pb; | |
40 GetBitContext gb; | |
41 ScanTable scantable; | |
42 int inv_qscale; | |
43 int mb_width; | |
44 int mb_height; | |
45 int mb_width2; | |
46 int mb_height2; | |
47 DCTELEM __align8 block[6][64]; | |
48 uint16_t __align8 intra_matrix[64]; | |
49 int __align8 q_intra_matrix[64]; | |
50 uint8_t *bitstream_buffer; | |
51 int bitstream_buffer_size; | |
52 } ASV1Context; | |
53 | |
54 static const uint8_t scantab[64]={ | |
55 0x00,0x08,0x01,0x09,0x10,0x18,0x11,0x19, | |
56 0x02,0x0A,0x03,0x0B,0x12,0x1A,0x13,0x1B, | |
57 0x04,0x0C,0x05,0x0D,0x20,0x28,0x21,0x29, | |
58 0x06,0x0E,0x07,0x0F,0x14,0x1C,0x15,0x1D, | |
59 0x22,0x2A,0x23,0x2B,0x30,0x38,0x31,0x39, | |
1433 | 60 0x16,0x1E,0x17,0x1F,0x24,0x2C,0x25,0x2D, |
61 0x32,0x3A,0x33,0x3B,0x26,0x2E,0x27,0x2F, | |
62 0x34,0x3C,0x35,0x3D,0x36,0x3E,0x37,0x3F, | |
63 }; | |
64 | |
65 | |
66 static const uint8_t reverse[256]={ | |
67 0x00,0x80,0x40,0xC0,0x20,0xA0,0x60,0xE0,0x10,0x90,0x50,0xD0,0x30,0xB0,0x70,0xF0, | |
68 0x08,0x88,0x48,0xC8,0x28,0xA8,0x68,0xE8,0x18,0x98,0x58,0xD8,0x38,0xB8,0x78,0xF8, | |
69 0x04,0x84,0x44,0xC4,0x24,0xA4,0x64,0xE4,0x14,0x94,0x54,0xD4,0x34,0xB4,0x74,0xF4, | |
70 0x0C,0x8C,0x4C,0xCC,0x2C,0xAC,0x6C,0xEC,0x1C,0x9C,0x5C,0xDC,0x3C,0xBC,0x7C,0xFC, | |
71 0x02,0x82,0x42,0xC2,0x22,0xA2,0x62,0xE2,0x12,0x92,0x52,0xD2,0x32,0xB2,0x72,0xF2, | |
72 0x0A,0x8A,0x4A,0xCA,0x2A,0xAA,0x6A,0xEA,0x1A,0x9A,0x5A,0xDA,0x3A,0xBA,0x7A,0xFA, | |
73 0x06,0x86,0x46,0xC6,0x26,0xA6,0x66,0xE6,0x16,0x96,0x56,0xD6,0x36,0xB6,0x76,0xF6, | |
74 0x0E,0x8E,0x4E,0xCE,0x2E,0xAE,0x6E,0xEE,0x1E,0x9E,0x5E,0xDE,0x3E,0xBE,0x7E,0xFE, | |
75 0x01,0x81,0x41,0xC1,0x21,0xA1,0x61,0xE1,0x11,0x91,0x51,0xD1,0x31,0xB1,0x71,0xF1, | |
76 0x09,0x89,0x49,0xC9,0x29,0xA9,0x69,0xE9,0x19,0x99,0x59,0xD9,0x39,0xB9,0x79,0xF9, | |
77 0x05,0x85,0x45,0xC5,0x25,0xA5,0x65,0xE5,0x15,0x95,0x55,0xD5,0x35,0xB5,0x75,0xF5, | |
78 0x0D,0x8D,0x4D,0xCD,0x2D,0xAD,0x6D,0xED,0x1D,0x9D,0x5D,0xDD,0x3D,0xBD,0x7D,0xFD, | |
79 0x03,0x83,0x43,0xC3,0x23,0xA3,0x63,0xE3,0x13,0x93,0x53,0xD3,0x33,0xB3,0x73,0xF3, | |
80 0x0B,0x8B,0x4B,0xCB,0x2B,0xAB,0x6B,0xEB,0x1B,0x9B,0x5B,0xDB,0x3B,0xBB,0x7B,0xFB, | |
81 0x07,0x87,0x47,0xC7,0x27,0xA7,0x67,0xE7,0x17,0x97,0x57,0xD7,0x37,0xB7,0x77,0xF7, | |
82 0x0F,0x8F,0x4F,0xCF,0x2F,0xAF,0x6F,0xEF,0x1F,0x9F,0x5F,0xDF,0x3F,0xBF,0x7F,0xFF, | |
1273 | 83 }; |
84 | |
85 static const uint8_t ccp_tab[17][2]={ | |
1433 | 86 {0x2,2}, {0x7,5}, {0xB,5}, {0x3,5}, |
87 {0xD,5}, {0x5,5}, {0x9,5}, {0x1,5}, | |
88 {0xE,5}, {0x6,5}, {0xA,5}, {0x2,5}, | |
89 {0xC,5}, {0x4,5}, {0x8,5}, {0x3,2}, | |
1273 | 90 {0xF,5}, //EOB |
91 }; | |
92 | |
93 static const uint8_t level_tab[7][2]={ | |
94 {3,4}, {3,3}, {3,2}, {0,3}, {2,2}, {2,3}, {2,4} | |
95 }; | |
96 | |
1433 | 97 static const uint8_t dc_ccp_tab[8][2]={ |
98 {0x1,2}, {0xD,4}, {0xF,4}, {0xC,4}, | |
99 {0x5,3}, {0xE,4}, {0x4,3}, {0x0,2}, | |
100 }; | |
101 | |
102 static const uint8_t ac_ccp_tab[16][2]={ | |
103 {0x00,2}, {0x3B,6}, {0x0A,4}, {0x3A,6}, | |
104 {0x02,3}, {0x39,6}, {0x3C,6}, {0x38,6}, | |
105 {0x03,3}, {0x3D,6}, {0x08,4}, {0x1F,5}, | |
106 {0x09,4}, {0x0B,4}, {0x0D,4}, {0x0C,4}, | |
107 }; | |
108 | |
109 static const uint8_t asv2_level_tab[63][2]={ | |
110 {0x3F,10},{0x2F,10},{0x37,10},{0x27,10},{0x3B,10},{0x2B,10},{0x33,10},{0x23,10}, | |
111 {0x3D,10},{0x2D,10},{0x35,10},{0x25,10},{0x39,10},{0x29,10},{0x31,10},{0x21,10}, | |
112 {0x1F, 8},{0x17, 8},{0x1B, 8},{0x13, 8},{0x1D, 8},{0x15, 8},{0x19, 8},{0x11, 8}, | |
113 {0x0F, 6},{0x0B, 6},{0x0D, 6},{0x09, 6}, | |
114 {0x07, 4},{0x05, 4}, | |
115 {0x03, 2}, | |
116 {0x00, 5}, | |
117 {0x02, 2}, | |
118 {0x04, 4},{0x06, 4}, | |
119 {0x08, 6},{0x0C, 6},{0x0A, 6},{0x0E, 6}, | |
120 {0x10, 8},{0x18, 8},{0x14, 8},{0x1C, 8},{0x12, 8},{0x1A, 8},{0x16, 8},{0x1E, 8}, | |
121 {0x20,10},{0x30,10},{0x28,10},{0x38,10},{0x24,10},{0x34,10},{0x2C,10},{0x3C,10}, | |
122 {0x22,10},{0x32,10},{0x2A,10},{0x3A,10},{0x26,10},{0x36,10},{0x2E,10},{0x3E,10}, | |
123 }; | |
124 | |
125 | |
1273 | 126 static VLC ccp_vlc; |
127 static VLC level_vlc; | |
1433 | 128 static VLC dc_ccp_vlc; |
129 static VLC ac_ccp_vlc; | |
130 static VLC asv2_level_vlc; | |
1273 | 131 |
132 static void init_vlcs(ASV1Context *a){ | |
133 static int done = 0; | |
134 | |
135 if (!done) { | |
136 done = 1; | |
137 | |
138 init_vlc(&ccp_vlc, VLC_BITS, 17, | |
139 &ccp_tab[0][1], 2, 1, | |
2370
26560d4fdb1f
Memory leak fix patch by (Burkhard Plaum <plaum >at< ipf.uni-stuttgart )dot( de>)
michael
parents:
2028
diff
changeset
|
140 &ccp_tab[0][0], 2, 1, 1); |
1433 | 141 init_vlc(&dc_ccp_vlc, VLC_BITS, 8, |
142 &dc_ccp_tab[0][1], 2, 1, | |
2370
26560d4fdb1f
Memory leak fix patch by (Burkhard Plaum <plaum >at< ipf.uni-stuttgart )dot( de>)
michael
parents:
2028
diff
changeset
|
143 &dc_ccp_tab[0][0], 2, 1, 1); |
1433 | 144 init_vlc(&ac_ccp_vlc, VLC_BITS, 16, |
145 &ac_ccp_tab[0][1], 2, 1, | |
2370
26560d4fdb1f
Memory leak fix patch by (Burkhard Plaum <plaum >at< ipf.uni-stuttgart )dot( de>)
michael
parents:
2028
diff
changeset
|
146 &ac_ccp_tab[0][0], 2, 1, 1); |
1273 | 147 init_vlc(&level_vlc, VLC_BITS, 7, |
148 &level_tab[0][1], 2, 1, | |
2370
26560d4fdb1f
Memory leak fix patch by (Burkhard Plaum <plaum >at< ipf.uni-stuttgart )dot( de>)
michael
parents:
2028
diff
changeset
|
149 &level_tab[0][0], 2, 1, 1); |
1433 | 150 init_vlc(&asv2_level_vlc, ASV2_LEVEL_VLC_BITS, 63, |
151 &asv2_level_tab[0][1], 2, 1, | |
2370
26560d4fdb1f
Memory leak fix patch by (Burkhard Plaum <plaum >at< ipf.uni-stuttgart )dot( de>)
michael
parents:
2028
diff
changeset
|
152 &asv2_level_tab[0][0], 2, 1, 1); |
1273 | 153 } |
154 } | |
155 | |
1433 | 156 //FIXME write a reversed bitstream reader to avoid the double reverse |
157 static inline int asv2_get_bits(GetBitContext *gb, int n){ | |
158 return reverse[ get_bits(gb, n) << (8-n) ]; | |
159 } | |
160 | |
1434 | 161 static inline void asv2_put_bits(PutBitContext *pb, int n, int v){ |
162 put_bits(pb, n, reverse[ v << (8-n) ]); | |
163 } | |
164 | |
1433 | 165 static inline int asv1_get_level(GetBitContext *gb){ |
1273 | 166 int code= get_vlc2(gb, level_vlc.table, VLC_BITS, 1); |
167 | |
168 if(code==3) return get_sbits(gb, 8); | |
169 else return code - 3; | |
170 } | |
171 | |
1433 | 172 static inline int asv2_get_level(GetBitContext *gb){ |
173 int code= get_vlc2(gb, asv2_level_vlc.table, ASV2_LEVEL_VLC_BITS, 1); | |
174 | |
175 if(code==31) return (int8_t)asv2_get_bits(gb, 8); | |
176 else return code - 31; | |
177 } | |
178 | |
179 static inline void asv1_put_level(PutBitContext *pb, int level){ | |
1273 | 180 unsigned int index= level + 3; |
181 | |
182 if(index <= 6) put_bits(pb, level_tab[index][1], level_tab[index][0]); | |
183 else{ | |
184 put_bits(pb, level_tab[3][1], level_tab[3][0]); | |
185 put_bits(pb, 8, level&0xFF); | |
186 } | |
187 } | |
188 | |
1434 | 189 static inline void asv2_put_level(PutBitContext *pb, int level){ |
190 unsigned int index= level + 31; | |
191 | |
192 if(index <= 62) put_bits(pb, asv2_level_tab[index][1], asv2_level_tab[index][0]); | |
193 else{ | |
194 put_bits(pb, asv2_level_tab[31][1], asv2_level_tab[31][0]); | |
195 asv2_put_bits(pb, 8, level&0xFF); | |
196 } | |
197 } | |
198 | |
1433 | 199 static inline int asv1_decode_block(ASV1Context *a, DCTELEM block[64]){ |
1273 | 200 int i; |
201 | |
202 block[0]= 8*get_bits(&a->gb, 8); | |
203 | |
204 for(i=0; i<11; i++){ | |
205 const int ccp= get_vlc2(&a->gb, ccp_vlc.table, VLC_BITS, 1); | |
206 | |
207 if(ccp){ | |
208 if(ccp == 16) break; | |
209 if(ccp < 0 || i>=10){ | |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1522
diff
changeset
|
210 av_log(a->avctx, AV_LOG_ERROR, "coded coeff pattern damaged\n"); |
1273 | 211 return -1; |
212 } | |
213 | |
1433 | 214 if(ccp&8) block[a->scantable.permutated[4*i+0]]= (asv1_get_level(&a->gb) * a->intra_matrix[4*i+0])>>4; |
215 if(ccp&4) block[a->scantable.permutated[4*i+1]]= (asv1_get_level(&a->gb) * a->intra_matrix[4*i+1])>>4; | |
216 if(ccp&2) block[a->scantable.permutated[4*i+2]]= (asv1_get_level(&a->gb) * a->intra_matrix[4*i+2])>>4; | |
217 if(ccp&1) block[a->scantable.permutated[4*i+3]]= (asv1_get_level(&a->gb) * a->intra_matrix[4*i+3])>>4; | |
1273 | 218 } |
219 } | |
220 | |
221 return 0; | |
222 } | |
223 | |
1433 | 224 static inline int asv2_decode_block(ASV1Context *a, DCTELEM block[64]){ |
225 int i, count, ccp; | |
226 | |
227 count= asv2_get_bits(&a->gb, 4); | |
228 | |
229 block[0]= 8*asv2_get_bits(&a->gb, 8); | |
230 | |
231 ccp= get_vlc2(&a->gb, dc_ccp_vlc.table, VLC_BITS, 1); | |
232 if(ccp){ | |
233 if(ccp&4) block[a->scantable.permutated[1]]= (asv2_get_level(&a->gb) * a->intra_matrix[1])>>4; | |
234 if(ccp&2) block[a->scantable.permutated[2]]= (asv2_get_level(&a->gb) * a->intra_matrix[2])>>4; | |
235 if(ccp&1) block[a->scantable.permutated[3]]= (asv2_get_level(&a->gb) * a->intra_matrix[3])>>4; | |
236 } | |
237 | |
238 for(i=1; i<count+1; i++){ | |
239 const int ccp= get_vlc2(&a->gb, ac_ccp_vlc.table, VLC_BITS, 1); | |
240 | |
241 if(ccp){ | |
242 if(ccp&8) block[a->scantable.permutated[4*i+0]]= (asv2_get_level(&a->gb) * a->intra_matrix[4*i+0])>>4; | |
243 if(ccp&4) block[a->scantable.permutated[4*i+1]]= (asv2_get_level(&a->gb) * a->intra_matrix[4*i+1])>>4; | |
244 if(ccp&2) block[a->scantable.permutated[4*i+2]]= (asv2_get_level(&a->gb) * a->intra_matrix[4*i+2])>>4; | |
245 if(ccp&1) block[a->scantable.permutated[4*i+3]]= (asv2_get_level(&a->gb) * a->intra_matrix[4*i+3])>>4; | |
246 } | |
247 } | |
248 | |
249 return 0; | |
250 } | |
251 | |
1434 | 252 static inline void asv1_encode_block(ASV1Context *a, DCTELEM block[64]){ |
1273 | 253 int i; |
254 int nc_count=0; | |
255 | |
256 put_bits(&a->pb, 8, (block[0] + 32)>>6); | |
257 block[0]= 0; | |
258 | |
259 for(i=0; i<10; i++){ | |
260 const int index= scantab[4*i]; | |
261 int ccp=0; | |
262 | |
1433 | 263 if( (block[index + 0] = (block[index + 0]*a->q_intra_matrix[index + 0] + (1<<15))>>16) ) ccp |= 8; |
264 if( (block[index + 8] = (block[index + 8]*a->q_intra_matrix[index + 8] + (1<<15))>>16) ) ccp |= 4; | |
265 if( (block[index + 1] = (block[index + 1]*a->q_intra_matrix[index + 1] + (1<<15))>>16) ) ccp |= 2; | |
266 if( (block[index + 9] = (block[index + 9]*a->q_intra_matrix[index + 9] + (1<<15))>>16) ) ccp |= 1; | |
1273 | 267 |
268 if(ccp){ | |
269 for(;nc_count; nc_count--) | |
270 put_bits(&a->pb, ccp_tab[0][1], ccp_tab[0][0]); | |
271 | |
272 put_bits(&a->pb, ccp_tab[ccp][1], ccp_tab[ccp][0]); | |
273 | |
1433 | 274 if(ccp&8) asv1_put_level(&a->pb, block[index + 0]); |
275 if(ccp&4) asv1_put_level(&a->pb, block[index + 8]); | |
276 if(ccp&2) asv1_put_level(&a->pb, block[index + 1]); | |
277 if(ccp&1) asv1_put_level(&a->pb, block[index + 9]); | |
1273 | 278 }else{ |
279 nc_count++; | |
280 } | |
281 } | |
282 put_bits(&a->pb, ccp_tab[16][1], ccp_tab[16][0]); | |
283 } | |
284 | |
1434 | 285 static inline void asv2_encode_block(ASV1Context *a, DCTELEM block[64]){ |
286 int i; | |
287 int count=0; | |
288 | |
289 for(count=63; count>3; count--){ | |
290 const int index= scantab[count]; | |
291 | |
292 if( (block[index]*a->q_intra_matrix[index] + (1<<15))>>16 ) | |
293 break; | |
294 } | |
295 | |
296 count >>= 2; | |
297 | |
298 asv2_put_bits(&a->pb, 4, count); | |
299 asv2_put_bits(&a->pb, 8, (block[0] + 32)>>6); | |
300 block[0]= 0; | |
301 | |
302 for(i=0; i<=count; i++){ | |
303 const int index= scantab[4*i]; | |
304 int ccp=0; | |
305 | |
306 if( (block[index + 0] = (block[index + 0]*a->q_intra_matrix[index + 0] + (1<<15))>>16) ) ccp |= 8; | |
307 if( (block[index + 8] = (block[index + 8]*a->q_intra_matrix[index + 8] + (1<<15))>>16) ) ccp |= 4; | |
308 if( (block[index + 1] = (block[index + 1]*a->q_intra_matrix[index + 1] + (1<<15))>>16) ) ccp |= 2; | |
309 if( (block[index + 9] = (block[index + 9]*a->q_intra_matrix[index + 9] + (1<<15))>>16) ) ccp |= 1; | |
310 | |
311 if(i) put_bits(&a->pb, ac_ccp_tab[ccp][1], ac_ccp_tab[ccp][0]); | |
312 else put_bits(&a->pb, dc_ccp_tab[ccp][1], dc_ccp_tab[ccp][0]); | |
313 | |
314 if(ccp){ | |
315 if(ccp&8) asv2_put_level(&a->pb, block[index + 0]); | |
316 if(ccp&4) asv2_put_level(&a->pb, block[index + 8]); | |
317 if(ccp&2) asv2_put_level(&a->pb, block[index + 1]); | |
318 if(ccp&1) asv2_put_level(&a->pb, block[index + 9]); | |
319 } | |
320 } | |
321 } | |
322 | |
1273 | 323 static inline int decode_mb(ASV1Context *a, DCTELEM block[6][64]){ |
324 int i; | |
325 | |
326 a->dsp.clear_blocks(block[0]); | |
327 | |
1433 | 328 if(a->avctx->codec_id == CODEC_ID_ASV1){ |
329 for(i=0; i<6; i++){ | |
330 if( asv1_decode_block(a, block[i]) < 0) | |
331 return -1; | |
332 } | |
333 }else{ | |
334 for(i=0; i<6; i++){ | |
335 if( asv2_decode_block(a, block[i]) < 0) | |
336 return -1; | |
337 } | |
1273 | 338 } |
339 return 0; | |
340 } | |
341 | |
2422 | 342 static inline int encode_mb(ASV1Context *a, DCTELEM block[6][64]){ |
1273 | 343 int i; |
2422 | 344 |
345 if(a->pb.buf_end - a->pb.buf - (put_bits_count(&a->pb)>>3) < 30*16*16*3/2/8){ | |
346 av_log(a->avctx, AV_LOG_ERROR, "encoded frame too large\n"); | |
347 return -1; | |
348 } | |
1273 | 349 |
1434 | 350 if(a->avctx->codec_id == CODEC_ID_ASV1){ |
351 for(i=0; i<6; i++) | |
352 asv1_encode_block(a, block[i]); | |
353 }else{ | |
354 for(i=0; i<6; i++) | |
355 asv2_encode_block(a, block[i]); | |
1273 | 356 } |
2422 | 357 return 0; |
1273 | 358 } |
1274
95061e8c5ea9
CONFIG_ENCODERS patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michaelni
parents:
1273
diff
changeset
|
359 |
1273 | 360 static inline void idct_put(ASV1Context *a, int mb_x, int mb_y){ |
361 DCTELEM (*block)[64]= a->block; | |
362 int linesize= a->picture.linesize[0]; | |
363 | |
364 uint8_t *dest_y = a->picture.data[0] + (mb_y * 16* linesize ) + mb_x * 16; | |
365 uint8_t *dest_cb = a->picture.data[1] + (mb_y * 8 * a->picture.linesize[1]) + mb_x * 8; | |
366 uint8_t *dest_cr = a->picture.data[2] + (mb_y * 8 * a->picture.linesize[2]) + mb_x * 8; | |
367 | |
368 a->dsp.idct_put(dest_y , linesize, block[0]); | |
369 a->dsp.idct_put(dest_y + 8, linesize, block[1]); | |
370 a->dsp.idct_put(dest_y + 8*linesize , linesize, block[2]); | |
371 a->dsp.idct_put(dest_y + 8*linesize + 8, linesize, block[3]); | |
372 | |
373 if(!(a->avctx->flags&CODEC_FLAG_GRAY)){ | |
374 a->dsp.idct_put(dest_cb, a->picture.linesize[1], block[4]); | |
375 a->dsp.idct_put(dest_cr, a->picture.linesize[2], block[5]); | |
376 } | |
377 } | |
378 | |
379 static inline void dct_get(ASV1Context *a, int mb_x, int mb_y){ | |
380 DCTELEM (*block)[64]= a->block; | |
381 int linesize= a->picture.linesize[0]; | |
382 int i; | |
383 | |
384 uint8_t *ptr_y = a->picture.data[0] + (mb_y * 16* linesize ) + mb_x * 16; | |
385 uint8_t *ptr_cb = a->picture.data[1] + (mb_y * 8 * a->picture.linesize[1]) + mb_x * 8; | |
386 uint8_t *ptr_cr = a->picture.data[2] + (mb_y * 8 * a->picture.linesize[2]) + mb_x * 8; | |
387 | |
388 a->dsp.get_pixels(block[0], ptr_y , linesize); | |
389 a->dsp.get_pixels(block[1], ptr_y + 8, linesize); | |
390 a->dsp.get_pixels(block[2], ptr_y + 8*linesize , linesize); | |
391 a->dsp.get_pixels(block[3], ptr_y + 8*linesize + 8, linesize); | |
392 for(i=0; i<4; i++) | |
393 a->dsp.fdct(block[i]); | |
394 | |
395 if(!(a->avctx->flags&CODEC_FLAG_GRAY)){ | |
396 a->dsp.get_pixels(block[4], ptr_cb, a->picture.linesize[1]); | |
397 a->dsp.get_pixels(block[5], ptr_cr, a->picture.linesize[2]); | |
398 for(i=4; i<6; i++) | |
399 a->dsp.fdct(block[i]); | |
400 } | |
401 } | |
402 | |
403 static int decode_frame(AVCodecContext *avctx, | |
404 void *data, int *data_size, | |
405 uint8_t *buf, int buf_size) | |
406 { | |
407 ASV1Context * const a = avctx->priv_data; | |
408 AVFrame *picture = data; | |
409 AVFrame * const p= (AVFrame*)&a->picture; | |
410 int mb_x, mb_y; | |
411 | |
412 if(p->data[0]) | |
413 avctx->release_buffer(avctx, p); | |
414 | |
415 p->reference= 0; | |
416 if(avctx->get_buffer(avctx, p) < 0){ | |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1522
diff
changeset
|
417 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); |
1273 | 418 return -1; |
419 } | |
420 p->pict_type= I_TYPE; | |
421 p->key_frame= 1; | |
422 | |
423 a->bitstream_buffer= av_fast_realloc(a->bitstream_buffer, &a->bitstream_buffer_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); | |
1433 | 424 |
425 if(avctx->codec_id == CODEC_ID_ASV1) | |
426 a->dsp.bswap_buf((uint32_t*)a->bitstream_buffer, (uint32_t*)buf, buf_size/4); | |
427 else{ | |
428 int i; | |
429 for(i=0; i<buf_size; i++) | |
430 a->bitstream_buffer[i]= reverse[ buf[i] ]; | |
431 } | |
432 | |
1273 | 433 init_get_bits(&a->gb, a->bitstream_buffer, buf_size*8); |
434 | |
435 for(mb_y=0; mb_y<a->mb_height2; mb_y++){ | |
436 for(mb_x=0; mb_x<a->mb_width2; mb_x++){ | |
437 if( decode_mb(a, a->block) <0) | |
438 return -1; | |
439 | |
440 idct_put(a, mb_x, mb_y); | |
441 } | |
442 } | |
443 | |
444 if(a->mb_width2 != a->mb_width){ | |
445 mb_x= a->mb_width2; | |
446 for(mb_y=0; mb_y<a->mb_height2; mb_y++){ | |
447 if( decode_mb(a, a->block) <0) | |
448 return -1; | |
449 | |
450 idct_put(a, mb_x, mb_y); | |
451 } | |
452 } | |
453 | |
454 if(a->mb_height2 != a->mb_height){ | |
455 mb_y= a->mb_height2; | |
456 for(mb_x=0; mb_x<a->mb_width; mb_x++){ | |
457 if( decode_mb(a, a->block) <0) | |
458 return -1; | |
459 | |
460 idct_put(a, mb_x, mb_y); | |
461 } | |
462 } | |
463 #if 0 | |
464 int i; | |
465 printf("%d %d\n", 8*buf_size, get_bits_count(&a->gb)); | |
466 for(i=get_bits_count(&a->gb); i<8*buf_size; i++){ | |
467 printf("%d", get_bits1(&a->gb)); | |
468 } | |
469 | |
470 for(i=0; i<s->avctx->extradata_size; i++){ | |
471 printf("%c\n", ((uint8_t*)s->avctx->extradata)[i]); | |
472 } | |
473 #endif | |
474 | |
475 *picture= *(AVFrame*)&a->picture; | |
476 *data_size = sizeof(AVPicture); | |
477 | |
478 emms_c(); | |
479 | |
480 return (get_bits_count(&a->gb)+31)/32*4; | |
481 } | |
482 | |
483 static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ | |
484 ASV1Context * const a = avctx->priv_data; | |
485 AVFrame *pict = data; | |
486 AVFrame * const p= (AVFrame*)&a->picture; | |
487 int size; | |
488 int mb_x, mb_y; | |
489 | |
1522
79dddc5cd990
removed the obsolete and unused parameters of init_put_bits
alex
parents:
1434
diff
changeset
|
490 init_put_bits(&a->pb, buf, buf_size); |
1273 | 491 |
492 *p = *pict; | |
493 p->pict_type= I_TYPE; | |
494 p->key_frame= 1; | |
495 | |
496 for(mb_y=0; mb_y<a->mb_height2; mb_y++){ | |
497 for(mb_x=0; mb_x<a->mb_width2; mb_x++){ | |
498 dct_get(a, mb_x, mb_y); | |
499 encode_mb(a, a->block); | |
500 } | |
501 } | |
502 | |
503 if(a->mb_width2 != a->mb_width){ | |
504 mb_x= a->mb_width2; | |
505 for(mb_y=0; mb_y<a->mb_height2; mb_y++){ | |
506 dct_get(a, mb_x, mb_y); | |
507 encode_mb(a, a->block); | |
508 } | |
509 } | |
510 | |
511 if(a->mb_height2 != a->mb_height){ | |
512 mb_y= a->mb_height2; | |
513 for(mb_x=0; mb_x<a->mb_width; mb_x++){ | |
514 dct_get(a, mb_x, mb_y); | |
515 encode_mb(a, a->block); | |
516 } | |
517 } | |
518 emms_c(); | |
519 | |
520 align_put_bits(&a->pb); | |
1786 | 521 while(put_bits_count(&a->pb)&31) |
1273 | 522 put_bits(&a->pb, 8, 0); |
523 | |
1786 | 524 size= put_bits_count(&a->pb)/32; |
1273 | 525 |
1434 | 526 if(avctx->codec_id == CODEC_ID_ASV1) |
527 a->dsp.bswap_buf((uint32_t*)buf, (uint32_t*)buf, size); | |
528 else{ | |
529 int i; | |
530 for(i=0; i<4*size; i++) | |
531 buf[i]= reverse[ buf[i] ]; | |
532 } | |
1273 | 533 |
534 return size*4; | |
535 } | |
536 | |
537 static void common_init(AVCodecContext *avctx){ | |
538 ASV1Context * const a = avctx->priv_data; | |
539 | |
540 dsputil_init(&a->dsp, avctx); | |
541 | |
542 a->mb_width = (avctx->width + 15) / 16; | |
543 a->mb_height = (avctx->height + 15) / 16; | |
544 a->mb_width2 = (avctx->width + 0) / 16; | |
545 a->mb_height2 = (avctx->height + 0) / 16; | |
546 | |
547 avctx->coded_frame= (AVFrame*)&a->picture; | |
548 a->avctx= avctx; | |
549 } | |
550 | |
551 static int decode_init(AVCodecContext *avctx){ | |
552 ASV1Context * const a = avctx->priv_data; | |
553 AVFrame *p= (AVFrame*)&a->picture; | |
554 int i; | |
1434 | 555 const int scale= avctx->codec_id == CODEC_ID_ASV1 ? 1 : 2; |
1273 | 556 |
557 common_init(avctx); | |
558 init_vlcs(a); | |
559 ff_init_scantable(a->dsp.idct_permutation, &a->scantable, scantab); | |
560 | |
1433 | 561 a->inv_qscale= ((uint8_t*)avctx->extradata)[0]; |
1273 | 562 if(a->inv_qscale == 0){ |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1522
diff
changeset
|
563 av_log(avctx, AV_LOG_ERROR, "illegal qscale 0\n"); |
1433 | 564 if(avctx->codec_id == CODEC_ID_ASV1) |
565 a->inv_qscale= 6; | |
566 else | |
567 a->inv_qscale= 10; | |
1273 | 568 } |
569 | |
570 for(i=0; i<64; i++){ | |
571 int index= scantab[i]; | |
1433 | 572 |
1434 | 573 a->intra_matrix[i]= 64*scale*ff_mpeg1_default_intra_matrix[index] / a->inv_qscale; |
1273 | 574 } |
575 | |
576 p->qstride= a->mb_width; | |
2426
1ee03f2a6cd5
av_malloc vs av_mallocz patch by (Kurosu <kurosu inforezo org>)
michael
parents:
2422
diff
changeset
|
577 p->qscale_table= av_malloc( p->qstride * a->mb_height); |
1434 | 578 p->quality= (32*scale + a->inv_qscale/2)/a->inv_qscale; |
579 memset(p->qscale_table, p->quality, p->qstride*a->mb_height); | |
1273 | 580 |
581 return 0; | |
582 } | |
583 | |
584 static int encode_init(AVCodecContext *avctx){ | |
585 ASV1Context * const a = avctx->priv_data; | |
586 int i; | |
1434 | 587 const int scale= avctx->codec_id == CODEC_ID_ASV1 ? 1 : 2; |
588 | |
1273 | 589 common_init(avctx); |
590 | |
591 if(avctx->global_quality == 0) avctx->global_quality= 4*FF_QUALITY_SCALE; | |
592 | |
1434 | 593 a->inv_qscale= (32*scale*FF_QUALITY_SCALE + avctx->global_quality/2) / avctx->global_quality; |
1273 | 594 |
595 avctx->extradata= av_mallocz(8); | |
596 avctx->extradata_size=8; | |
597 ((uint32_t*)avctx->extradata)[0]= le2me_32(a->inv_qscale); | |
598 ((uint32_t*)avctx->extradata)[1]= le2me_32(ff_get_fourcc("ASUS")); | |
599 | |
600 for(i=0; i<64; i++){ | |
1434 | 601 int q= 32*scale*ff_mpeg1_default_intra_matrix[i]; |
1273 | 602 a->q_intra_matrix[i]= ((a->inv_qscale<<16) + q/2) / q; |
603 } | |
604 | |
605 return 0; | |
606 } | |
607 | |
608 static int decode_end(AVCodecContext *avctx){ | |
609 ASV1Context * const a = avctx->priv_data; | |
610 | |
611 av_freep(&a->bitstream_buffer); | |
612 av_freep(&a->picture.qscale_table); | |
613 a->bitstream_buffer_size=0; | |
614 | |
615 return 0; | |
616 } | |
617 | |
618 AVCodec asv1_decoder = { | |
619 "asv1", | |
620 CODEC_TYPE_VIDEO, | |
621 CODEC_ID_ASV1, | |
622 sizeof(ASV1Context), | |
623 decode_init, | |
624 NULL, | |
625 decode_end, | |
626 decode_frame, | |
627 CODEC_CAP_DR1, | |
628 }; | |
629 | |
1433 | 630 AVCodec asv2_decoder = { |
631 "asv2", | |
632 CODEC_TYPE_VIDEO, | |
633 CODEC_ID_ASV2, | |
634 sizeof(ASV1Context), | |
635 decode_init, | |
636 NULL, | |
637 decode_end, | |
638 decode_frame, | |
639 CODEC_CAP_DR1, | |
640 }; | |
641 | |
1274
95061e8c5ea9
CONFIG_ENCODERS patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michaelni
parents:
1273
diff
changeset
|
642 #ifdef CONFIG_ENCODERS |
95061e8c5ea9
CONFIG_ENCODERS patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michaelni
parents:
1273
diff
changeset
|
643 |
1273 | 644 AVCodec asv1_encoder = { |
645 "asv1", | |
646 CODEC_TYPE_VIDEO, | |
647 CODEC_ID_ASV1, | |
648 sizeof(ASV1Context), | |
649 encode_init, | |
650 encode_frame, | |
651 //encode_end, | |
652 }; | |
1274
95061e8c5ea9
CONFIG_ENCODERS patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michaelni
parents:
1273
diff
changeset
|
653 |
1434 | 654 AVCodec asv2_encoder = { |
655 "asv2", | |
656 CODEC_TYPE_VIDEO, | |
657 CODEC_ID_ASV2, | |
658 sizeof(ASV1Context), | |
659 encode_init, | |
660 encode_frame, | |
661 //encode_end, | |
662 }; | |
663 | |
1274
95061e8c5ea9
CONFIG_ENCODERS patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michaelni
parents:
1273
diff
changeset
|
664 #endif //CONFIG_ENCODERS |