Libav 0.7.1
|
00001 /* 00002 * ASUS V1/V2 codec 00003 * Copyright (c) 2003 Michael Niedermayer 00004 * 00005 * This file is part of Libav. 00006 * 00007 * Libav is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * Libav is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with Libav; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00027 #include "avcodec.h" 00028 #include "libavutil/common.h" 00029 #include "put_bits.h" 00030 #include "dsputil.h" 00031 #include "mpeg12data.h" 00032 00033 //#undef NDEBUG 00034 //#include <assert.h> 00035 00036 #define VLC_BITS 6 00037 #define ASV2_LEVEL_VLC_BITS 10 00038 00039 typedef struct ASV1Context{ 00040 AVCodecContext *avctx; 00041 DSPContext dsp; 00042 AVFrame picture; 00043 PutBitContext pb; 00044 GetBitContext gb; 00045 ScanTable scantable; 00046 int inv_qscale; 00047 int mb_width; 00048 int mb_height; 00049 int mb_width2; 00050 int mb_height2; 00051 DECLARE_ALIGNED(16, DCTELEM, block)[6][64]; 00052 uint16_t intra_matrix[64]; 00053 int q_intra_matrix[64]; 00054 uint8_t *bitstream_buffer; 00055 unsigned int bitstream_buffer_size; 00056 } ASV1Context; 00057 00058 static const uint8_t scantab[64]={ 00059 0x00,0x08,0x01,0x09,0x10,0x18,0x11,0x19, 00060 0x02,0x0A,0x03,0x0B,0x12,0x1A,0x13,0x1B, 00061 0x04,0x0C,0x05,0x0D,0x20,0x28,0x21,0x29, 00062 0x06,0x0E,0x07,0x0F,0x14,0x1C,0x15,0x1D, 00063 0x22,0x2A,0x23,0x2B,0x30,0x38,0x31,0x39, 00064 0x16,0x1E,0x17,0x1F,0x24,0x2C,0x25,0x2D, 00065 0x32,0x3A,0x33,0x3B,0x26,0x2E,0x27,0x2F, 00066 0x34,0x3C,0x35,0x3D,0x36,0x3E,0x37,0x3F, 00067 }; 00068 00069 00070 static const uint8_t ccp_tab[17][2]={ 00071 {0x2,2}, {0x7,5}, {0xB,5}, {0x3,5}, 00072 {0xD,5}, {0x5,5}, {0x9,5}, {0x1,5}, 00073 {0xE,5}, {0x6,5}, {0xA,5}, {0x2,5}, 00074 {0xC,5}, {0x4,5}, {0x8,5}, {0x3,2}, 00075 {0xF,5}, //EOB 00076 }; 00077 00078 static const uint8_t level_tab[7][2]={ 00079 {3,4}, {3,3}, {3,2}, {0,3}, {2,2}, {2,3}, {2,4} 00080 }; 00081 00082 static const uint8_t dc_ccp_tab[8][2]={ 00083 {0x1,2}, {0xD,4}, {0xF,4}, {0xC,4}, 00084 {0x5,3}, {0xE,4}, {0x4,3}, {0x0,2}, 00085 }; 00086 00087 static const uint8_t ac_ccp_tab[16][2]={ 00088 {0x00,2}, {0x3B,6}, {0x0A,4}, {0x3A,6}, 00089 {0x02,3}, {0x39,6}, {0x3C,6}, {0x38,6}, 00090 {0x03,3}, {0x3D,6}, {0x08,4}, {0x1F,5}, 00091 {0x09,4}, {0x0B,4}, {0x0D,4}, {0x0C,4}, 00092 }; 00093 00094 static const uint8_t asv2_level_tab[63][2]={ 00095 {0x3F,10},{0x2F,10},{0x37,10},{0x27,10},{0x3B,10},{0x2B,10},{0x33,10},{0x23,10}, 00096 {0x3D,10},{0x2D,10},{0x35,10},{0x25,10},{0x39,10},{0x29,10},{0x31,10},{0x21,10}, 00097 {0x1F, 8},{0x17, 8},{0x1B, 8},{0x13, 8},{0x1D, 8},{0x15, 8},{0x19, 8},{0x11, 8}, 00098 {0x0F, 6},{0x0B, 6},{0x0D, 6},{0x09, 6}, 00099 {0x07, 4},{0x05, 4}, 00100 {0x03, 2}, 00101 {0x00, 5}, 00102 {0x02, 2}, 00103 {0x04, 4},{0x06, 4}, 00104 {0x08, 6},{0x0C, 6},{0x0A, 6},{0x0E, 6}, 00105 {0x10, 8},{0x18, 8},{0x14, 8},{0x1C, 8},{0x12, 8},{0x1A, 8},{0x16, 8},{0x1E, 8}, 00106 {0x20,10},{0x30,10},{0x28,10},{0x38,10},{0x24,10},{0x34,10},{0x2C,10},{0x3C,10}, 00107 {0x22,10},{0x32,10},{0x2A,10},{0x3A,10},{0x26,10},{0x36,10},{0x2E,10},{0x3E,10}, 00108 }; 00109 00110 00111 static VLC ccp_vlc; 00112 static VLC level_vlc; 00113 static VLC dc_ccp_vlc; 00114 static VLC ac_ccp_vlc; 00115 static VLC asv2_level_vlc; 00116 00117 static av_cold void init_vlcs(ASV1Context *a){ 00118 static int done = 0; 00119 00120 if (!done) { 00121 done = 1; 00122 00123 INIT_VLC_STATIC(&ccp_vlc, VLC_BITS, 17, 00124 &ccp_tab[0][1], 2, 1, 00125 &ccp_tab[0][0], 2, 1, 64); 00126 INIT_VLC_STATIC(&dc_ccp_vlc, VLC_BITS, 8, 00127 &dc_ccp_tab[0][1], 2, 1, 00128 &dc_ccp_tab[0][0], 2, 1, 64); 00129 INIT_VLC_STATIC(&ac_ccp_vlc, VLC_BITS, 16, 00130 &ac_ccp_tab[0][1], 2, 1, 00131 &ac_ccp_tab[0][0], 2, 1, 64); 00132 INIT_VLC_STATIC(&level_vlc, VLC_BITS, 7, 00133 &level_tab[0][1], 2, 1, 00134 &level_tab[0][0], 2, 1, 64); 00135 INIT_VLC_STATIC(&asv2_level_vlc, ASV2_LEVEL_VLC_BITS, 63, 00136 &asv2_level_tab[0][1], 2, 1, 00137 &asv2_level_tab[0][0], 2, 1, 1024); 00138 } 00139 } 00140 00141 //FIXME write a reversed bitstream reader to avoid the double reverse 00142 static inline int asv2_get_bits(GetBitContext *gb, int n){ 00143 return av_reverse[ get_bits(gb, n) << (8-n) ]; 00144 } 00145 00146 static inline void asv2_put_bits(PutBitContext *pb, int n, int v){ 00147 put_bits(pb, n, av_reverse[ v << (8-n) ]); 00148 } 00149 00150 static inline int asv1_get_level(GetBitContext *gb){ 00151 int code= get_vlc2(gb, level_vlc.table, VLC_BITS, 1); 00152 00153 if(code==3) return get_sbits(gb, 8); 00154 else return code - 3; 00155 } 00156 00157 static inline int asv2_get_level(GetBitContext *gb){ 00158 int code= get_vlc2(gb, asv2_level_vlc.table, ASV2_LEVEL_VLC_BITS, 1); 00159 00160 if(code==31) return (int8_t)asv2_get_bits(gb, 8); 00161 else return code - 31; 00162 } 00163 00164 static inline void asv1_put_level(PutBitContext *pb, int level){ 00165 unsigned int index= level + 3; 00166 00167 if(index <= 6) put_bits(pb, level_tab[index][1], level_tab[index][0]); 00168 else{ 00169 put_bits(pb, level_tab[3][1], level_tab[3][0]); 00170 put_sbits(pb, 8, level); 00171 } 00172 } 00173 00174 static inline void asv2_put_level(PutBitContext *pb, int level){ 00175 unsigned int index= level + 31; 00176 00177 if(index <= 62) put_bits(pb, asv2_level_tab[index][1], asv2_level_tab[index][0]); 00178 else{ 00179 put_bits(pb, asv2_level_tab[31][1], asv2_level_tab[31][0]); 00180 asv2_put_bits(pb, 8, level&0xFF); 00181 } 00182 } 00183 00184 static inline int asv1_decode_block(ASV1Context *a, DCTELEM block[64]){ 00185 int i; 00186 00187 block[0]= 8*get_bits(&a->gb, 8); 00188 00189 for(i=0; i<11; i++){ 00190 const int ccp= get_vlc2(&a->gb, ccp_vlc.table, VLC_BITS, 1); 00191 00192 if(ccp){ 00193 if(ccp == 16) break; 00194 if(ccp < 0 || i>=10){ 00195 av_log(a->avctx, AV_LOG_ERROR, "coded coeff pattern damaged\n"); 00196 return -1; 00197 } 00198 00199 if(ccp&8) block[a->scantable.permutated[4*i+0]]= (asv1_get_level(&a->gb) * a->intra_matrix[4*i+0])>>4; 00200 if(ccp&4) block[a->scantable.permutated[4*i+1]]= (asv1_get_level(&a->gb) * a->intra_matrix[4*i+1])>>4; 00201 if(ccp&2) block[a->scantable.permutated[4*i+2]]= (asv1_get_level(&a->gb) * a->intra_matrix[4*i+2])>>4; 00202 if(ccp&1) block[a->scantable.permutated[4*i+3]]= (asv1_get_level(&a->gb) * a->intra_matrix[4*i+3])>>4; 00203 } 00204 } 00205 00206 return 0; 00207 } 00208 00209 static inline int asv2_decode_block(ASV1Context *a, DCTELEM block[64]){ 00210 int i, count, ccp; 00211 00212 count= asv2_get_bits(&a->gb, 4); 00213 00214 block[0]= 8*asv2_get_bits(&a->gb, 8); 00215 00216 ccp= get_vlc2(&a->gb, dc_ccp_vlc.table, VLC_BITS, 1); 00217 if(ccp){ 00218 if(ccp&4) block[a->scantable.permutated[1]]= (asv2_get_level(&a->gb) * a->intra_matrix[1])>>4; 00219 if(ccp&2) block[a->scantable.permutated[2]]= (asv2_get_level(&a->gb) * a->intra_matrix[2])>>4; 00220 if(ccp&1) block[a->scantable.permutated[3]]= (asv2_get_level(&a->gb) * a->intra_matrix[3])>>4; 00221 } 00222 00223 for(i=1; i<count+1; i++){ 00224 const int ccp= get_vlc2(&a->gb, ac_ccp_vlc.table, VLC_BITS, 1); 00225 00226 if(ccp){ 00227 if(ccp&8) block[a->scantable.permutated[4*i+0]]= (asv2_get_level(&a->gb) * a->intra_matrix[4*i+0])>>4; 00228 if(ccp&4) block[a->scantable.permutated[4*i+1]]= (asv2_get_level(&a->gb) * a->intra_matrix[4*i+1])>>4; 00229 if(ccp&2) block[a->scantable.permutated[4*i+2]]= (asv2_get_level(&a->gb) * a->intra_matrix[4*i+2])>>4; 00230 if(ccp&1) block[a->scantable.permutated[4*i+3]]= (asv2_get_level(&a->gb) * a->intra_matrix[4*i+3])>>4; 00231 } 00232 } 00233 00234 return 0; 00235 } 00236 00237 static inline void asv1_encode_block(ASV1Context *a, DCTELEM block[64]){ 00238 int i; 00239 int nc_count=0; 00240 00241 put_bits(&a->pb, 8, (block[0] + 32)>>6); 00242 block[0]= 0; 00243 00244 for(i=0; i<10; i++){ 00245 const int index= scantab[4*i]; 00246 int ccp=0; 00247 00248 if( (block[index + 0] = (block[index + 0]*a->q_intra_matrix[index + 0] + (1<<15))>>16) ) ccp |= 8; 00249 if( (block[index + 8] = (block[index + 8]*a->q_intra_matrix[index + 8] + (1<<15))>>16) ) ccp |= 4; 00250 if( (block[index + 1] = (block[index + 1]*a->q_intra_matrix[index + 1] + (1<<15))>>16) ) ccp |= 2; 00251 if( (block[index + 9] = (block[index + 9]*a->q_intra_matrix[index + 9] + (1<<15))>>16) ) ccp |= 1; 00252 00253 if(ccp){ 00254 for(;nc_count; nc_count--) 00255 put_bits(&a->pb, ccp_tab[0][1], ccp_tab[0][0]); 00256 00257 put_bits(&a->pb, ccp_tab[ccp][1], ccp_tab[ccp][0]); 00258 00259 if(ccp&8) asv1_put_level(&a->pb, block[index + 0]); 00260 if(ccp&4) asv1_put_level(&a->pb, block[index + 8]); 00261 if(ccp&2) asv1_put_level(&a->pb, block[index + 1]); 00262 if(ccp&1) asv1_put_level(&a->pb, block[index + 9]); 00263 }else{ 00264 nc_count++; 00265 } 00266 } 00267 put_bits(&a->pb, ccp_tab[16][1], ccp_tab[16][0]); 00268 } 00269 00270 static inline void asv2_encode_block(ASV1Context *a, DCTELEM block[64]){ 00271 int i; 00272 int count=0; 00273 00274 for(count=63; count>3; count--){ 00275 const int index= scantab[count]; 00276 00277 if( (block[index]*a->q_intra_matrix[index] + (1<<15))>>16 ) 00278 break; 00279 } 00280 00281 count >>= 2; 00282 00283 asv2_put_bits(&a->pb, 4, count); 00284 asv2_put_bits(&a->pb, 8, (block[0] + 32)>>6); 00285 block[0]= 0; 00286 00287 for(i=0; i<=count; i++){ 00288 const int index= scantab[4*i]; 00289 int ccp=0; 00290 00291 if( (block[index + 0] = (block[index + 0]*a->q_intra_matrix[index + 0] + (1<<15))>>16) ) ccp |= 8; 00292 if( (block[index + 8] = (block[index + 8]*a->q_intra_matrix[index + 8] + (1<<15))>>16) ) ccp |= 4; 00293 if( (block[index + 1] = (block[index + 1]*a->q_intra_matrix[index + 1] + (1<<15))>>16) ) ccp |= 2; 00294 if( (block[index + 9] = (block[index + 9]*a->q_intra_matrix[index + 9] + (1<<15))>>16) ) ccp |= 1; 00295 00296 assert(i || ccp<8); 00297 if(i) put_bits(&a->pb, ac_ccp_tab[ccp][1], ac_ccp_tab[ccp][0]); 00298 else put_bits(&a->pb, dc_ccp_tab[ccp][1], dc_ccp_tab[ccp][0]); 00299 00300 if(ccp){ 00301 if(ccp&8) asv2_put_level(&a->pb, block[index + 0]); 00302 if(ccp&4) asv2_put_level(&a->pb, block[index + 8]); 00303 if(ccp&2) asv2_put_level(&a->pb, block[index + 1]); 00304 if(ccp&1) asv2_put_level(&a->pb, block[index + 9]); 00305 } 00306 } 00307 } 00308 00309 static inline int decode_mb(ASV1Context *a, DCTELEM block[6][64]){ 00310 int i; 00311 00312 a->dsp.clear_blocks(block[0]); 00313 00314 if(a->avctx->codec_id == CODEC_ID_ASV1){ 00315 for(i=0; i<6; i++){ 00316 if( asv1_decode_block(a, block[i]) < 0) 00317 return -1; 00318 } 00319 }else{ 00320 for(i=0; i<6; i++){ 00321 if( asv2_decode_block(a, block[i]) < 0) 00322 return -1; 00323 } 00324 } 00325 return 0; 00326 } 00327 00328 static inline int encode_mb(ASV1Context *a, DCTELEM block[6][64]){ 00329 int i; 00330 00331 if(a->pb.buf_end - a->pb.buf - (put_bits_count(&a->pb)>>3) < 30*16*16*3/2/8){ 00332 av_log(a->avctx, AV_LOG_ERROR, "encoded frame too large\n"); 00333 return -1; 00334 } 00335 00336 if(a->avctx->codec_id == CODEC_ID_ASV1){ 00337 for(i=0; i<6; i++) 00338 asv1_encode_block(a, block[i]); 00339 }else{ 00340 for(i=0; i<6; i++) 00341 asv2_encode_block(a, block[i]); 00342 } 00343 return 0; 00344 } 00345 00346 static inline void idct_put(ASV1Context *a, int mb_x, int mb_y){ 00347 DCTELEM (*block)[64]= a->block; 00348 int linesize= a->picture.linesize[0]; 00349 00350 uint8_t *dest_y = a->picture.data[0] + (mb_y * 16* linesize ) + mb_x * 16; 00351 uint8_t *dest_cb = a->picture.data[1] + (mb_y * 8 * a->picture.linesize[1]) + mb_x * 8; 00352 uint8_t *dest_cr = a->picture.data[2] + (mb_y * 8 * a->picture.linesize[2]) + mb_x * 8; 00353 00354 a->dsp.idct_put(dest_y , linesize, block[0]); 00355 a->dsp.idct_put(dest_y + 8, linesize, block[1]); 00356 a->dsp.idct_put(dest_y + 8*linesize , linesize, block[2]); 00357 a->dsp.idct_put(dest_y + 8*linesize + 8, linesize, block[3]); 00358 00359 if(!(a->avctx->flags&CODEC_FLAG_GRAY)){ 00360 a->dsp.idct_put(dest_cb, a->picture.linesize[1], block[4]); 00361 a->dsp.idct_put(dest_cr, a->picture.linesize[2], block[5]); 00362 } 00363 } 00364 00365 static inline void dct_get(ASV1Context *a, int mb_x, int mb_y){ 00366 DCTELEM (*block)[64]= a->block; 00367 int linesize= a->picture.linesize[0]; 00368 int i; 00369 00370 uint8_t *ptr_y = a->picture.data[0] + (mb_y * 16* linesize ) + mb_x * 16; 00371 uint8_t *ptr_cb = a->picture.data[1] + (mb_y * 8 * a->picture.linesize[1]) + mb_x * 8; 00372 uint8_t *ptr_cr = a->picture.data[2] + (mb_y * 8 * a->picture.linesize[2]) + mb_x * 8; 00373 00374 a->dsp.get_pixels(block[0], ptr_y , linesize); 00375 a->dsp.get_pixels(block[1], ptr_y + 8, linesize); 00376 a->dsp.get_pixels(block[2], ptr_y + 8*linesize , linesize); 00377 a->dsp.get_pixels(block[3], ptr_y + 8*linesize + 8, linesize); 00378 for(i=0; i<4; i++) 00379 a->dsp.fdct(block[i]); 00380 00381 if(!(a->avctx->flags&CODEC_FLAG_GRAY)){ 00382 a->dsp.get_pixels(block[4], ptr_cb, a->picture.linesize[1]); 00383 a->dsp.get_pixels(block[5], ptr_cr, a->picture.linesize[2]); 00384 for(i=4; i<6; i++) 00385 a->dsp.fdct(block[i]); 00386 } 00387 } 00388 00389 static int decode_frame(AVCodecContext *avctx, 00390 void *data, int *data_size, 00391 AVPacket *avpkt) 00392 { 00393 const uint8_t *buf = avpkt->data; 00394 int buf_size = avpkt->size; 00395 ASV1Context * const a = avctx->priv_data; 00396 AVFrame *picture = data; 00397 AVFrame * const p= &a->picture; 00398 int mb_x, mb_y; 00399 00400 if(p->data[0]) 00401 avctx->release_buffer(avctx, p); 00402 00403 p->reference= 0; 00404 if(avctx->get_buffer(avctx, p) < 0){ 00405 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); 00406 return -1; 00407 } 00408 p->pict_type= AV_PICTURE_TYPE_I; 00409 p->key_frame= 1; 00410 00411 av_fast_malloc(&a->bitstream_buffer, &a->bitstream_buffer_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); 00412 if (!a->bitstream_buffer) 00413 return AVERROR(ENOMEM); 00414 00415 if(avctx->codec_id == CODEC_ID_ASV1) 00416 a->dsp.bswap_buf((uint32_t*)a->bitstream_buffer, (const uint32_t*)buf, buf_size/4); 00417 else{ 00418 int i; 00419 for(i=0; i<buf_size; i++) 00420 a->bitstream_buffer[i]= av_reverse[ buf[i] ]; 00421 } 00422 00423 init_get_bits(&a->gb, a->bitstream_buffer, buf_size*8); 00424 00425 for(mb_y=0; mb_y<a->mb_height2; mb_y++){ 00426 for(mb_x=0; mb_x<a->mb_width2; mb_x++){ 00427 if( decode_mb(a, a->block) <0) 00428 return -1; 00429 00430 idct_put(a, mb_x, mb_y); 00431 } 00432 } 00433 00434 if(a->mb_width2 != a->mb_width){ 00435 mb_x= a->mb_width2; 00436 for(mb_y=0; mb_y<a->mb_height2; mb_y++){ 00437 if( decode_mb(a, a->block) <0) 00438 return -1; 00439 00440 idct_put(a, mb_x, mb_y); 00441 } 00442 } 00443 00444 if(a->mb_height2 != a->mb_height){ 00445 mb_y= a->mb_height2; 00446 for(mb_x=0; mb_x<a->mb_width; mb_x++){ 00447 if( decode_mb(a, a->block) <0) 00448 return -1; 00449 00450 idct_put(a, mb_x, mb_y); 00451 } 00452 } 00453 00454 *picture= *(AVFrame*)&a->picture; 00455 *data_size = sizeof(AVPicture); 00456 00457 emms_c(); 00458 00459 return (get_bits_count(&a->gb)+31)/32*4; 00460 } 00461 00462 #if CONFIG_ASV1_ENCODER || CONFIG_ASV2_ENCODER 00463 static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ 00464 ASV1Context * const a = avctx->priv_data; 00465 AVFrame *pict = data; 00466 AVFrame * const p= &a->picture; 00467 int size; 00468 int mb_x, mb_y; 00469 00470 init_put_bits(&a->pb, buf, buf_size); 00471 00472 *p = *pict; 00473 p->pict_type= AV_PICTURE_TYPE_I; 00474 p->key_frame= 1; 00475 00476 for(mb_y=0; mb_y<a->mb_height2; mb_y++){ 00477 for(mb_x=0; mb_x<a->mb_width2; mb_x++){ 00478 dct_get(a, mb_x, mb_y); 00479 encode_mb(a, a->block); 00480 } 00481 } 00482 00483 if(a->mb_width2 != a->mb_width){ 00484 mb_x= a->mb_width2; 00485 for(mb_y=0; mb_y<a->mb_height2; mb_y++){ 00486 dct_get(a, mb_x, mb_y); 00487 encode_mb(a, a->block); 00488 } 00489 } 00490 00491 if(a->mb_height2 != a->mb_height){ 00492 mb_y= a->mb_height2; 00493 for(mb_x=0; mb_x<a->mb_width; mb_x++){ 00494 dct_get(a, mb_x, mb_y); 00495 encode_mb(a, a->block); 00496 } 00497 } 00498 emms_c(); 00499 00500 align_put_bits(&a->pb); 00501 while(put_bits_count(&a->pb)&31) 00502 put_bits(&a->pb, 8, 0); 00503 00504 size= put_bits_count(&a->pb)/32; 00505 00506 if(avctx->codec_id == CODEC_ID_ASV1) 00507 a->dsp.bswap_buf((uint32_t*)buf, (uint32_t*)buf, size); 00508 else{ 00509 int i; 00510 for(i=0; i<4*size; i++) 00511 buf[i]= av_reverse[ buf[i] ]; 00512 } 00513 00514 return size*4; 00515 } 00516 #endif /* CONFIG_ASV1_ENCODER || CONFIG_ASV2_ENCODER */ 00517 00518 static av_cold void common_init(AVCodecContext *avctx){ 00519 ASV1Context * const a = avctx->priv_data; 00520 00521 dsputil_init(&a->dsp, avctx); 00522 00523 a->mb_width = (avctx->width + 15) / 16; 00524 a->mb_height = (avctx->height + 15) / 16; 00525 a->mb_width2 = (avctx->width + 0) / 16; 00526 a->mb_height2 = (avctx->height + 0) / 16; 00527 00528 avctx->coded_frame= &a->picture; 00529 a->avctx= avctx; 00530 } 00531 00532 static av_cold int decode_init(AVCodecContext *avctx){ 00533 ASV1Context * const a = avctx->priv_data; 00534 AVFrame *p= &a->picture; 00535 int i; 00536 const int scale= avctx->codec_id == CODEC_ID_ASV1 ? 1 : 2; 00537 00538 common_init(avctx); 00539 init_vlcs(a); 00540 ff_init_scantable(a->dsp.idct_permutation, &a->scantable, scantab); 00541 avctx->pix_fmt= PIX_FMT_YUV420P; 00542 00543 a->inv_qscale= avctx->extradata[0]; 00544 if(a->inv_qscale == 0){ 00545 av_log(avctx, AV_LOG_ERROR, "illegal qscale 0\n"); 00546 if(avctx->codec_id == CODEC_ID_ASV1) 00547 a->inv_qscale= 6; 00548 else 00549 a->inv_qscale= 10; 00550 } 00551 00552 for(i=0; i<64; i++){ 00553 int index= scantab[i]; 00554 00555 a->intra_matrix[i]= 64*scale*ff_mpeg1_default_intra_matrix[index] / a->inv_qscale; 00556 } 00557 00558 p->qstride= a->mb_width; 00559 p->qscale_table= av_malloc( p->qstride * a->mb_height); 00560 p->quality= (32*scale + a->inv_qscale/2)/a->inv_qscale; 00561 memset(p->qscale_table, p->quality, p->qstride*a->mb_height); 00562 00563 return 0; 00564 } 00565 00566 #if CONFIG_ASV1_ENCODER || CONFIG_ASV2_ENCODER 00567 static av_cold int encode_init(AVCodecContext *avctx){ 00568 ASV1Context * const a = avctx->priv_data; 00569 int i; 00570 const int scale= avctx->codec_id == CODEC_ID_ASV1 ? 1 : 2; 00571 00572 common_init(avctx); 00573 00574 if(avctx->global_quality == 0) avctx->global_quality= 4*FF_QUALITY_SCALE; 00575 00576 a->inv_qscale= (32*scale*FF_QUALITY_SCALE + avctx->global_quality/2) / avctx->global_quality; 00577 00578 avctx->extradata= av_mallocz(8); 00579 avctx->extradata_size=8; 00580 ((uint32_t*)avctx->extradata)[0]= av_le2ne32(a->inv_qscale); 00581 ((uint32_t*)avctx->extradata)[1]= av_le2ne32(AV_RL32("ASUS")); 00582 00583 for(i=0; i<64; i++){ 00584 int q= 32*scale*ff_mpeg1_default_intra_matrix[i]; 00585 a->q_intra_matrix[i]= ((a->inv_qscale<<16) + q/2) / q; 00586 } 00587 00588 return 0; 00589 } 00590 #endif /* CONFIG_ASV1_ENCODER || CONFIG_ASV2_ENCODER */ 00591 00592 static av_cold int decode_end(AVCodecContext *avctx){ 00593 ASV1Context * const a = avctx->priv_data; 00594 00595 av_freep(&a->bitstream_buffer); 00596 av_freep(&a->picture.qscale_table); 00597 a->bitstream_buffer_size=0; 00598 00599 if(a->picture.data[0]) 00600 avctx->release_buffer(avctx, &a->picture); 00601 00602 return 0; 00603 } 00604 00605 AVCodec ff_asv1_decoder = { 00606 "asv1", 00607 AVMEDIA_TYPE_VIDEO, 00608 CODEC_ID_ASV1, 00609 sizeof(ASV1Context), 00610 decode_init, 00611 NULL, 00612 decode_end, 00613 decode_frame, 00614 CODEC_CAP_DR1, 00615 .long_name= NULL_IF_CONFIG_SMALL("ASUS V1"), 00616 }; 00617 00618 AVCodec ff_asv2_decoder = { 00619 "asv2", 00620 AVMEDIA_TYPE_VIDEO, 00621 CODEC_ID_ASV2, 00622 sizeof(ASV1Context), 00623 decode_init, 00624 NULL, 00625 decode_end, 00626 decode_frame, 00627 CODEC_CAP_DR1, 00628 .long_name= NULL_IF_CONFIG_SMALL("ASUS V2"), 00629 }; 00630 00631 #if CONFIG_ASV1_ENCODER 00632 AVCodec ff_asv1_encoder = { 00633 "asv1", 00634 AVMEDIA_TYPE_VIDEO, 00635 CODEC_ID_ASV1, 00636 sizeof(ASV1Context), 00637 encode_init, 00638 encode_frame, 00639 //encode_end, 00640 .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, 00641 .long_name= NULL_IF_CONFIG_SMALL("ASUS V1"), 00642 }; 00643 #endif 00644 00645 #if CONFIG_ASV2_ENCODER 00646 AVCodec ff_asv2_encoder = { 00647 "asv2", 00648 AVMEDIA_TYPE_VIDEO, 00649 CODEC_ID_ASV2, 00650 sizeof(ASV1Context), 00651 encode_init, 00652 encode_frame, 00653 //encode_end, 00654 .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, 00655 .long_name= NULL_IF_CONFIG_SMALL("ASUS V2"), 00656 }; 00657 #endif