Mercurial > libavcodec.hg
changeset 947:9be53be2d1a9 libavcodec
trellis quantization for mpeg1
rounding bugfix for mpeg1 (seems this was introduced during the ME changes)
author | michaelni |
---|---|
date | Wed, 01 Jan 2003 00:42:18 +0000 |
parents | 4f522c9e6099 |
children | 371bc36a9c5c |
files | mpeg12.c mpegvideo.c mpegvideo.h |
diffstat | 3 files changed, 85 insertions(+), 14 deletions(-) [+] |
line wrap: on
line diff
--- a/mpeg12.c Tue Dec 31 22:58:41 2002 +0000 +++ b/mpeg12.c Wed Jan 01 00:42:18 2003 +0000 @@ -66,9 +66,14 @@ int n); static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred); +#ifdef CONFIG_ENCODERS static UINT16 mv_penalty[MAX_FCODE+1][MAX_MV*2+1]; static UINT8 fcode_tab[MAX_MV*2+1]; +static uint32_t uni_mpeg1_ac_vlc_bits[64*64*2]; +static uint8_t uni_mpeg1_ac_vlc_len [64*64*2]; +#endif + static inline int get_bits_diff(MpegEncContext *s){ int bits,ret; @@ -118,6 +123,51 @@ } } +static void init_uni_ac_vlc(RLTable *rl, uint32_t *uni_ac_vlc_bits, uint8_t *uni_ac_vlc_len){ + int i; + + for(i=0; i<128; i++){ + int level= i-64; + int run; + for(run=0; run<64; run++){ + int len, bits, code; + + int alevel= ABS(level); + int sign= (level>>31)&1; + + if (alevel > rl->max_level[0][run]) + code= 111; /*rl->n*/ + else + code= rl->index_run[0][run] + alevel - 1; + + if (code < 111 /* rl->n */) { + /* store the vlc & sign at once */ + len= mpeg1_vlc[code][1]+1; + bits= (mpeg1_vlc[code][0]<<1) + sign; + } else { + len= mpeg1_vlc[111/*rl->n*/][1]+6; + bits= mpeg1_vlc[111/*rl->n*/][0]<<6; + + bits|= run; + if (alevel < 128) { + bits<<=8; len+=8; + bits|= level & 0xff; + } else { + bits<<=16; len+=16; + bits|= level & 0xff; + if (level < 0) { + bits|= 0x8001 + level + 255; + } else { + bits|= level & 0xffff; + } + } + } + + uni_ac_vlc_bits[UNI_AC_ENC_INDEX(run, i)]= bits; + uni_ac_vlc_len [UNI_AC_ENC_INDEX(run, i)]= len; + } + } +} static void put_header(MpegEncContext *s, int header) { @@ -465,12 +515,14 @@ done=1; init_rl(&rl_mpeg1); - + for(i=0; i<64; i++) { mpeg1_max_level[0][i]= rl_mpeg1.max_level[0][i]; mpeg1_index_run[0][i]= rl_mpeg1.index_run[0][i]; } + + init_uni_ac_vlc(&rl_mpeg1, uni_mpeg1_ac_vlc_bits, uni_mpeg1_ac_vlc_len); /* build unified dc encoding tables */ for(i=-255; i<256; i++) @@ -532,6 +584,8 @@ s->max_qcoeff= 255; s->intra_quant_bias= 3<<(QUANT_BIAS_SHIFT-3); //(a + x*3/8)/x s->inter_quant_bias= 0; + s->intra_ac_vlc_length= + s->inter_ac_vlc_length= uni_mpeg1_ac_vlc_len; } static inline void encode_dc(MpegEncContext *s, int diff, int component) @@ -602,12 +656,8 @@ sign&=1; // code = get_rl_index(rl, 0, run, alevel); - if (alevel > mpeg1_max_level[0][run]) - code= 111; /*rl->n*/ - else + if (alevel <= mpeg1_max_level[0][run]){ code= mpeg1_index_run[0][run] + alevel - 1; - - if (code < 111 /* rl->n */) { /* store the vlc & sign at once */ put_bits(&s->pb, mpeg1_vlc[code][1]+1, (mpeg1_vlc[code][0]<<1) + sign); } else {
--- a/mpegvideo.c Tue Dec 31 22:58:41 2002 +0000 +++ b/mpegvideo.c Wed Jan 01 00:42:18 2003 +0000 @@ -2780,7 +2780,7 @@ s->no_rounding=1; else if(s->flipflop_rounding) s->no_rounding ^= 1; - }else{ + }else if(s->out_format == FMT_H263){ if(s->pict_type==I_TYPE) s->no_rounding=0; else if(s->pict_type!=B_TYPE) @@ -3307,7 +3307,7 @@ start_i = 1; last_non_zero = 0; qmat = s->q_intra_matrix[qscale]; - if(s->mpeg_quant) + if(s->mpeg_quant || s->codec_id== CODEC_ID_MPEG1VIDEO) bias= 1<<(QMAT_SHIFT-1); length = s->intra_ac_vlc_length; last_length= s->intra_ac_vlc_last_length; @@ -3381,13 +3381,33 @@ }else{ unquant_coeff= level*qmul - qadd; } - } //FIXME else + }else{ //MPEG1 + j= s->idct_permutation[ scantable[i + start_i] ]; //FIXME optimize + if(s->mb_intra){ + if (level < 0) { + unquant_coeff = (int)((-level) * qscale * s->intra_matrix[j]) >> 3; + unquant_coeff = -((unquant_coeff - 1) | 1); + } else { + unquant_coeff = (int)( level * qscale * s->intra_matrix[j]) >> 3; + unquant_coeff = (unquant_coeff - 1) | 1; + } + }else{ + if (level < 0) { + unquant_coeff = ((((-level) << 1) + 1) * qscale * ((int) s->inter_matrix[j])) >> 4; + unquant_coeff = -((unquant_coeff - 1) | 1); + } else { + unquant_coeff = ((( level << 1) + 1) * qscale * ((int) s->inter_matrix[j])) >> 4; + unquant_coeff = (unquant_coeff - 1) | 1; + } + } + unquant_coeff<<= 3; + } distoration= (unquant_coeff - dct_coeff) * (unquant_coeff - dct_coeff); level+=64; if((level&(~127)) == 0){ for(run=0; run<=i - left_limit; run++){ - int score= distoration + length[UNI_ENC_INDEX(run, level)]*lambda; + int score= distoration + length[UNI_AC_ENC_INDEX(run, level)]*lambda; score += score_tab[i-run]; if(score < best_score){ @@ -3400,7 +3420,7 @@ if(s->out_format == FMT_H263){ for(run=0; run<=i - left_limit; run++){ - int score= distoration + last_length[UNI_ENC_INDEX(run, level)]*lambda; + int score= distoration + last_length[UNI_AC_ENC_INDEX(run, level)]*lambda; score += score_tab[i-run]; if(score < last_score){ last_score= score; @@ -3452,11 +3472,12 @@ if(s->out_format != FMT_H263){ last_score= 256*256*256*120; - for(i=0; i<=last_non_zero - start_i + 1; i++){ + for(i= left_limit; i<=last_non_zero - start_i + 1; i++){ int score= score_tab[i]; + if(i) score += lambda*2; //FIXME exacter? + if(score < last_score){ last_score= score; - if(i) last_score += lambda*2; //FIXME exacter? last_i= i; last_level= level_tab[i]; last_run= run_tab[i];
--- a/mpegvideo.h Tue Dec 31 22:58:41 2002 +0000 +++ b/mpegvideo.h Wed Jan 01 00:42:18 2003 +0000 @@ -312,7 +312,7 @@ uint8_t *intra_ac_vlc_last_length; uint8_t *inter_ac_vlc_length; uint8_t *inter_ac_vlc_last_length; -#define UNI_ENC_INDEX(run,level) ((run)*128 + (level)) +#define UNI_AC_ENC_INDEX(run,level) ((run)*128 + (level)) /* precomputed matrix (combine qscale and DCT renorm) */ int __align8 q_intra_matrix[32][64];