diff h263.c @ 248:56ee684c48bb libavcodec

- H.263+ decoder support for Advanded INTRA Coding (buggy)
author pulento
date Mon, 18 Feb 2002 19:33:27 +0000
parents a023f78e0cc2
children 42a0b7b16738
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;