changeset 248:56ee684c48bb libavcodec

- H.263+ decoder support for Advanded INTRA Coding (buggy)
author pulento
date Mon, 18 Feb 2002 19:33:27 +0000
parents 6f48cacd9ed9
children 42a0b7b16738
files h263.c h263data.h h263dec.c i386/mpegvideo_mmx.c mpegvideo.c mpegvideo.h
diffstat 6 files changed, 214 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/h263.c	Mon Feb 18 09:40:05 2002 +0000
+++ b/h263.c	Mon Feb 18 19:33:27 2002 +0000
@@ -273,6 +273,97 @@
     }
 }
 
+static int h263_pred_dc(MpegEncContext * s, int n, UINT16 **dc_val_ptr)
+{
+    int a, c, x, y, wrap, pred, scale;
+    UINT16 *dc_val;
+
+    /* find prediction */
+    if (n < 4) {
+        x = 2 * s->mb_x + 1 + (n & 1);
+        y = 2 * s->mb_y + 1 + ((n & 2) >> 1);
+        wrap = s->mb_width * 2 + 2;
+        dc_val = s->dc_val[0];
+        scale = s->y_dc_scale;
+    } else {
+        x = s->mb_x + 1;
+        y = s->mb_y + 1;
+        wrap = s->mb_width + 2;
+        dc_val = s->dc_val[n - 4 + 1];
+        scale = s->c_dc_scale;
+    }
+
+    /* B C
+     * A X 
+     */
+    a = dc_val[(x - 1) + (y) * wrap];
+    c = dc_val[(x) + (y - 1) * wrap];
+    
+    if (s->ac_pred) {
+        if (s->h263_aic_dir)
+            pred = a;
+        else
+            pred = c;
+    } else if (a != 1024 && c != 1024)
+        pred = (a + c) >> 1;
+    else if (a != 1024)
+        pred = a;
+    else
+        pred = c;
+        
+    
+    /* we assume pred is positive */
+    pred = (pred) / scale;
+
+    /* prepare address for prediction update */
+    *dc_val_ptr = &dc_val[(x) + (y) * wrap];
+
+    return pred;
+}
+
+void h263_pred_ac(MpegEncContext * s, INT16 *block, int n)
+{
+    int x, y, wrap, i;
+    INT16 *ac_val, *ac_val1;
+
+    /* find prediction */
+    if (n < 4) {
+        x = 2 * s->mb_x + 1 + (n & 1);
+        y = 2 * s->mb_y + 1 + ((n & 2) >> 1);
+        wrap = s->mb_width * 2 + 2;
+        ac_val = s->ac_val[0][0];
+    } else {
+        x = s->mb_x + 1;
+        y = s->mb_y + 1;
+        wrap = s->mb_width + 2;
+        ac_val = s->ac_val[n - 4 + 1][0];
+    }
+    ac_val += ((y) * wrap + (x)) * 16;
+    ac_val1 = ac_val;
+
+    if (s->ac_pred) {
+        if (s->h263_aic_dir) {
+            /* left prediction */
+            ac_val -= 16;
+            for(i=1;i<8;i++) {
+                block[block_permute_op(i*8)] += ac_val[i];
+            }
+        } else {
+            /* top prediction */
+            ac_val -= 16 * wrap;
+            for(i=1;i<8;i++) {
+                block[block_permute_op(i)] += ac_val[i + 8];
+            }
+        }
+    }
+    /* left copy */
+    for(i=1;i<8;i++)
+        ac_val1[i] = block[block_permute_op(i * 8)];
+    /* top copy */
+    for(i=1;i<8;i++)
+        ac_val1[8 + i] = block[block_permute_op(i)];
+}
+
 static inline int mid_pred(int a, int b, int c)
 {
     int vmin, vmax;
@@ -821,8 +912,10 @@
                  &mvtab[0][0], 2, 1);
         init_rl(&rl_inter);
         init_rl(&rl_intra);
+        init_rl(&rl_intra_aic);
         init_vlc_rl(&rl_inter);
         init_vlc_rl(&rl_intra);
+        init_vlc_rl(&rl_intra_aic);
         init_vlc(&dc_lum, 9, 13,
                  &DCtab_lum[0][1], 2, 1,
                  &DCtab_lum[0][0], 2, 1);
