[SCM] libav/experimental: - H.263+ decoder support for Advanded INTRA Coding (buggy)

siretart at users.alioth.debian.org siretart at users.alioth.debian.org
Sun Jun 30 15:31:04 UTC 2013


The following commit has been merged in the experimental branch:
commit d140623fc44c67e8955c56c7cf74c56c94c0f064
Author: Juanjo <pulento at users.sourceforge.net>
Date:   Mon Feb 18 19:33:27 2002 +0000

    - H.263+ decoder support for Advanded INTRA Coding (buggy)
    
    Originally committed as revision 310 to svn://svn.ffmpeg.org/ffmpeg/trunk

diff --git a/libavcodec/h263.c b/libavcodec/h263.c
index dade959..e0b234b 100644
--- a/libavcodec/h263.c
+++ b/libavcodec/h263.c
@@ -273,6 +273,97 @@ void h263_encode_mb(MpegEncContext * s,
     }
 }
 
+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 @@ void h263_decode_init_vlc(MpegEncContext *s)
                  &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 @@ int h263_decode_mb(MpegEncContext *s,
         }
     } 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 @@ static int h263_decode_block(MpegEncContext * s, DCTELEM * block,
 {
     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 @@ static int h263_decode_block(MpegEncContext * s, DCTELEM * block,
                 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 @@ static int h263_decode_block(MpegEncContext * s, DCTELEM * block,
             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 @@ int h263_decode_picture_header(MpegEncContext *s)
             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;
diff --git a/libavcodec/h263data.h b/libavcodec/h263data.h
index d41996a..88e456b 100644
--- a/libavcodec/h263data.h
+++ b/libavcodec/h263data.h
@@ -125,6 +125,47 @@ static RLTable rl_inter = {
     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 },
diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c
index ea628bf..e0a5f67 100644
--- a/libavcodec/h263dec.c
+++ b/libavcodec/h263dec.c
@@ -156,6 +156,9 @@ static int h263_decode_frame(AVCodecContext *avctx,
                 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;
diff --git a/libavcodec/i386/mpegvideo_mmx.c b/libavcodec/i386/mpegvideo_mmx.c
index 3ca40ca..542d2d8 100644
--- a/libavcodec/i386/mpegvideo_mmx.c
+++ b/libavcodec/i386/mpegvideo_mmx.c
@@ -83,7 +83,10 @@ static void dct_unquantize_h263_mmx(MpegEncContext *s,
     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)
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index a8e1907..d67dffe 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -181,7 +181,7 @@ int MPV_common_init(MpegEncContext *s)
         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 @@ static void encode_picture(MpegEncContext *s, int picture_number)
                 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 @@ static void dct_unquantize_h263_c(MpegEncContext *s,
     }
 
     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 @@ static int rate_estimate_qscale(MpegEncContext *s)
         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;
 }
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index acbb123..8b39746 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -146,10 +146,12 @@ typedef struct MpegEncContext {
     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;

-- 
Libav/FFmpeg packaging



More information about the pkg-multimedia-commits mailing list