- Bug fix on inter MCBPC table for inter+q.
authorJuanjo <pulento@users.sourceforge.net>
Sat, 3 Nov 2001 00:49:53 +0000 (00:49 +0000)
committerJuanjo <pulento@users.sourceforge.net>
Sat, 3 Nov 2001 00:49:53 +0000 (00:49 +0000)
- H.263/H.263+ decoder now knows GOB start codes.
- H.263/H.263+ decoder now returns the size of the stream on the first call.
- Added show_bits() functions to see the buffer without loosing the bits.
- TODO: H.263v1 UMV parsing is buggy.

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

libavcodec/common.c
libavcodec/common.h
libavcodec/h263.c
libavcodec/h263data.h
libavcodec/h263dec.c

index 2f7cafc..aa45c35 100644 (file)
@@ -250,6 +250,52 @@ void align_get_bits(GetBitContext *s)
         get_bits(s, n);
     }
 }
+/* This function is identical to get_bits_long(), the */
+/* only diference is that it doesn't touch the buffer */
+/* it is usefull to see the buffer.                   */
+
+unsigned int show_bits_long(GetBitContext *s, int n)
+{
+    unsigned int val;
+    int bit_cnt;
+    unsigned int bit_buf;
+       UINT8 *buf_ptr;
+       
+    bit_buf = s->bit_buf;
+    bit_cnt = s->bit_cnt - n;
+
+    val = bit_buf >> (32 - n);
+    buf_ptr = s->buf_ptr;
+    buf_ptr += 4;
+
+    /* handle common case: we can read everything */
+    if (buf_ptr <= s->buf_end) {
+#ifdef ARCH_X86
+        bit_buf = bswap_32(*((unsigned long*)(&buf_ptr[-4])));
+#else
+        bit_buf = (buf_ptr[-4] << 24) |
+            (buf_ptr[-3] << 16) |
+            (buf_ptr[-2] << 8) |
+            (buf_ptr[-1]);         
+#endif
+    } else {
+        buf_ptr -= 4;
+        bit_buf = 0;
+        if (buf_ptr < s->buf_end)
+            bit_buf |= *buf_ptr++ << 24;
+        if (buf_ptr < s->buf_end)
+            bit_buf |= *buf_ptr++ << 16;
+        if (buf_ptr < s->buf_end)
+            bit_buf |= *buf_ptr++ << 8;
+        if (buf_ptr < s->buf_end)
+            bit_buf |= *buf_ptr++;
+    }
+    val |= bit_buf >> (32 + bit_cnt);
+    bit_buf <<= - bit_cnt;
+    bit_cnt += 32;
+    
+    return val;
+}
 
 /* VLC decoding */
 
index aafcf5f..2b1deba 100644 (file)
@@ -196,6 +196,7 @@ void init_get_bits(GetBitContext *s,
                    UINT8 *buffer, int buffer_size);
 
 unsigned int get_bits_long(GetBitContext *s, int n);