@@ -959,8 +1052,10 @@
         }
     } else {
         s->ac_pred = 0;
-	    if (s->h263_pred) {
+        if (s->h263_pred || s->h263_aic) {
             s->ac_pred = get_bits1(&s->gb);
+            if (s->ac_pred && s->h263_aic)
+                s->h263_aic_dir = get_bits1(&s->gb);
         }
         cbpy = get_vlc(&s->gb, &cbpy_vlc);
         cbp = (cbpc & 3) | (cbpy << 2);
@@ -1059,9 +1154,21 @@
 {
     int code, level, i, j, last, run;
     RLTable *rl = &rl_inter;
+    UINT16 *dc_val;
+    const UINT8 *scan_table;
 
-    if (s->mb_intra) {
-	/* DC coef */
+    scan_table = zigzag_direct;
+    if (s->h263_aic) {
+        rl = &rl_intra_aic;
+        i = 0;
+        if (s->ac_pred) {
+            if (s->h263_aic_dir) 
+                scan_table = ff_alternate_vertical_scan; /* left */
+            else
+                scan_table = ff_alternate_horizontal_scan; /* top */
+        }
+    } else if (s->mb_intra) {
+        /* DC coef */
         if (s->h263_rv10 && s->rv10_version == 3 && s->pict_type == I_TYPE) {
             int component, diff;
             component = (n <= 3 ? 0 : n - 4 + 1);
@@ -1082,11 +1189,21 @@
                 level = 128;
         }
         block[0] = level;
-	i = 1;
+        i = 1;
     } else {
-	i = 0;
+        i = 0;
     }
     if (!coded) {
+        if (s->mb_intra && s->h263_aic) {
+            level = h263_pred_dc(s, n, &dc_val);
+            if (level < 0)
+                level = 0;
+            *dc_val = level * s->y_dc_scale;  
+            block[0] = level;
+            h263_pred_ac(s, block, n);
+            i = 64;
+            //i = 1;
+        }
         s->block_last_index[n] = i - 1;
         return 0;
     }
@@ -1112,15 +1229,29 @@
             if (get_bits1(&s->gb))
                 level = -level;
         }
+        if (!i && s->h263_aic) {
+            level += h263_pred_dc(s, n, &dc_val);
+            if (level < 0)
+                level = 0;
+            else if (level & 1)
+                level++;
+            *dc_val = level * s->y_dc_scale;
+            
+        }
         i += run;
         if (i >= 64)
             return -1;
-	j = zigzag_direct[i];
+        j = scan_table[i];
         block[j] = level;
         if (last)
             break;
         i++;
     }
+    
+    if (s->h263_aic) {
+        h263_pred_ac(s, block, n);
+        i = 64;
+    }
     s->block_last_index[n] = i;
     return 0;
 }
@@ -1325,7 +1456,10 @@
             if (get_bits1(&s->gb) != 0) {
                 s->mv_type = MV_TYPE_8X8; /* Advanced prediction mode */
             }
-            skip_bits(&s->gb, 8);
+            if (get_bits1(&s->gb) != 0) { /* Advanced Intra Coding (AIC) */
+                s->h263_aic = 1;
+            }
+            skip_bits(&s->gb, 7);
             skip_bits(&s->gb, 3); /* Reserved */
         } else if (ufep != 0)
             return -1;
--- a/h263data.h	Mon Feb 18 09:40:05 2002 +0000
+++ b/h263data.h	Mon Feb 18 19:33:27 2002 +0000
@@ -125,6 +125,47 @@
     inter_level,
 };
 
