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