+unsigned int show_bits_long(GetBitContext *s, int n);
 
 static inline unsigned int get_bits(GetBitContext *s, int n){
     if(s->bit_cnt>=n){
@@ -225,6 +226,19 @@ static inline unsigned int get_bits1(GetBitContext *s){
     return get_bits_long(s,1);
 }
 
+/* This function is identical to get_bits(), the only */
+/* diference is that it doesn't touch the buffer      */
+/* it is usefull to see the buffer.                   */
+static inline unsigned int show_bits(GetBitContext *s, int n)
+{
+    if(s->bit_cnt>=n) {
+        /* most common case here */
+        unsigned int val = s->bit_buf >> (32 - n);
+        return val;
+    }
+    return show_bits_long(s,n);
+}
+
 static inline void skip_bits(GetBitContext *s, int n){
     if(s->bit_cnt>=n){
         /* most common case here */
index bef779f..138276c 100644 (file)
@@ -38,7 +38,6 @@ static int h263_decode_block(MpegEncContext * s, DCTELEM * block,
 static int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
                               int n, int coded);
 
-
 int h263_get_picture_format(int width, int height)
 {
     int format;
@@ -777,9 +776,35 @@ int h263_decode_mb(MpegEncContext *s,
                    DCTELEM block[6][64])
 {
     int cbpc, cbpy, i, cbp, pred_x, pred_y, mx, my, dquant;
+    unsigned int val;
     INT16 *mot_val;
     static INT8 quant_tab[4] = { -1, -2, 1, 2 };
-
+        
+    /* Check for GOB Start Code */
+    val = show_bits(&s->gb, 16);
+    
+    if (val == 0) {
+        /* We have a GBSC probably with GSTUFF */
+#ifdef DEBUG
+        unsigned int gn, gfid;
+#endif
+        //skip_bits(&s->gb, 16); /* Drop the zeros */
+        while (get_bits1(&s->gb) == 0); /* Seek the '1' bit */
+#ifdef DEBUG
+        fprintf(stderr,"\nGOB Start Code at MB %d\n", 
+            (s->mb_y * s->mb_width) + s->mb_x);
+        gn = get_bits(&s->gb, 5); /* GN */
+        gfid = get_bits(&s->gb, 2); /* GFID */
+#else
+        skip_bits(&s->gb, 5); /* GN */
+        skip_bits(&s->gb, 2); /* GFID */
+#endif        
+        s->qscale = get_bits(&s->gb, 5); /* GQUANT */
+#ifdef DEBUG
+        fprintf(stderr, "\nGN: %u GFID: %u Quant: %u\n", gn, gfid, s->qscale);
+#endif
+    }
+    
     if (s->pict_type == P_TYPE) {
         if (get_bits1(&s->gb)) {
             /* skip mb */
@@ -794,8 +819,10 @@ int h263_decode_mb(MpegEncContext *s,
             return 0;
         }
         cbpc = get_vlc(&s->gb, &inter_MCBPC_vlc);
+        //fprintf(stderr, "\tCBPC: %d", cbpc);
         if (cbpc < 0)
             return -1;
+        
         dquant = cbpc & 8;
         s->mb_intra = ((cbpc & 4) != 0);
     } else {
@@ -866,7 +893,7 @@ int h263_decode_mb(MpegEncContext *s,
         }
     } else {
         s->ac_pred = 0;
-       if (s->h263_pred) {
+           if (s->h263_pred) {
             s->ac_pred = get_bits1(&s->gb);
         }
         cbpy = get_vlc(&s->gb, &cbpy_vlc);
@@ -1261,6 +1288,7 @@ int h263_decode_picture_header(MpegEncContext *s)
     s->f_code = 1;
     s->width = width;
     s->height = height;
+    
     return 0;
 }
 
@@ -1462,3 +1490,4 @@ int intel_h263_decode_picture_header(MpegEncContext *s)
     s->f_code = 1;
     return 0;
 }
+
index 4fd9d36..6965525 100644 (file)
@@ -4,6 +4,23 @@ static const UINT8 intra_MCBPC_code[8] = { 1, 1, 2, 3, 1, 1, 2, 3 };
 static const UINT8 intra_MCBPC_bits[8] = { 1, 3, 3, 3, 4, 6, 6, 6 };
 
 /* inter MCBPC, mb_type = (inter), (intra), (interq), (intraq), (inter4v) */
+/* Changed the tables for interq, following the standard ** Juanjo ** */
+static const UINT8 inter_MCBPC_code[20] = { 
+    1, 3, 2, 5, 
+    3, 4, 3, 3, 
+    3, 7, 6, 5,
+    4, 4, 3, 2,
+    2, 5, 4, 5,
+};
+static const UINT8 inter_MCBPC_bits[20] = { 
+    1, 4, 4, 6, 
+    5, 8, 8, 7,
+    3, 7, 7, 9,
+    6, 9, 9, 9,
+    3, 7, 7, 8,
+};
+
+/* This is the old table 
 static const UINT8 inter_MCBPC_code[20] = { 
     1, 3, 2, 5, 
     3, 4, 3, 3, 
@@ -17,7 +34,7 @@ static const UINT8 inter_MCBPC_bits[20] = {
     12, 12, 12, 12,
     6, 9, 9, 9,
     3, 7, 7, 8,
-};
+};*/
 
 static const UINT8 cbpy_tab[16][2] =
 {
index 7f2a6dd..99d7277 100644 (file)
@@ -56,8 +56,9 @@ static int h263_decode_init(AVCodecContext *avctx)
     }
 
     /* for h263, we allocate the images after having read the header */
-    if (MPV_common_init(s) < 0)
-        return -1;
+    if (avctx->codec->id != CODEC_ID_H263)
+        if (MPV_common_init(s) < 0)
+            return -1;
 
     /* XXX: suppress this matrix init, only needed because using mpeg1
        dequantize in mmx case */
@@ -92,7 +93,7 @@ static int h263_decode_frame(AVCodecContext *avctx,
     printf("*****frame %d size=%d\n", avctx->frame_number, buf_size);
     printf("bytes=%x %x %x %x\n", buf[0], buf[1], buf[2], buf[3]);
 #endif
-
+    
     /* no supplementary picture */
     if (buf_size == 0) {
         *data_size = 0;
@@ -110,6 +111,16 @@ static int h263_decode_frame(AVCodecContext *avctx,
         ret = intel_h263_decode_picture_header(s);
     } else {
         ret = h263_decode_picture_header(s);
+        /* After H263 header decode we have the height, width,     */
+        /* and other parameters. So then we could init the picture */
+        if (s->width != avctx->width || s->height != avctx->height) {
+            avctx->width = s->width;
+            avctx->height = s->height;
+            /* FIXME: By the way H263 decoder is evolving it should have */
+            /* an H263EncContext                                         */
+            if (MPV_common_init(s) < 0)
+                return -1;
+        }
     }
     if (ret < 0)
         return -1;
@@ -126,6 +137,7 @@ static int h263_decode_frame(AVCodecContext *avctx,
 #ifdef DEBUG
             printf("**mb x=%d y=%d\n", s->mb_x, s->mb_y);
 #endif
+            //fprintf(stderr,"\nFrame: %d\tMB: %d",avctx->frame_number, (s->mb_y * s->mb_width) + s->mb_x);
             /* DCT & quantize */
             if (s->h263_msmpeg4) {
                 msmpeg4_dc_scale(s);