+/* table used for Advanced INTRA Coding, just RUN and LEVEL change */
+const INT8 inter_level_aic[102] = {
+  1,  1,  1,  1,  1,  1,  1,  1,
+  1,  3,  2,  1,  2,  2,  4,  5,
+  6,  7,  3,  2,  3,  4,  5,  2,
+  3,  4,  2,  3,  1,  2, 25,  1,
+  2, 24,  8,  2,  7,  4,  6,  1,
+  9, 23,  2,  3,  1, 10, 12, 11,
+ 18, 17, 16, 15, 14, 13, 20, 19,
+ 22, 21,  1,  1,  1,  1,  1,  1,
+  1,  2,  1,  1,  1,  3,  1,  1,
+  1,  1,  1,  1,  1,  4,  1,  1,
+  1,  1,  2,  2,  6,  5,  2,  2,
+  3,  7,  3,  4,  9,  8,  1,  1,
+  1,  2,  2,  2,  3, 10,
+};
+
+const INT8 inter_run_aic[102] = {
+  0,  1,  3,  5,  7,  8,  9, 10,
+ 11,  4,  9, 13,  0,  1,  1,  1,
+  1,  1,  0,  3,  2,  3,  0,  4,
+  3,  0,  5,  5,  2,  6,  0,  4,
+  7,  0,  0,  8,  0,  2,  0, 12,
+  0,  0,  2,  1,  6,  0,  0,  0,
+  0,  0,  0,  0,  0,  0,  0,  0,
+  0,  0,  0, 14, 20,  1, 19,  2,
+  3,  0,  5,  6,  4,  0,  9, 10,
+ 11, 12, 13,  8,  7,  0, 17, 18,
+ 16, 15,  2,  1,  0,  0,  4,  3,
+  1,  0,  2,  1,  0,  0, 21, 22,
+ 23,  7,  6,  5,  3,  0,
+};
+
+static RLTable rl_intra_aic = {
+    102,
+    58,
+    inter_vlc,
+    inter_run_aic,
+    inter_level_aic,
+};
+
 static const UINT16 h263_format[8][2] = {
     { 0, 0 },
     { 128, 96 },
--- a/h263dec.c	Mon Feb 18 09:40:05 2002 +0000
+++ b/h263dec.c	Mon Feb 18 19:33:27 2002 +0000
@@ -156,6 +156,9 @@
                 msmpeg4_dc_scale(s);
             } else if (s->h263_pred) {
                 h263_dc_scale(s);
+            } else if (s->h263_aic) {
+                s->y_dc_scale = s->qscale;
+                s->c_dc_scale = s->qscale;                
             } else {
                 /* default quantization values */
                 s->y_dc_scale = 8;
--- a/i386/mpegvideo_mmx.c	Mon Feb 18 09:40:05 2002 +0000
+++ b/i386/mpegvideo_mmx.c	Mon Feb 18 19:33:27 2002 +0000
@@ -83,7 +83,10 @@
     int i, level, qmul, qadd, nCoeffs;
     
     qmul = s->qscale << 1;
-    qadd = (s->qscale - 1) | 1;
+    if (s->h263_aic && s->mb_intra)
+        qadd = 0;
+    else
+        qadd = (s->qscale - 1) | 1;
 
     if (s->mb_intra) {
         if (n < 4)
--- a/mpegvideo.c	Mon Feb 18 09:40:05 2002 +0000
+++ b/mpegvideo.c	Mon Feb 18 19:33:27 2002 +0000
@@ -181,7 +181,7 @@
         memset(s->motion_val, 0, size * 2 * sizeof(INT16));
     }
 
-    if (s->h263_pred) {
+    if (s->h263_pred || s->h263_plus) {
         int y_size, c_size, i, size;
         
         /* dc values */
@@ -1062,10 +1062,20 @@
                 sub_pixels_2(s->block[5], ptr, s->linesize >> 1, dxy);
             }
             emms_c();
-            //if (s->avg_mb_var)
-            //    printf("\nqscale=%2d dquant=%2d var=%4d avgvar=%4d", s->qscale,
-            //        s->qscale*(s->mb_var[s->mb_width*mb_y+mb_x]/s->avg_mb_var),
-            //        s->mb_var[s->mb_width*mb_y+mb_x], s->avg_mb_var);
+            
+#if 0
+            {
+                float adap_parm;
+                
+                adap_parm = ((s->avg_mb_var << 1) + s->mb_var[s->mb_width*mb_y+mb_x] + 1.0) /
+                            ((s->mb_var[s->mb_width*mb_y+mb_x] << 1) + s->avg_mb_var + 1.0);
+            
+                printf("\ntype=%c qscale=%2d adap=%0.2f dquant=%4.2f var=%4d avgvar=%4d", 
+                        (s->mb_type[s->mb_width*mb_y+mb_x] > 0) ? 'I' : 'P', 
+                        s->qscale, adap_parm, s->qscale*adap_parm,
+                        s->mb_var[s->mb_width*mb_y+mb_x], s->avg_mb_var);
+            }
+#endif
             /* DCT & quantize */
             if (s->h263_msmpeg4) {
                 msmpeg4_dc_scale(s);
@@ -1331,7 +1341,10 @@
     }
 
     qmul = s->qscale << 1;
-    qadd = (s->qscale - 1) | 1;
+    if (s->h263_aic && s->mb_intra)
+        qadd = 0;
+    else
+        qadd = (s->qscale - 1) | 1;
 
     for(;i<nCoeffs;i++) {
         level = block[i];
@@ -1407,12 +1420,13 @@
         q = 31;
     qscale = (int)(q + 0.5);
 #if defined(DEBUG)
-    printf("%d: total=%0.0f br=%0.1f diff=%d qest=%0.1f\n", 
+    printf("\n%d: total=%0.0f wanted=%0.0f br=%0.1f diff=%d qest=%2.1f\n", 
            s->picture_number, 
            (double)total_bits, 
+           (double)s->wanted_bits,
            (float)s->frame_rate / FRAME_RATE_BASE * 
            total_bits / s->picture_number, 
-           diff, q);
+           (int)diff, q);
 #endif
     return qscale;
 }
--- a/mpegvideo.h	Mon Feb 18 09:40:05 2002 +0000
+++ b/mpegvideo.h	Mon Feb 18 19:33:27 2002 +0000
@@ -146,10 +146,12 @@
     int gob_number;
     int gob_index;
     int first_gob_line;
-    
+        
     /* H.263+ specific */
     int umvplus;
     int umvplus_dec;
+    int h263_aic; /* Advanded INTRA Coding (AIC) */
+    int h263_aic_dir; /* AIC direction: 0 = left, 1 = top */
     
     /* mpeg4 specific */
     int time_increment_bits;