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