trellis quantization for mpeg1
authorMichael Niedermayer <michaelni@gmx.at>
Wed, 1 Jan 2003 00:42:18 +0000 (00:42 +0000)
committerMichael Niedermayer <michaelni@gmx.at>
Wed, 1 Jan 2003 00:42:18 +0000 (00:42 +0000)
rounding bugfix for mpeg1 (seems this was introduced during the ME changes)

Originally committed as revision 1382 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavcodec/mpeg12.c
libavcodec/mpegvideo.c
libavcodec/mpegvideo.h

index 5dc3e6218ee1223020fa6323a18ce66c5b3ea26b..e7c59a36454222f1e9b775418bbaa1dab083184a 100644 (file)
@@ -66,9 +66,14 @@ static inline int mpeg2_decode_block_intra(MpegEncContext *s,
                                     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_2d_vlc_rl(RLTable *rl)
     }
 }
 
+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 @@ void ff_mpeg1_encode_init(MpegEncContext *s)
 
         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 @@ void ff_mpeg1_encode_init(MpegEncContext *s)
     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 @@ static void mpeg1_encode_block(MpegEncContext *s,
             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 {
index cb74d5a8525e60150f5ef15f2314719032e12c49..139688f794fa14db8b14b64f86821cb1cc37f0e1 100644 (file)
@@ -2780,7 +2780,7 @@ static void encode_picture(MpegEncContext *s, int picture_number)
             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 @@ static int dct_quantize_trellis_c(MpegEncContext *s,
         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 @@ static int dct_quantize_trellis_c(MpegEncContext *s,
                 }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 @@ static int dct_quantize_trellis_c(MpegEncContext *s,
 
                 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 @@ static int dct_quantize_trellis_c(MpegEncContext *s,
 
     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];
index e6af7fa287e71f3efedadecc6812393217e8fc74..82fc9c4aaafe24a9920e2ae1686353ab10d29e4b 100644 (file)
@@ -312,7 +312,7 @@ typedef struct MpegEncContext {
     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];