[Ffmpeg-cvslog] r5775 - trunk/libavcodec/vp3.c

michael subversion
Mon Jul 17 11:52:00 CEST 2006


Author: michael
Date: Mon Jul 17 11:51:59 2006
New Revision: 5775

Modified:
   trunk/libavcodec/vp3.c

Log:
attempt to implement xiphs useless and stupid quantization matrix mess


Modified: trunk/libavcodec/vp3.c
==============================================================================
--- trunk/libavcodec/vp3.c	(original)
+++ trunk/libavcodec/vp3.c	Mon Jul 17 11:51:59 2006
@@ -262,9 +262,10 @@
     /* tables */
     uint16_t coded_dc_scale_factor[64];
     uint32_t coded_ac_scale_factor[64];
-    uint16_t coded_intra_y_dequant[64];
-    uint16_t coded_intra_c_dequant[64];
-    uint16_t coded_inter_dequant[64];
+    uint8_t base_matrix[384][64];
+    uint8_t qr_count[2][3];
+    uint8_t qr_size [2][3][64];
+    uint16_t qr_base[2][3][64];
 
     /* this is a list of indices into the all_fragments array indicating
      * which of the fragments are coded */
@@ -643,98 +644,38 @@
  */
 static void init_dequantizer(Vp3DecodeContext *s)
 {
-
     int ac_scale_factor = s->coded_ac_scale_factor[s->quality_index];
     int dc_scale_factor = s->coded_dc_scale_factor[s->quality_index];
-    int i, j;
+    int i, j, plane, inter, qri, bmi, bmj, qistart;
 
     debug_vp3("  vp3: initializing dequantization tables\n");
 
-    /*
-     * Scale dequantizers:
-     *
-     *   quantizer * sf
-     *   --------------
-     *        100
-     *
-     * where sf = dc_scale_factor for DC quantizer
-     *         or ac_scale_factor for AC quantizer
-     *
-     * Then, saturate the result to a lower limit of MIN_DEQUANT_VAL.
-     */
-#define SCALER 4
-
-    /* scale DC quantizers */
-    s->qmat[0][0][0] = s->coded_intra_y_dequant[0] * dc_scale_factor / 100;
-    if (s->qmat[0][0][0] < MIN_DEQUANT_VAL * 2)
-        s->qmat[0][0][0] = MIN_DEQUANT_VAL * 2;
-    s->qmat[0][0][0] *= SCALER;
-
-    s->qmat[0][1][0] = s->coded_intra_c_dequant[0] * dc_scale_factor / 100;
-    if (s->qmat[0][1][0] < MIN_DEQUANT_VAL * 2)
-        s->qmat[0][1][0] = MIN_DEQUANT_VAL * 2;
-    s->qmat[0][1][0] *= SCALER;
-
-    s->qmat[1][0][0] = s->coded_inter_dequant[0] * dc_scale_factor / 100;
-    if (s->qmat[1][0][0] < MIN_DEQUANT_VAL * 4)
-        s->qmat[1][0][0] = MIN_DEQUANT_VAL * 4;
-    s->qmat[1][0][0] *= SCALER;
-
-    /* scale AC quantizers, zigzag at the same time in preparation for
-     * the dequantization phase */
-    for (i = 1; i < 64; i++) {
-        int k= s->scantable.scantable[i];
-        j = s->scantable.permutated[i];
-
-        s->qmat[0][0][j] = s->coded_intra_y_dequant[k] * ac_scale_factor / 100;
-        if (s->qmat[0][0][j] < MIN_DEQUANT_VAL)
-            s->qmat[0][0][j] = MIN_DEQUANT_VAL;
-        s->qmat[0][0][j] *= SCALER;
-
-        s->qmat[0][1][j] = s->coded_intra_c_dequant[k] * ac_scale_factor / 100;
-        if (s->qmat[0][1][j] < MIN_DEQUANT_VAL)
-            s->qmat[0][1][j] = MIN_DEQUANT_VAL;
-        s->qmat[0][1][j] *= SCALER;
-
-        s->qmat[1][0][j] = s->coded_inter_dequant[k] * ac_scale_factor / 100;
-        if (s->qmat[1][0][j] < MIN_DEQUANT_VAL * 2)
-            s->qmat[1][0][j] = MIN_DEQUANT_VAL * 2;
-        s->qmat[1][0][j] *= SCALER;
-    }
-
-    memcpy(s->qmat[0][2], s->qmat[0][1], sizeof(s->qmat[0][0]));
-    memcpy(s->qmat[1][1], s->qmat[1][0], sizeof(s->qmat[0][0]));
-    memcpy(s->qmat[1][2], s->qmat[1][0], sizeof(s->qmat[0][0]));
+    for(inter=0; inter<2; inter++){
+        for(plane=0; plane<3; plane++){
+            int sum=0;
+            for(qri=0; qri<s->qr_count[inter][plane]; qri++){
+                sum+= s->qr_size[inter][plane][qri];
+                if(s->quality_index <= sum)
+                    break;
+            }
+            qistart= sum - s->qr_size[inter][plane][qri];
+            bmi= s->qr_base[inter][plane][qri  ];
+            bmj= s->qr_base[inter][plane][qri+1];
+            for(i=0; i<64; i++){
+                int coeff= (  2*(sum    -s->quality_index)*s->base_matrix[bmi][i]
+                            - 2*(qistart-s->quality_index)*s->base_matrix[bmj][i]
+                            + s->qr_size[inter][plane][qri])
+                           / (2*s->qr_size[inter][plane][qri]);
 
-    memset(s->qscale_table, (FFMAX(s->qmat[0][0][1], s->qmat[0][1][1])+8)/16, 512); //FIXME finetune
+                int qmin= 8<<(inter + !plane);
+                int qscale= i ? ac_scale_factor : dc_scale_factor;
 
-    /* print debug information as requested */
-    debug_dequantizers("intra Y dequantizers:\n");
-    for (i = 0; i < 8; i++) {
-      for (j = i * 8; j < i * 8 + 8; j++) {
-        debug_dequantizers(" %4d,", s->qmat[0][0][j]);
-      }
-      debug_dequantizers("\n");
-    }
-    debug_dequantizers("\n");
-
-    debug_dequantizers("intra C dequantizers:\n");
-    for (i = 0; i < 8; i++) {
-      for (j = i * 8; j < i * 8 + 8; j++) {
-        debug_dequantizers(" %4d,", s->qmat[0][1][j]);
-      }
-      debug_dequantizers("\n");
-    }
-    debug_dequantizers("\n");
-
-    debug_dequantizers("interframe dequantizers:\n");
-    for (i = 0; i < 8; i++) {
-      for (j = i * 8; j < i * 8 + 8; j++) {
-        debug_dequantizers(" %4d,", s->qmat[1][0][j]);
-      }
-      debug_dequantizers("\n");
+                s->qmat[inter][plane][i]= clip((qscale * coeff)/100 * 4, qmin, 4096);
+            }
+        }
     }
-    debug_dequantizers("\n");
+
+    memset(s->qscale_table, (FFMAX(s->qmat[0][0][1], s->qmat[0][1][1])+8)/16, 512); //FIXME finetune
 }
 
 /*
@@ -2201,7 +2142,7 @@
 static int vp3_decode_init(AVCodecContext *avctx)
 {
     Vp3DecodeContext *s = avctx->priv_data;
-    int i;
+    int i, inter, plane;
     int c_width;
     int c_height;
     int y_superblock_count;
@@ -2284,14 +2225,23 @@
         for (i = 0; i < 64; i++)
             s->coded_ac_scale_factor[i] = vp31_ac_scale_factor[i];
         for (i = 0; i < 64; i++)
-            s->coded_intra_y_dequant[i] = vp31_intra_y_dequant[i];
+            s->base_matrix[0][i] = vp31_intra_y_dequant[i];
         for (i = 0; i < 64; i++)
-            s->coded_intra_c_dequant[i] = vp31_intra_c_dequant[i];
+            s->base_matrix[1][i] = vp31_intra_c_dequant[i];
         for (i = 0; i < 64; i++)
-            s->coded_inter_dequant[i] = vp31_inter_dequant[i];
+            s->base_matrix[2][i] = vp31_inter_dequant[i];
         for (i = 0; i < 64; i++)
             s->filter_limit_values[i] = vp31_filter_limit_values[i];
 
+        for(inter=0; inter<2; inter++){
+            for(plane=0; plane<3; plane++){
+                s->qr_count[inter][plane]= 1;
+                s->qr_size [inter][plane][0]= 63;
+                s->qr_base [inter][plane][0]=
+                s->qr_base [inter][plane][1]= 2*inter + (!!plane)*!inter;
+            }
+        }
+
         /* init VLC tables */
         for (i = 0; i < 16; i++) {
 
@@ -2714,7 +2664,7 @@
 static int theora_decode_tables(AVCodecContext *avctx, GetBitContext *gb)
 {
     Vp3DecodeContext *s = avctx->priv_data;
-    int i, n, matrices;
+    int i, n, matrices, inter, plane;
 
     if (s->theora >= 0x030200) {
         n = get_bits(gb, 3);
@@ -2743,52 +2693,57 @@
         matrices = get_bits(gb, 9) + 1;
     else
         matrices = 3;
-    if (matrices != 3) {
-        av_log(avctx,AV_LOG_ERROR, "unsupported matrices: %d\n", matrices);
-//        return -1;
-    }
-    /* y coeffs */
-    for (i = 0; i < 64; i++)
-        s->coded_intra_y_dequant[i] = get_bits(gb, 8);
 
-    /* uv coeffs */
-    for (i = 0; i < 64; i++)
-        s->coded_intra_c_dequant[i] = get_bits(gb, 8);
-
-    /* inter coeffs */
-    for (i = 0; i < 64; i++)
-        s->coded_inter_dequant[i] = get_bits(gb, 8);
+    if(matrices > 384){
+        av_log(avctx, AV_LOG_ERROR, "invalid number of base matrixes\n");
+        return -1;
+    }
 
-    /* skip unknown matrices */
-    n = matrices - 3;
-    while(n--)
+    for(n=0; n<matrices; n++){
         for (i = 0; i < 64; i++)
-            skip_bits(gb, 8);
+            s->base_matrix[n][i]= get_bits(gb, 8);
+    }
 
-    for (i = 0; i <= 1; i++) {
-        for (n = 0; n <= 2; n++) {
-            int newqr;
-            if (i > 0 || n > 0)
+    for (inter = 0; inter <= 1; inter++) {
+        for (plane = 0; plane <= 2; plane++) {
+            int newqr= 1;
+            if (inter || plane > 0)
                 newqr = get_bits(gb, 1);
-            else
-                newqr = 1;
             if (!newqr) {
-                if (i > 0)
-                    get_bits(gb, 1);
-                //FIXME this is simply incomplete
-            }
-            else {
+                int qtj, plj;
+                if(inter && get_bits(gb, 1)){
+                    qtj = 0;
+                    plj = plane;
+                }else{
+                    qtj= (3*inter + plane - 1) / 3;
+                    plj= (plane + 2) % 3;
+                }
+                s->qr_count[inter][plane]= s->qr_count[qtj][plj];
+                memcpy(s->qr_size[inter][plane], s->qr_size[qtj][plj], sizeof(s->qr_size[0][0]));
+                memcpy(s->qr_base[inter][plane], s->qr_base[qtj][plj], sizeof(s->qr_base[0][0]));
+            } else {
+                int qri= 0;
                 int qi = 0;
-                //FIXME this is simply incomplete
-                skip_bits(gb, av_log2(matrices-1)+1);
-                while (qi < 63) {
-                    qi += get_bits(gb, av_log2(63-qi)+1) + 1;
-                    skip_bits(gb, av_log2(matrices-1)+1);
+
+                for(;;){
+                    i= get_bits(gb, av_log2(matrices-1)+1);
+                    if(i>= matrices){
+                        av_log(avctx, AV_LOG_ERROR, "invalid base matrix index\n");
+                        return -1;
+                    }
+                    s->qr_base[inter][plane][qri]= i;
+                    if(qi >= 63)
+                        break;
+                    i = get_bits(gb, av_log2(63-qi)+1) + 1;
+                    s->qr_size[inter][plane][qri++]= i;
+                    qi += i;
                 }
+
                 if (qi > 63) {
                     av_log(avctx, AV_LOG_ERROR, "invalid qi %d > 63\n", qi);
                     return -1;
                 }
+                s->qr_count[inter][plane]= qri;
             }
         }
     }




More information about the ffmpeg-cvslog mailing list