Mercurial > libavcodec.hg
annotate asv1.c @ 5319:40af705cef7e libavcodec
AC-3 decoder, soc revision 69, Aug 31 07:12:56 2006 UTC by cloud9
Fix the bugs:
1. The quality of output because of incorrect windowing coefficients.
New code for window generation.
2. Dynrng values were reset where dynrng value is present in the first block,
but not in the subsequent block.
author | jbr |
---|---|
date | Sat, 14 Jul 2007 16:03:14 +0000 |
parents | c8c591fe26f8 |
children | 2bd6911a39c6 |
rev | line source |
---|---|
1273 | 1 /* |
1433 | 2 * ASUS V1/V2 codec |
1273 | 3 * Copyright (c) 2003 Michael Niedermayer |
4 * | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
5 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
6 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
1273 | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
1273 | 11 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
1273 | 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 | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
2967
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
1273 | 20 */ |
2967 | 21 |
1273 | 22 /** |
23 * @file asv1.c | |
1433 | 24 * ASUS V1/V2 codec. |
1273 | 25 */ |
2967 | 26 |
1273 | 27 #include "avcodec.h" |
28 #include "dsputil.h" | |
29 #include "mpegvideo.h" | |
30 | |
31 //#undef NDEBUG | |
32 //#include <assert.h> | |
33 | |
1433 | 34 #define VLC_BITS 6 |
35 #define ASV2_LEVEL_VLC_BITS 10 | |
2967 | 36 |
1273 | 37 typedef struct ASV1Context{ |
38 AVCodecContext *avctx; | |
39 DSPContext dsp; | |
40 AVFrame picture; | |
41 PutBitContext pb; | |
42 GetBitContext gb; | |
43 ScanTable scantable; | |
44 int inv_qscale; | |
45 int mb_width; | |
46 int mb_height; | |
47 int mb_width2; | |
48 int mb_height2; | |
3089 | 49 DECLARE_ALIGNED_8(DCTELEM, block[6][64]); |
50 DECLARE_ALIGNED_8(uint16_t, intra_matrix[64]); | |
51 DECLARE_ALIGNED_8(int, q_intra_matrix[64]); | |
1273 | 52 uint8_t *bitstream_buffer; |
3066
04b924f8f5a5
warning fixes by Luca Abeni, lucabe72 ##@## email ##.## it
diego
parents:
3036
diff
changeset
|
53 unsigned int bitstream_buffer_size; |
1273 | 54 } ASV1Context; |
55 | |
56 static const uint8_t scantab[64]={ | |
57 0x00,0x08,0x01,0x09,0x10,0x18,0x11,0x19, | |
58 0x02,0x0A,0x03,0x0B,0x12,0x1A,0x13,0x1B, | |
59 0x04,0x0C,0x05,0x0D,0x20,0x28,0x21,0x29, | |
60 0x06,0x0E,0x07,0x0F,0x14,0x1C,0x15,0x1D, | |
61 0x22,0x2A,0x23,0x2B,0x30,0x38,0x31,0x39, | |
1433 | 62 0x16,0x1E,0x17,0x1F,0x24,0x2C,0x25,0x2D, |
63 0x32,0x3A,0x33,0x3B,0x26,0x2E,0x27,0x2F, | |
64 0x34,0x3C,0x35,0x3D,0x36,0x3E,0x37,0x3F, | |
65 }; | |
66 | |
67 | |
1273 | 68 static const uint8_t ccp_tab[17][2]={ |
1433 | 69 {0x2,2}, {0x7,5}, {0xB,5}, {0x3,5}, |
70 {0xD,5}, {0x5,5}, {0x9,5}, {0x1,5}, | |
2967 | 71 {0xE,5}, {0x6,5}, {0xA,5}, {0x2,5}, |
1433 | 72 {0xC,5}, {0x4,5}, {0x8,5}, {0x3,2}, |
1273 | 73 {0xF,5}, //EOB |
74 }; | |
75 | |
76 static const uint8_t level_tab[7][2]={ | |
77 {3,4}, {3,3}, {3,2}, {0,3}, {2,2}, {2,3}, {2,4} | |
78 }; | |
79 | |
1433 | 80 static const uint8_t dc_ccp_tab[8][2]={ |
81 {0x1,2}, {0xD,4}, {0xF,4}, {0xC,4}, | |
82 {0x5,3}, {0xE,4}, {0x4,3}, {0x0,2}, | |
83 }; | |
84 | |
85 static const uint8_t ac_ccp_tab[16][2]={ | |
86 {0x00,2}, {0x3B,6}, {0x0A,4}, {0x3A,6}, | |
87 {0x02,3}, {0x39,6}, {0x3C,6}, {0x38,6}, | |
88 {0x03,3}, {0x3D,6}, {0x08,4}, {0x1F,5}, | |
89 {0x09,4}, {0x0B,4}, {0x0D,4}, {0x0C,4}, | |
90 }; | |
91 | |
92 static const uint8_t asv2_level_tab[63][2]={ | |
93 {0x3F,10},{0x2F,10},{0x37,10},{0x27,10},{0x3B,10},{0x2B,10},{0x33,10},{0x23,10}, | |
94 {0x3D,10},{0x2D,10},{0x35,10},{0x25,10},{0x39,10},{0x29,10},{0x31,10},{0x21,10}, | |
95 {0x1F, 8},{0x17, 8},{0x1B, 8},{0x13, 8},{0x1D, 8},{0x15, 8},{0x19, 8},{0x11, 8}, | |
96 {0x0F, 6},{0x0B, 6},{0x0D, 6},{0x09, 6}, | |
97 {0x07, 4},{0x05, 4}, | |
98 {0x03, 2}, | |
99 {0x00, 5}, | |
100 {0x02, 2}, | |
101 {0x04, 4},{0x06, 4}, | |
102 {0x08, 6},{0x0C, 6},{0x0A, 6},{0x0E, 6}, | |
103 {0x10, 8},{0x18, 8},{0x14, 8},{0x1C, 8},{0x12, 8},{0x1A, 8},{0x16, 8},{0x1E, 8}, | |
104 {0x20,10},{0x30,10},{0x28,10},{0x38,10},{0x24,10},{0x34,10},{0x2C,10},{0x3C,10}, | |
105 {0x22,10},{0x32,10},{0x2A,10},{0x3A,10},{0x26,10},{0x36,10},{0x2E,10},{0x3E,10}, | |
106 }; | |
107 | |
108 | |
1273 | 109 static VLC ccp_vlc; |
110 static VLC level_vlc; | |
1433 | 111 static VLC dc_ccp_vlc; |
112 static VLC ac_ccp_vlc; | |
113 static VLC asv2_level_vlc; | |
1273 | 114 |
115 static void init_vlcs(ASV1Context *a){ | |
116 static int done = 0; | |
117 | |
118 if (!done) { | |
119 done = 1; | |
120 | |
2967 | 121 init_vlc(&ccp_vlc, VLC_BITS, 17, |
1273 | 122 &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
|
123 &ccp_tab[0][0], 2, 1, 1); |
2967 | 124 init_vlc(&dc_ccp_vlc, VLC_BITS, 8, |
1433 | 125 &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
|
126 &dc_ccp_tab[0][0], 2, 1, 1); |
2967 | 127 init_vlc(&ac_ccp_vlc, VLC_BITS, 16, |
1433 | 128 &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
|
129 &ac_ccp_tab[0][0], 2, 1, 1); |
2967 | 130 init_vlc(&level_vlc, VLC_BITS, 7, |
1273 | 131 &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
|
132 &level_tab[0][0], 2, 1, 1); |
2967 | 133 init_vlc(&asv2_level_vlc, ASV2_LEVEL_VLC_BITS, 63, |
1433 | 134 &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
|
135 &asv2_level_tab[0][0], 2, 1, 1); |
1273 | 136 } |
137 } | |
138 | |
1433 | 139 //FIXME write a reversed bitstream reader to avoid the double reverse |
140 static inline int asv2_get_bits(GetBitContext *gb, int n){ | |
2578 | 141 return ff_reverse[ get_bits(gb, n) << (8-n) ]; |
1433 | 142 } |
143 | |
1434 | 144 static inline void asv2_put_bits(PutBitContext *pb, int n, int v){ |
2578 | 145 put_bits(pb, n, ff_reverse[ v << (8-n) ]); |
1434 | 146 } |
147 | |
1433 | 148 static inline int asv1_get_level(GetBitContext *gb){ |
1273 | 149 int code= get_vlc2(gb, level_vlc.table, VLC_BITS, 1); |
150 | |
151 if(code==3) return get_sbits(gb, 8); | |
152 else return code - 3; | |
153 } | |
154 | |
1433 | 155 static inline int asv2_get_level(GetBitContext *gb){ |
156 int code= get_vlc2(gb, asv2_level_vlc.table, ASV2_LEVEL_VLC_BITS, 1); | |
157 | |
158 if(code==31) return (int8_t)asv2_get_bits(gb, 8); | |
159 else return code - 31; | |
160 } | |
161 | |
162 static inline void asv1_put_level(PutBitContext *pb, int level){ | |
1273 | 163 unsigned int index= level + 3; |
164 | |
165 if(index <= 6) put_bits(pb, level_tab[index][1], level_tab[index][0]); | |
166 else{ | |
167 put_bits(pb, level_tab[3][1], level_tab[3][0]); | |
168 put_bits(pb, 8, level&0xFF); | |
169 } | |
170 } | |
171 | |
1434 | 172 static inline void asv2_put_level(PutBitContext *pb, int level){ |
173 unsigned int index= level + 31; | |
174 | |
175 if(index <= 62) put_bits(pb, asv2_level_tab[index][1], asv2_level_tab[index][0]); | |
176 else{ | |
177 put_bits(pb, asv2_level_tab[31][1], asv2_level_tab[31][0]); | |
178 asv2_put_bits(pb, 8, level&0xFF); | |
179 } | |
180 } | |
181 | |
1433 | 182 static inline int asv1_decode_block(ASV1Context *a, DCTELEM block[64]){ |
1273 | 183 int i; |
184 | |
185 block[0]= 8*get_bits(&a->gb, 8); | |
2967 | 186 |
1273 | 187 for(i=0; i<11; i++){ |
188 const int ccp= get_vlc2(&a->gb, ccp_vlc.table, VLC_BITS, 1); | |
189 | |
190 if(ccp){ | |
191 if(ccp == 16) break; | |
192 if(ccp < 0 || i>=10){ | |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1522
diff
changeset
|
193 av_log(a->avctx, AV_LOG_ERROR, "coded coeff pattern damaged\n"); |
1273 | 194 return -1; |
195 } | |
196 | |
1433 | 197 if(ccp&8) block[a->scantable.permutated[4*i+0]]= (asv1_get_level(&a->gb) * a->intra_matrix[4*i+0])>>4; |
198 if(ccp&4) block[a->scantable.permutated[4*i+1]]= (asv1_get_level(&a->gb) * a->intra_matrix[4*i+1])>>4; | |
199 if(ccp&2) block[a->scantable.permutated[4*i+2]]= (asv1_get_level(&a->gb) * a->intra_matrix[4*i+2])>>4; | |
200 if(ccp&1) block[a->scantable.permutated[4*i+3]]= (asv1_get_level(&a->gb) * a->intra_matrix[4*i+3])>>4; | |
1273 | 201 } |
202 } | |
203 | |
204 return 0; | |
205 } | |
206 | |
1433 | 207 static inline int asv2_decode_block(ASV1Context *a, DCTELEM block[64]){ |
208 int i, count, ccp; | |
209 | |
210 count= asv2_get_bits(&a->gb, 4); | |
2967 | 211 |
1433 | 212 block[0]= 8*asv2_get_bits(&a->gb, 8); |
2967 | 213 |
1433 | 214 ccp= get_vlc2(&a->gb, dc_ccp_vlc.table, VLC_BITS, 1); |
215 if(ccp){ | |
216 if(ccp&4) block[a->scantable.permutated[1]]= (asv2_get_level(&a->gb) * a->intra_matrix[1])>>4; | |
217 if(ccp&2) block[a->scantable.permutated[2]]= (asv2_get_level(&a->gb) * a->intra_matrix[2])>>4; | |
218 if(ccp&1) block[a->scantable.permutated[3]]= (asv2_get_level(&a->gb) * a->intra_matrix[3])>>4; | |
219 } | |
220 | |
221 for(i=1; i<count+1; i++){ | |
222 const int ccp= get_vlc2(&a->gb, ac_ccp_vlc.table, VLC_BITS, 1); | |
223 | |
224 if(ccp){ | |
225 if(ccp&8) block[a->scantable.permutated[4*i+0]]= (asv2_get_level(&a->gb) * a->intra_matrix[4*i+0])>>4; | |
226 if(ccp&4) block[a->scantable.permutated[4*i+1]]= (asv2_get_level(&a->gb) * a->intra_matrix[4*i+1])>>4; | |
227 if(ccp&2) block[a->scantable.permutated[4*i+2]]= (asv2_get_level(&a->gb) * a->intra_matrix[4*i+2])>>4; | |
228 if(ccp&1) block[a->scantable.permutated[4*i+3]]= (asv2_get_level(&a->gb) * a->intra_matrix[4*i+3])>>4; | |
229 } | |
230 } | |
2967 | 231 |
1433 | 232 return 0; |
233 } | |
234 | |
1434 | 235 static inline void asv1_encode_block(ASV1Context *a, DCTELEM block[64]){ |
1273 | 236 int i; |
237 int nc_count=0; | |
2967 | 238 |
1273 | 239 put_bits(&a->pb, 8, (block[0] + 32)>>6); |
240 block[0]= 0; | |
2967 | 241 |
1273 | 242 for(i=0; i<10; i++){ |
243 const int index= scantab[4*i]; | |
244 int ccp=0; | |
245 | |
1433 | 246 if( (block[index + 0] = (block[index + 0]*a->q_intra_matrix[index + 0] + (1<<15))>>16) ) ccp |= 8; |
247 if( (block[index + 8] = (block[index + 8]*a->q_intra_matrix[index + 8] + (1<<15))>>16) ) ccp |= 4; | |
248 if( (block[index + 1] = (block[index + 1]*a->q_intra_matrix[index + 1] + (1<<15))>>16) ) ccp |= 2; | |
249 if( (block[index + 9] = (block[index + 9]*a->q_intra_matrix[index + 9] + (1<<15))>>16) ) ccp |= 1; | |
1273 | 250 |
251 if(ccp){ | |
2967 | 252 for(;nc_count; nc_count--) |
1273 | 253 put_bits(&a->pb, ccp_tab[0][1], ccp_tab[0][0]); |
254 | |
255 put_bits(&a->pb, ccp_tab[ccp][1], ccp_tab[ccp][0]); | |
2967 | 256 |
1433 | 257 if(ccp&8) asv1_put_level(&a->pb, block[index + 0]); |
258 if(ccp&4) asv1_put_level(&a->pb, block[index + 8]); | |
259 if(ccp&2) asv1_put_level(&a->pb, block[index + 1]); | |
260 if(ccp&1) asv1_put_level(&a->pb, block[index + 9]); | |
1273 | 261 }else{ |
262 nc_count++; | |
263 } | |
264 } | |
265 put_bits(&a->pb, ccp_tab[16][1], ccp_tab[16][0]); | |
266 } | |
267 | |
1434 | 268 static inline void asv2_encode_block(ASV1Context *a, DCTELEM block[64]){ |
269 int i; | |
270 int count=0; | |
2967 | 271 |
1434 | 272 for(count=63; count>3; count--){ |
273 const int index= scantab[count]; | |
274 | |
2967 | 275 if( (block[index]*a->q_intra_matrix[index] + (1<<15))>>16 ) |
1434 | 276 break; |
277 } | |
2967 | 278 |
1434 | 279 count >>= 2; |
280 | |
281 asv2_put_bits(&a->pb, 4, count); | |
282 asv2_put_bits(&a->pb, 8, (block[0] + 32)>>6); | |
283 block[0]= 0; | |
2967 | 284 |
1434 | 285 for(i=0; i<=count; i++){ |
286 const int index= scantab[4*i]; | |
287 int ccp=0; | |
288 | |
289 if( (block[index + 0] = (block[index + 0]*a->q_intra_matrix[index + 0] + (1<<15))>>16) ) ccp |= 8; | |
290 if( (block[index + 8] = (block[index + 8]*a->q_intra_matrix[index + 8] + (1<<15))>>16) ) ccp |= 4; | |
291 if( (block[index + 1] = (block[index + 1]*a->q_intra_matrix[index + 1] + (1<<15))>>16) ) ccp |= 2; | |
292 if( (block[index + 9] = (block[index + 9]*a->q_intra_matrix[index + 9] + (1<<15))>>16) ) ccp |= 1; | |
293 | |
3183
8e00b10aeb0a
add assert to clarify that we know what we are doing
michael
parents:
3089
diff
changeset
|
294 assert(i || ccp<8); |
1434 | 295 if(i) put_bits(&a->pb, ac_ccp_tab[ccp][1], ac_ccp_tab[ccp][0]); |
296 else put_bits(&a->pb, dc_ccp_tab[ccp][1], dc_ccp_tab[ccp][0]); | |
297 | |
298 if(ccp){ | |
299 if(ccp&8) asv2_put_level(&a->pb, block[index + 0]); | |
300 if(ccp&4) asv2_put_level(&a->pb, block[index + 8]); | |
301 if(ccp&2) asv2_put_level(&a->pb, block[index + 1]); | |
302 if(ccp&1) asv2_put_level(&a->pb, block[index + 9]); | |
303 } | |
304 } | |
305 } | |
306 | |
1273 | 307 static inline int decode_mb(ASV1Context *a, DCTELEM block[6][64]){ |
308 int i; | |
309 | |
310 a->dsp.clear_blocks(block[0]); | |
2967 | 311 |
1433 | 312 if(a->avctx->codec_id == CODEC_ID_ASV1){ |
313 for(i=0; i<6; i++){ | |
2967 | 314 if( asv1_decode_block(a, block[i]) < 0) |
1433 | 315 return -1; |
316 } | |
317 }else{ | |
318 for(i=0; i<6; i++){ | |
2967 | 319 if( asv2_decode_block(a, block[i]) < 0) |
1433 | 320 return -1; |
321 } | |
1273 | 322 } |
323 return 0; | |
324 } | |
325 | |
2422 | 326 static inline int encode_mb(ASV1Context *a, DCTELEM block[6][64]){ |
1273 | 327 int i; |
2967 | 328 |
2422 | 329 if(a->pb.buf_end - a->pb.buf - (put_bits_count(&a->pb)>>3) < 30*16*16*3/2/8){ |
330 av_log(a->avctx, AV_LOG_ERROR, "encoded frame too large\n"); | |
331 return -1; | |
332 } | |
1273 | 333 |
1434 | 334 if(a->avctx->codec_id == CODEC_ID_ASV1){ |
335 for(i=0; i<6; i++) | |
336 asv1_encode_block(a, block[i]); | |
337 }else{ | |
338 for(i=0; i<6; i++) | |
339 asv2_encode_block(a, block[i]); | |
1273 | 340 } |
2422 | 341 return 0; |
1273 | 342 } |
1274
95061e8c5ea9
CONFIG_ENCODERS patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michaelni
parents:
1273
diff
changeset
|
343 |
1273 | 344 static inline void idct_put(ASV1Context *a, int mb_x, int mb_y){ |
345 DCTELEM (*block)[64]= a->block; | |
346 int linesize= a->picture.linesize[0]; | |
2967 | 347 |
1273 | 348 uint8_t *dest_y = a->picture.data[0] + (mb_y * 16* linesize ) + mb_x * 16; |
349 uint8_t *dest_cb = a->picture.data[1] + (mb_y * 8 * a->picture.linesize[1]) + mb_x * 8; | |
350 uint8_t *dest_cr = a->picture.data[2] + (mb_y * 8 * a->picture.linesize[2]) + mb_x * 8; | |
351 | |
352 a->dsp.idct_put(dest_y , linesize, block[0]); | |
353 a->dsp.idct_put(dest_y + 8, linesize, block[1]); | |
354 a->dsp.idct_put(dest_y + 8*linesize , linesize, block[2]); | |
355 a->dsp.idct_put(dest_y + 8*linesize + 8, linesize, block[3]); | |
356 | |
357 if(!(a->avctx->flags&CODEC_FLAG_GRAY)){ | |
358 a->dsp.idct_put(dest_cb, a->picture.linesize[1], block[4]); | |
359 a->dsp.idct_put(dest_cr, a->picture.linesize[2], block[5]); | |
360 } | |
361 } | |
362 | |
363 static inline void dct_get(ASV1Context *a, int mb_x, int mb_y){ | |
364 DCTELEM (*block)[64]= a->block; | |
365 int linesize= a->picture.linesize[0]; | |
366 int i; | |
2967 | 367 |
1273 | 368 uint8_t *ptr_y = a->picture.data[0] + (mb_y * 16* linesize ) + mb_x * 16; |
369 uint8_t *ptr_cb = a->picture.data[1] + (mb_y * 8 * a->picture.linesize[1]) + mb_x * 8; | |
370 uint8_t *ptr_cr = a->picture.data[2] + (mb_y * 8 * a->picture.linesize[2]) + mb_x * 8; | |
371 | |
372 a->dsp.get_pixels(block[0], ptr_y , linesize); | |
373 a->dsp.get_pixels(block[1], ptr_y + 8, linesize); | |
374 a->dsp.get_pixels(block[2], ptr_y + 8*linesize , linesize); | |
375 a->dsp.get_pixels(block[3], ptr_y + 8*linesize + 8, linesize); | |
376 for(i=0; i<4; i++) | |
377 a->dsp.fdct(block[i]); | |
2967 | 378 |
1273 | 379 if(!(a->avctx->flags&CODEC_FLAG_GRAY)){ |
380 a->dsp.get_pixels(block[4], ptr_cb, a->picture.linesize[1]); | |
381 a->dsp.get_pixels(block[5], ptr_cr, a->picture.linesize[2]); | |
382 for(i=4; i<6; i++) | |
383 a->dsp.fdct(block[i]); | |
384 } | |
385 } | |
386 | |
2967 | 387 static int decode_frame(AVCodecContext *avctx, |
1273 | 388 void *data, int *data_size, |
389 uint8_t *buf, int buf_size) | |
390 { | |
391 ASV1Context * const a = avctx->priv_data; | |
392 AVFrame *picture = data; | |
393 AVFrame * const p= (AVFrame*)&a->picture; | |
394 int mb_x, mb_y; | |
395 | |
396 if(p->data[0]) | |
397 avctx->release_buffer(avctx, p); | |
398 | |
399 p->reference= 0; | |
400 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
|
401 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); |
1273 | 402 return -1; |
403 } | |
404 p->pict_type= I_TYPE; | |
405 p->key_frame= 1; | |
406 | |
407 a->bitstream_buffer= av_fast_realloc(a->bitstream_buffer, &a->bitstream_buffer_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); | |
2967 | 408 |
1433 | 409 if(avctx->codec_id == CODEC_ID_ASV1) |
410 a->dsp.bswap_buf((uint32_t*)a->bitstream_buffer, (uint32_t*)buf, buf_size/4); | |
411 else{ | |
412 int i; | |
413 for(i=0; i<buf_size; i++) | |
2578 | 414 a->bitstream_buffer[i]= ff_reverse[ buf[i] ]; |
1433 | 415 } |
416 | |
1273 | 417 init_get_bits(&a->gb, a->bitstream_buffer, buf_size*8); |
418 | |
419 for(mb_y=0; mb_y<a->mb_height2; mb_y++){ | |
420 for(mb_x=0; mb_x<a->mb_width2; mb_x++){ | |
421 if( decode_mb(a, a->block) <0) | |
422 return -1; | |
2967 | 423 |
1273 | 424 idct_put(a, mb_x, mb_y); |
425 } | |
426 } | |
427 | |
428 if(a->mb_width2 != a->mb_width){ | |
429 mb_x= a->mb_width2; | |
430 for(mb_y=0; mb_y<a->mb_height2; mb_y++){ | |
431 if( decode_mb(a, a->block) <0) | |
432 return -1; | |
2967 | 433 |
1273 | 434 idct_put(a, mb_x, mb_y); |
435 } | |
436 } | |
437 | |
438 if(a->mb_height2 != a->mb_height){ | |
439 mb_y= a->mb_height2; | |
440 for(mb_x=0; mb_x<a->mb_width; mb_x++){ | |
441 if( decode_mb(a, a->block) <0) | |
442 return -1; | |
2967 | 443 |
1273 | 444 idct_put(a, mb_x, mb_y); |
445 } | |
446 } | |
2967 | 447 #if 0 |
1273 | 448 int i; |
449 printf("%d %d\n", 8*buf_size, get_bits_count(&a->gb)); | |
450 for(i=get_bits_count(&a->gb); i<8*buf_size; i++){ | |
451 printf("%d", get_bits1(&a->gb)); | |
452 } | |
453 | |
454 for(i=0; i<s->avctx->extradata_size; i++){ | |
455 printf("%c\n", ((uint8_t*)s->avctx->extradata)[i]); | |
456 } | |
457 #endif | |
458 | |
459 *picture= *(AVFrame*)&a->picture; | |
460 *data_size = sizeof(AVPicture); | |
461 | |
462 emms_c(); | |
2967 | 463 |
1273 | 464 return (get_bits_count(&a->gb)+31)/32*4; |
465 } | |
466 | |
3777 | 467 #ifdef CONFIG_ENCODERS |
1273 | 468 static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ |
469 ASV1Context * const a = avctx->priv_data; | |
470 AVFrame *pict = data; | |
471 AVFrame * const p= (AVFrame*)&a->picture; | |
472 int size; | |
473 int mb_x, mb_y; | |
474 | |
1522
79dddc5cd990
removed the obsolete and unused parameters of init_put_bits
alex
parents:
1434
diff
changeset
|
475 init_put_bits(&a->pb, buf, buf_size); |
2967 | 476 |
1273 | 477 *p = *pict; |
478 p->pict_type= I_TYPE; | |
479 p->key_frame= 1; | |
480 | |
481 for(mb_y=0; mb_y<a->mb_height2; mb_y++){ | |
482 for(mb_x=0; mb_x<a->mb_width2; mb_x++){ | |
483 dct_get(a, mb_x, mb_y); | |
484 encode_mb(a, a->block); | |
485 } | |
486 } | |
487 | |
488 if(a->mb_width2 != a->mb_width){ | |
489 mb_x= a->mb_width2; | |
490 for(mb_y=0; mb_y<a->mb_height2; mb_y++){ | |
491 dct_get(a, mb_x, mb_y); | |
492 encode_mb(a, a->block); | |
493 } | |
494 } | |
495 | |
496 if(a->mb_height2 != a->mb_height){ | |
497 mb_y= a->mb_height2; | |
498 for(mb_x=0; mb_x<a->mb_width; mb_x++){ | |
499 dct_get(a, mb_x, mb_y); | |
500 encode_mb(a, a->block); | |
501 } | |
502 } | |
503 emms_c(); | |
2967 | 504 |
1273 | 505 align_put_bits(&a->pb); |
1786 | 506 while(put_bits_count(&a->pb)&31) |
1273 | 507 put_bits(&a->pb, 8, 0); |
2967 | 508 |
1786 | 509 size= put_bits_count(&a->pb)/32; |
2967 | 510 |
1434 | 511 if(avctx->codec_id == CODEC_ID_ASV1) |
512 a->dsp.bswap_buf((uint32_t*)buf, (uint32_t*)buf, size); | |
513 else{ | |
514 int i; | |
515 for(i=0; i<4*size; i++) | |
2578 | 516 buf[i]= ff_reverse[ buf[i] ]; |
1434 | 517 } |
2967 | 518 |
1273 | 519 return size*4; |
520 } | |
3777 | 521 #endif /* CONFIG_ENCODERS */ |
1273 | 522 |
523 static void common_init(AVCodecContext *avctx){ | |
524 ASV1Context * const a = avctx->priv_data; | |
525 | |
526 dsputil_init(&a->dsp, avctx); | |
527 | |
528 a->mb_width = (avctx->width + 15) / 16; | |
529 a->mb_height = (avctx->height + 15) / 16; | |
530 a->mb_width2 = (avctx->width + 0) / 16; | |
531 a->mb_height2 = (avctx->height + 0) / 16; | |
532 | |
533 avctx->coded_frame= (AVFrame*)&a->picture; | |
534 a->avctx= avctx; | |
535 } | |
536 | |
537 static int decode_init(AVCodecContext *avctx){ | |
538 ASV1Context * const a = avctx->priv_data; | |
539 AVFrame *p= (AVFrame*)&a->picture; | |
540 int i; | |
1434 | 541 const int scale= avctx->codec_id == CODEC_ID_ASV1 ? 1 : 2; |
2967 | 542 |
1273 | 543 common_init(avctx); |
544 init_vlcs(a); | |
545 ff_init_scantable(a->dsp.idct_permutation, &a->scantable, scantab); | |
2635 | 546 avctx->pix_fmt= PIX_FMT_YUV420P; |
1273 | 547 |
1433 | 548 a->inv_qscale= ((uint8_t*)avctx->extradata)[0]; |
1273 | 549 if(a->inv_qscale == 0){ |
1598
932d306bf1dc
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1522
diff
changeset
|
550 av_log(avctx, AV_LOG_ERROR, "illegal qscale 0\n"); |
1433 | 551 if(avctx->codec_id == CODEC_ID_ASV1) |
552 a->inv_qscale= 6; | |
553 else | |
554 a->inv_qscale= 10; | |
1273 | 555 } |
556 | |
557 for(i=0; i<64; i++){ | |
558 int index= scantab[i]; | |
1433 | 559 |
1434 | 560 a->intra_matrix[i]= 64*scale*ff_mpeg1_default_intra_matrix[index] / a->inv_qscale; |
1273 | 561 } |
562 | |
563 p->qstride= a->mb_width; | |
2426
1ee03f2a6cd5
av_malloc vs av_mallocz patch by (Kurosu <kurosu inforezo org>)
michael
parents:
2422
diff
changeset
|
564 p->qscale_table= av_malloc( p->qstride * a->mb_height); |
1434 | 565 p->quality= (32*scale + a->inv_qscale/2)/a->inv_qscale; |
566 memset(p->qscale_table, p->quality, p->qstride*a->mb_height); | |
1273 | 567 |
568 return 0; | |
569 } | |
570 | |
3777 | 571 #ifdef CONFIG_ENCODERS |
1273 | 572 static int encode_init(AVCodecContext *avctx){ |
573 ASV1Context * const a = avctx->priv_data; | |
574 int i; | |
1434 | 575 const int scale= avctx->codec_id == CODEC_ID_ASV1 ? 1 : 2; |
576 | |
1273 | 577 common_init(avctx); |
2967 | 578 |
1273 | 579 if(avctx->global_quality == 0) avctx->global_quality= 4*FF_QUALITY_SCALE; |
580 | |
1434 | 581 a->inv_qscale= (32*scale*FF_QUALITY_SCALE + avctx->global_quality/2) / avctx->global_quality; |
2967 | 582 |
1273 | 583 avctx->extradata= av_mallocz(8); |
584 avctx->extradata_size=8; | |
585 ((uint32_t*)avctx->extradata)[0]= le2me_32(a->inv_qscale); | |
586 ((uint32_t*)avctx->extradata)[1]= le2me_32(ff_get_fourcc("ASUS")); | |
2967 | 587 |
1273 | 588 for(i=0; i<64; i++){ |
1434 | 589 int q= 32*scale*ff_mpeg1_default_intra_matrix[i]; |
1273 | 590 a->q_intra_matrix[i]= ((a->inv_qscale<<16) + q/2) / q; |
591 } | |
592 | |
593 return 0; | |
594 } | |
3777 | 595 #endif |
1273 | 596 |
597 static int decode_end(AVCodecContext *avctx){ | |
598 ASV1Context * const a = avctx->priv_data; | |
599 | |
600 av_freep(&a->bitstream_buffer); | |
601 av_freep(&a->picture.qscale_table); | |
602 a->bitstream_buffer_size=0; | |
2967 | 603 |
1273 | 604 return 0; |
605 } | |
606 | |
607 AVCodec asv1_decoder = { | |
608 "asv1", | |
609 CODEC_TYPE_VIDEO, | |
610 CODEC_ID_ASV1, | |
611 sizeof(ASV1Context), | |
612 decode_init, | |
613 NULL, | |
614 decode_end, | |
615 decode_frame, | |
616 CODEC_CAP_DR1, | |
617 }; | |
618 | |
1433 | 619 AVCodec asv2_decoder = { |
620 "asv2", | |
621 CODEC_TYPE_VIDEO, | |
622 CODEC_ID_ASV2, | |
623 sizeof(ASV1Context), | |
624 decode_init, | |
625 NULL, | |
626 decode_end, | |
627 decode_frame, | |
628 CODEC_CAP_DR1, | |
629 }; | |
630 | |
1274
95061e8c5ea9
CONFIG_ENCODERS patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michaelni
parents:
1273
diff
changeset
|
631 #ifdef CONFIG_ENCODERS |
95061e8c5ea9
CONFIG_ENCODERS patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michaelni
parents:
1273
diff
changeset
|
632 |
1273 | 633 AVCodec asv1_encoder = { |
634 "asv1", | |
635 CODEC_TYPE_VIDEO, | |
636 CODEC_ID_ASV1, | |
637 sizeof(ASV1Context), | |
638 encode_init, | |
639 encode_frame, | |
640 //encode_end, | |
3740
0082fb8c77b6
set supported pixel formats for a few encoders (fixes crashes with grayscale)
michael
parents:
3183
diff
changeset
|
641 .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1}, |
1273 | 642 }; |
1274
95061e8c5ea9
CONFIG_ENCODERS patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michaelni
parents:
1273
diff
changeset
|
643 |
1434 | 644 AVCodec asv2_encoder = { |
645 "asv2", | |
646 CODEC_TYPE_VIDEO, | |
647 CODEC_ID_ASV2, | |
648 sizeof(ASV1Context), | |
649 encode_init, | |
650 encode_frame, | |
651 //encode_end, | |
3740
0082fb8c77b6
set supported pixel formats for a few encoders (fixes crashes with grayscale)
michael
parents:
3183
diff
changeset
|
652 .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1}, |
1434 | 653 }; |
654 | |
1274
95061e8c5ea9
CONFIG_ENCODERS patch by (Wolfgang Hesseler <qv at multimediaware dot com>)
michaelni
parents:
1273
diff
changeset
|
655 #endif //CONFIG_ENCODERS |