changeset 307:764aeec1320e libavcodec

msmpeg4v2 decoding (no encoding yet)
author michaelni
date Fri, 05 Apr 2002 04:09:04 +0000
parents ebfd518cbbbf
children 072c4ff05e62
files avcodec.h h263data.h h263dec.c mpeg4data.h mpegvideo.c mpegvideo.h msmpeg4.c msmpeg4data.h utils.c
diffstat 9 files changed, 392 insertions(+), 99 deletions(-) [+]
line wrap: on
line diff
--- a/avcodec.h	Thu Apr 04 20:04:10 2002 +0000
+++ b/avcodec.h	Fri Apr 05 04:09:04 2002 +0000
@@ -14,7 +14,9 @@
     CODEC_ID_MJPEG,
     CODEC_ID_MPEG4,
     CODEC_ID_RAWVIDEO,
-    CODEC_ID_MSMPEG4,
+    CODEC_ID_MSMPEG4V1,
+    CODEC_ID_MSMPEG4V2,
+    CODEC_ID_MSMPEG4V3,
     CODEC_ID_H263P,
     CODEC_ID_H263I,
 
@@ -28,6 +30,7 @@
     CODEC_ID_PCM_MULAW,
     CODEC_ID_PCM_ALAW,
 };
+#define CODEC_ID_MSMPEG4 CODEC_ID_MSMPEG4V3
 
 enum CodecType {
     CODEC_TYPE_VIDEO,
@@ -200,11 +203,15 @@
 extern AVCodec rv10_encoder;
 extern AVCodec mjpeg_encoder;
 extern AVCodec mpeg4_encoder;
-extern AVCodec msmpeg4_encoder;
+extern AVCodec msmpeg4v1_encoder;
+extern AVCodec msmpeg4v2_encoder;
+extern AVCodec msmpeg4v3_encoder;
 
 extern AVCodec h263_decoder;
 extern AVCodec mpeg4_decoder;
-extern AVCodec msmpeg4_decoder;
+extern AVCodec msmpeg4v1_decoder;
+extern AVCodec msmpeg4v2_decoder;
+extern AVCodec msmpeg4v3_decoder;
 extern AVCodec mpeg_decoder;
 extern AVCodec h263i_decoder;
 extern AVCodec rv10_decoder;
--- a/h263data.h	Thu Apr 04 20:04:10 2002 +0000
+++ b/h263data.h	Fri Apr 05 04:09:04 2002 +0000
@@ -40,13 +40,13 @@
     3, 7, 7, 8,
 };*/
 
-static const UINT8 cbpy_tab[16][2] =
+const UINT8 cbpy_tab[16][2] =
 {
   {3,4}, {5,5}, {4,5}, {9,4}, {3,5}, {7,4}, {2,6}, {11,4},
   {2,5}, {3,6}, {5,4}, {10,4}, {4,4}, {8,4}, {6,4}, {3,2}
 };
 
-static const UINT8 mvtab[33][2] =
+const UINT8 mvtab[33][2] =
 {
   {1,1}, {1,2}, {1,3}, {1,4}, {3,6}, {5,7}, {4,7}, {3,7},
   {11,9}, {10,9}, {9,9}, {17,10}, {16,10}, {15,10}, {14,10}, {13,10},
--- a/h263dec.c	Thu Apr 04 20:04:10 2002 +0000
+++ b/h263dec.c	Fri Apr 05 04:09:04 2002 +0000
@@ -47,9 +47,20 @@
         s->h263_pred = 1;
         s->has_b_frames = 1;
         break;
-    case CODEC_ID_MSMPEG4:
+    case CODEC_ID_MSMPEG4V1:
         s->h263_msmpeg4 = 1;
         s->h263_pred = 1;
+        s->msmpeg4_version=1;
+        break;
+    case CODEC_ID_MSMPEG4V2:
+        s->h263_msmpeg4 = 1;
+        s->h263_pred = 1;
+        s->msmpeg4_version=2;
+        break;
+    case CODEC_ID_MSMPEG4V3:
+        s->h263_msmpeg4 = 1;
+        s->h263_pred = 1;
+        s->msmpeg4_version=3;
         break;
     case CODEC_ID_H263I:
         s->h263_intel = 1;
@@ -269,10 +280,34 @@
     CODEC_CAP_DRAW_HORIZ_BAND,
 };
 
-AVCodec msmpeg4_decoder = {
+AVCodec msmpeg4v1_decoder = {
+    "msmpeg4v1",
+    CODEC_TYPE_VIDEO,
+    CODEC_ID_MSMPEG4V1,
+    sizeof(MpegEncContext),
+    h263_decode_init,
+    NULL,
+    h263_decode_end,
+    h263_decode_frame,
+    CODEC_CAP_DRAW_HORIZ_BAND,
+};
+
+AVCodec msmpeg4v2_decoder = {
+    "msmpeg4v2",
+    CODEC_TYPE_VIDEO,
+    CODEC_ID_MSMPEG4V2,
+    sizeof(MpegEncContext),
+    h263_decode_init,
+    NULL,
+    h263_decode_end,
+    h263_decode_frame,
+    CODEC_CAP_DRAW_HORIZ_BAND,
+};
+
+AVCodec msmpeg4v3_decoder = {
     "msmpeg4",
     CODEC_TYPE_VIDEO,
-    CODEC_ID_MSMPEG4,
+    CODEC_ID_MSMPEG4V3,
     sizeof(MpegEncContext),
     h263_decode_init,
     NULL,
--- a/mpeg4data.h	Thu Apr 04 20:04:10 2002 +0000
+++ b/mpeg4data.h	Fri Apr 05 04:09:04 2002 +0000
@@ -12,13 +12,13 @@
 #define GMC_SPRITE 2
 
 /* dc encoding for mpeg4 */
-static const UINT8 DCtab_lum[13][2] =
+const UINT8 DCtab_lum[13][2] =
 {
     {3,3}, {3,2}, {2,2}, {2,3}, {1,3}, {1,4}, {1,5}, {1,6}, {1,7},
     {1,8}, {1,9}, {1,10}, {1,11},
 }; 
 
-static const UINT8 DCtab_chrom[13][2] =
+const UINT8 DCtab_chrom[13][2] =
 {
     {3,2}, {2,2}, {1,2}, {1,3}, {1,4}, {1,5}, {1,6}, {1,7}, {1,8},
     {1,9}, {1,10}, {1,11}, {1,12},
@@ -103,3 +103,22 @@
 static const UINT8 mb_type_b_tab[4][2] = {
  {1, 1}, {1, 2}, {1, 3}, {1, 4},
 };
+
+static const UINT16 pixel_aspect[16][2]={
+ {0, 0},
+ {1, 1},
+ {12, 11},
+ {10, 11},
+ {16, 11},
+ {40, 33},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+};
--- a/mpegvideo.c	Thu Apr 04 20:04:10 2002 +0000
+++ b/mpegvideo.c	Fri Apr 05 04:09:04 2002 +0000
@@ -355,11 +355,26 @@
         s->h263_pred = 1;
         s->unrestricted_mv = 1;
         break;
-    case CODEC_ID_MSMPEG4:
+    case CODEC_ID_MSMPEG4V1:
         s->out_format = FMT_H263;
         s->h263_msmpeg4 = 1;
         s->h263_pred = 1;
         s->unrestricted_mv = 1;
+        s->msmpeg4_version= 1;
+        break;
+    case CODEC_ID_MSMPEG4V2:
+        s->out_format = FMT_H263;
+        s->h263_msmpeg4 = 1;
+        s->h263_pred = 1;
+        s->unrestricted_mv = 1;
+        s->msmpeg4_version= 2;
+        break;
+    case CODEC_ID_MSMPEG4V3:
+        s->out_format = FMT_H263;
+        s->h263_msmpeg4 = 1;
+        s->h263_pred = 1;
+        s->unrestricted_mv = 1;
+        s->msmpeg4_version= 3;
         break;
     default:
         return -1;
@@ -2117,12 +2132,32 @@
     MPV_encode_end,
 };
 
-AVCodec msmpeg4_encoder = {
-    "msmpeg4",
+AVCodec msmpeg4v1_encoder = {
+    "msmpeg4v1",
     CODEC_TYPE_VIDEO,
-    CODEC_ID_MSMPEG4,
+    CODEC_ID_MSMPEG4V1,
     sizeof(MpegEncContext),
     MPV_encode_init,
     MPV_encode_picture,
     MPV_encode_end,
 };
+
+AVCodec msmpeg4v2_encoder = {
+    "msmpeg4v2",
+    CODEC_TYPE_VIDEO,
+    CODEC_ID_MSMPEG4V2,
+    sizeof(MpegEncContext),
+    MPV_encode_init,
+    MPV_encode_picture,
+    MPV_encode_end,
+};
+
+AVCodec msmpeg4v3_encoder = {
+    "msmpeg4",
+    CODEC_TYPE_VIDEO,
+    CODEC_ID_MSMPEG4V3,
+    sizeof(MpegEncContext),
+    MPV_encode_init,
+    MPV_encode_picture,
+    MPV_encode_end,
+};
--- a/mpegvideo.h	Thu Apr 04 20:04:10 2002 +0000
+++ b/mpegvideo.h	Fri Apr 05 04:09:04 2002 +0000
@@ -267,6 +267,7 @@
     int first_slice_line;  /* used in mpeg4 too to handle resync markers */
     int flipflop_rounding;
     int bitrate;
+    int msmpeg4_version;   /* 1=mp41, 2=mp42, 3=mp43/divx3 */
     /* decompression specific */
     GetBitContext gb;
 
--- a/msmpeg4.c	Thu Apr 04 20:04:10 2002 +0000
+++ b/msmpeg4.c	Fri Apr 05 04:09:04 2002 +0000
@@ -29,7 +29,6 @@
  * TODO: 
  *        - (encoding) select best mv table (two choices)
  *        - (encoding) select best vlc/dc table 
- *        - (decoding) handle slice indication
  */
 //#define DEBUG
 
@@ -44,6 +43,9 @@
     VLC vlc;                /* decoding: vlc */
 } MVTable;
 
+static UINT32 v2_dc_lum_table[512][2];
+static UINT32 v2_dc_chroma_table[512][2];
+
 static void msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n);
 static int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
                                 int n, int coded);
@@ -620,6 +622,72 @@
 static VLC mb_intra_vlc;
 static VLC dc_lum_vlc[2];
 static VLC dc_chroma_vlc[2];
+static VLC v2_dc_lum_vlc;
+static VLC v2_dc_chroma_vlc;
+static VLC cbpy_vlc;
+static VLC v2_intra_cbpc_vlc;
+static VLC v2_mb_type_vlc;
+static VLC v2_mv_vlc;
+
+/* this table is practically identical to the one from h263 except that its inverted */
+static void init_h263_dc_for_msmpeg4()
+{
+    static int inited=0;
+    
+    if(!inited){
+        int level, uni_code, uni_len;
+        inited=1;
+
+        for(level=-255; level<256; level++){
+            int size, v, l;
+            /* find number of bits */
+            size = 0;
+            v = abs(level);
+            while (v) {
+                v >>= 1;
+		    size++;
+            }
+
+            if (level < 0)
+                l= (-level) ^ ((1 << size) - 1);
+            else
+                l= level;
+
+            /* luminance h263 */
+            uni_code= DCtab_lum[size][0];
+            uni_len = DCtab_lum[size][1];
+            uni_code ^= (1<<uni_len)-1; //M$ doesnt like compatibility
+
+            if (size > 0) {
+                uni_code<<=size; uni_code|=l;
+                uni_len+=size;
+                if (size > 8){
+                    uni_code<<=1; uni_code|=1;
+                    uni_len++;
+                }
+            }
+            v2_dc_lum_table[level+256][0]= uni_code;
+            v2_dc_lum_table[level+256][1]= uni_len;
+
+            /* chrominance h263 */
+            uni_code= DCtab_chrom[size][0];
+            uni_len = DCtab_chrom[size][1];
+            uni_code ^= (1<<uni_len)-1; //M$ doesnt like compatibility
+            
+            if (size > 0) {
+                uni_code<<=size; uni_code|=l;
+                uni_len+=size;
+                if (size > 8){
+                    uni_code<<=1; uni_code|=1;
+                    uni_len++;
+                }
+            }
+            v2_dc_chroma_table[level+256][0]= uni_code;
+            v2_dc_chroma_table[level+256][1]= uni_len;
+
+        }
+    }
+}
 
 /* init all vlc decoding tables */
 int msmpeg4_decode_init_vlc(MpegEncContext *s)
@@ -650,6 +718,27 @@
     init_vlc(&dc_chroma_vlc[1], 9, 120, 
              &table1_dc_chroma[0][1], 8, 4,
              &table1_dc_chroma[0][0], 8, 4);
+    
+    init_h263_dc_for_msmpeg4();
+    init_vlc(&v2_dc_lum_vlc, 9, 512, 
+             &v2_dc_lum_table[0][1], 8, 4,
+             &v2_dc_lum_table[0][0], 8, 4);
+    init_vlc(&v2_dc_chroma_vlc, 9, 512, 
+             &v2_dc_chroma_table[0][1], 8, 4,
+             &v2_dc_chroma_table[0][0], 8, 4);
+    
+    init_vlc(&cbpy_vlc, 6, 16,
+             &cbpy_tab[0][1], 2, 1,
+             &cbpy_tab[0][0], 2, 1);
+    init_vlc(&v2_intra_cbpc_vlc, 3, 4,
+             &v2_intra_cbpc[0][1], 2, 1,
+             &v2_intra_cbpc[0][0], 2, 1);
+    init_vlc(&v2_mb_type_vlc, 5, 8,
+             &v2_mb_type[0][1], 2, 1,
+             &v2_mb_type[0][0], 2, 1);
+    init_vlc(&v2_mv_vlc, 9, 33,
+             &mvtab[0][1], 2, 1,
+             &mvtab[0][0], 2, 1);
 
     init_vlc(&mb_non_intra_vlc, 9, 128, 
              &table_mb_non_intra[0][1], 8, 4,
@@ -670,7 +759,7 @@
         return get_bits1(gb) + 1;
 }
 
-int msmpeg4v2_decode_picture_header(MpegEncContext * s)
+int msmpeg4_decode_picture_header(MpegEncContext * s)
 {
     int code;
 
@@ -683,72 +772,21 @@
 
     if (s->pict_type == I_TYPE) {
         code = get_bits(&s->gb, 5); 
-        /* 0x17: one slice, 0x18: three slices */
-        /* XXX: implement it */
-	//printf("%d %d %d\n", code, s->slice_height, s->first_slice_line);
+        /* 0x17: one slice, 0x18: two slices */
         if (code < 0x17)
             return -1;
         s->slice_height = s->mb_height / (code - 0x16);
-/*        s->rl_chroma_table_index = decode012(&s->gb);
-        s->rl_table_index = decode012(&s->gb);
-
-        s->dc_table_index = get_bits1(&s->gb);*/
-        s->no_rounding = 1;
-    } else {
-        s->use_skip_mb_code = get_bits1(&s->gb);
-        
-/*        s->rl_table_index = decode012(&s->gb);
-        s->rl_chroma_table_index = s->rl_table_index;
-
-        s->dc_table_index = get_bits1(&s->gb);
-
-        s->mv_table_index = get_bits1(&s->gb);*/
-	if(s->flipflop_rounding){
-	    s->no_rounding ^= 1;
-	}else{
-	    s->no_rounding = 0;
-	}
-//	printf("%d", s->no_rounding);
-    }
-
-printf("%s q:%d s:%X ", s->pict_type == I_TYPE ? "I" : "P" , s->qscale,
-                        s->pict_type == I_TYPE ? code : s->use_skip_mb_code);
-
-    return 0;
-}
+        if(s->msmpeg4_version==2){
+            s->rl_chroma_table_index = 2;
+            s->rl_table_index = 2;
 
-int msmpeg4_decode_picture_header(MpegEncContext * s)
-{
-    int code;
-#if 0
-{
-int i;
-msmpeg4v2_decode_picture_header(s);
-for(i=0; i<s->gb.size*8; i++)
-    printf("%d", get_bits1(&s->gb));
-printf("END\n");
-return -1;
-}
-#endif
-    s->pict_type = get_bits(&s->gb, 2) + 1;
-    if (s->pict_type != I_TYPE &&
-        s->pict_type != P_TYPE)
-        return -1;
+            s->dc_table_index = 0; //not used
+        }else{
+            s->rl_chroma_table_index = decode012(&s->gb);
+            s->rl_table_index = decode012(&s->gb);
 
-    s->qscale = get_bits(&s->gb, 5);
-
-    if (s->pict_type == I_TYPE) {
-        code = get_bits(&s->gb, 5); 
-        /* 0x17: one slice, 0x18: three slices */
-        /* XXX: implement it */
-	//printf("%d %d %d\n", code, s->slice_height, s->first_slice_line);
-        if (code < 0x17)
-            return -1;
-        s->slice_height = s->mb_height / (code - 0x16);
-        s->rl_chroma_table_index = decode012(&s->gb);
-        s->rl_table_index = decode012(&s->gb);
-
-        s->dc_table_index = get_bits1(&s->gb);
+            s->dc_table_index = get_bits1(&s->gb);
+        }
         s->no_rounding = 1;
 /*	printf(" %d %d %d %d     \n", 
 		s->qscale,
@@ -758,12 +796,21 @@
     } else {
         s->use_skip_mb_code = get_bits1(&s->gb);
         
-        s->rl_table_index = decode012(&s->gb);
-        s->rl_chroma_table_index = s->rl_table_index;
+        if(s->msmpeg4_version==2){
+            s->rl_table_index = 2;
+            s->rl_chroma_table_index = s->rl_table_index;
+
+            s->dc_table_index = 0; //not used
 
-        s->dc_table_index = get_bits1(&s->gb);
+            s->mv_table_index = 0;
+        }else{
+            s->rl_table_index = decode012(&s->gb);
+            s->rl_chroma_table_index = s->rl_table_index;
 
-        s->mv_table_index = get_bits1(&s->gb);
+            s->dc_table_index = get_bits1(&s->gb);
+
+            s->mv_table_index = get_bits1(&s->gb);
+        }
 /*	printf(" %d %d %d %d %d     \n", 
 		s->use_skip_mb_code, 
 		s->rl_table_index, 
@@ -778,7 +825,20 @@
 //	printf("%d", s->no_rounding);
     }
     
-   
+#if 0
+if(s->msmpeg4_version==2)
+{
+int i;
+printf("%s q:%d s:%X ", s->pict_type == I_TYPE ? "I" : "P" , s->qscale,
+                        s->pict_type == I_TYPE ? code : s->use_skip_mb_code);
+for(i=0; i<s->gb.size*8; i++)
+//    printf("%d", get_bits1(&s->gb));
+    get_bits1(&s->gb);
+printf("END\n");
+return -1;
+}
+#endif
+
 #ifdef DEBUG
     printf("*****frame %d:\n", frame_count++);
 #endif
@@ -814,6 +874,103 @@
         tab[i] = val;
 }
 
+/* this is identical to h263 except that its range is multiplied by 2 */
+static int msmpeg4v2_decode_motion(MpegEncContext * s, int pred, int f_code)
+{
+    int code, val, sign, shift;
+
+    code = get_vlc(&s->gb, &v2_mv_vlc);
+    if (code < 0)
+        return 0xffff;
+
+    if (code == 0)
+        return pred;
+    sign = get_bits1(&s->gb);
+    shift = f_code - 1;
+    val = (code - 1) << shift;
+    if (shift > 0)
+        val |= get_bits(&s->gb, shift);
+    val++;
+    if (sign)
+        val = -val;
+    val += pred;
+
+    if (val <= -64)
+        val += 64;
+    else if (val >= 64)
+        val -= 64;
+
+    return val;
+}
+
+
+int msmpeg4v2_decode_mb(MpegEncContext *s, 
+                      DCTELEM block[6][64])
+{
+    int cbp, code, i;
+//printf("M");
+//fflush(stderr); fflush(stdout);
+    if (s->pict_type == P_TYPE) {
+        if (s->use_skip_mb_code) {
+            if (get_bits1(&s->gb)) {
+                /* skip mb */
+                s->mb_intra = 0;
+                for(i=0;i<6;i++)
+                    s->block_last_index[i] = -1;
+                s->mv_dir = MV_DIR_FORWARD;
+                s->mv_type = MV_TYPE_16X16;
+                s->mv[0][0][0] = 0;
+                s->mv[0][0][1] = 0;
+                s->mb_skiped = 1;
+                return 0;
+            }
+        }
+
+        code = get_vlc(&s->gb, &v2_mb_type_vlc);
+        s->mb_intra = code >>2;
+    
+        cbp = code & 0x3;
+    } else {
+        s->mb_intra = 1;
+//printf("%X ", show_bits(&s->gb, 24));
+        cbp= get_vlc(&s->gb, &v2_intra_cbpc_vlc);
+//printf("%X ", show_bits(&s->gb, 24));
+//printf("CBP: %X ",cbp);
+    }
+
+    if (!s->mb_intra) {
+        int mx, my;
+
+        cbp|= get_vlc(&s->gb, &cbpy_vlc)<<2;
+        if((cbp&3) != 3) cbp^= 0x3C;
+        
+        h263_pred_motion(s, 0, &mx, &my);
+        mx= msmpeg4v2_decode_motion(s, mx, 1);
+        my= msmpeg4v2_decode_motion(s, my, 1);
+        
+        s->mv_dir = MV_DIR_FORWARD;
+        s->mv_type = MV_TYPE_16X16;
+        s->mv[0][0][0] = mx;
+        s->mv[0][0][1] = my;
+    } else {
+//if(s->pict_type == P_TYPE) printf("intra cbp: %X", cbp);
+        s->ac_pred = get_bits1(&s->gb);
+//printf("AC: %d ",s->ac_pred);
+        cbp|= get_vlc(&s->gb, &cbpy_vlc)<<2;
+//printf("cbp: %X ",cbp);
+    }
+
+    for (i = 0; i < 6; i++) {
+        if (msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1) < 0)
+	{
+//fflush(stderr); fflush(stdout);
+             fprintf(stderr,"\nIgnoring error while decoding block: %d x %d (%d)\n", s->mb_x, s->mb_y, i);
+             return -1;
+	}
+    }
+    return 0;
+}
+
 int msmpeg4_decode_mb(MpegEncContext *s, 
                       DCTELEM block[6][64])
 {
@@ -850,6 +1007,8 @@
         }
     }
 
+    if(s->msmpeg4_version==2) return msmpeg4v2_decode_mb(s, block); //FIXME merge if possible
+    
     if (s->pict_type == P_TYPE) {
         set_stat(ST_INTER_MB);
         if (s->use_skip_mb_code) {
@@ -962,7 +1121,12 @@
         qadd = (s->qscale - 1) | 1;
 	i = 0;
         rl = &rl_table[3 + s->rl_table_index];
-        run_diff = 1;
+
+        if(s->msmpeg4_version==2)
+            run_diff = 0;
+        else
+            run_diff = 1;
+
         if (!coded) {
             s->block_last_index[n] = i - 1;
             return 0;
@@ -1046,21 +1210,33 @@
     int level, pred;
     INT16 *dc_val;
 
-    if (n < 4) {
-        level = get_vlc(&s->gb, &dc_lum_vlc[s->dc_table_index]);
-    } else {
-        level = get_vlc(&s->gb, &dc_chroma_vlc[s->dc_table_index]);
-    }
-    if (level < 0)
-        return -1;
+    if(s->msmpeg4_version==2){
+        if (n < 4) {
+            level = get_vlc(&s->gb, &v2_dc_lum_vlc);
+        } else {
+            level = get_vlc(&s->gb, &v2_dc_chroma_vlc);
+        }
+        if (level < 0)
+            return -1;
 
-    if (level == DC_MAX) {
-        level = get_bits(&s->gb, 8);
-        if (get_bits1(&s->gb))
-            level = -level;
-    } else if (level != 0) {
-        if (get_bits1(&s->gb))
-            level = -level;
+        level-=256;
+    }else{  //FIXME optimize use unified tables & index
+        if (n < 4) {
+            level = get_vlc(&s->gb, &dc_lum_vlc[s->dc_table_index]);
+        } else {
+            level = get_vlc(&s->gb, &dc_chroma_vlc[s->dc_table_index]);
+        }
+        if (level < 0)
+            return -1;
+
+        if (level == DC_MAX) {
+            level = get_bits(&s->gb, 8);
+            if (get_bits1(&s->gb))
+                level = -level;
+        } else if (level != 0) {
+            if (get_bits1(&s->gb))
+                level = -level;
+        }
     }
 
     pred = msmpeg4_pred_dc(s, n, &dc_val, dir_ptr);
--- a/msmpeg4data.h	Thu Apr 04 20:04:10 2002 +0000
+++ b/msmpeg4data.h	Fri Apr 05 04:09:04 2002 +0000
@@ -569,6 +569,13 @@
 extern const INT8 intra_level[102];
 extern const INT8 intra_run[102];
 
+extern const UINT8 DCtab_lum[13][2];
+extern const UINT8 DCtab_chrom[13][2];
+
+extern const UINT8 cbpy_tab[16][2];
+extern const UINT8 mvtab[33][2];
+
+
 #define NB_RL_TABLES  6
 
 static RLTable rl_table[NB_RL_TABLES] = {
@@ -1765,3 +1772,12 @@
         table1_mvy,
     }
 };
+
+static const UINT8 v2_mb_type[8][2] = {
+ {1, 1}, {0   , 2}, {3   , 3}, {9   , 5},
+ {5, 4}, {0x21, 7}, {0x20, 7}, {0x11, 6},
+};
+
+static const UINT8 v2_intra_cbpc[4][2] = {
+ {1, 1}, {0, 3}, {1, 3}, {1, 2},
+};
--- a/utils.c	Thu Apr 04 20:04:10 2002 +0000
+++ b/utils.c	Fri Apr 05 04:09:04 2002 +0000
@@ -416,7 +416,9 @@
     register_avcodec(&rv10_encoder);
     register_avcodec(&mjpeg_encoder);
     register_avcodec(&mpeg4_encoder);
-    register_avcodec(&msmpeg4_encoder);
+    register_avcodec(&msmpeg4v1_encoder);
+    register_avcodec(&msmpeg4v2_encoder);
+    register_avcodec(&msmpeg4v3_encoder);
 #endif /* CONFIG_ENCODERS */
     register_avcodec(&rawvideo_codec);
 
@@ -424,7 +426,9 @@
 #ifdef CONFIG_DECODERS
     register_avcodec(&h263_decoder);
     register_avcodec(&mpeg4_decoder);
-    register_avcodec(&msmpeg4_decoder);
+    register_avcodec(&msmpeg4v1_decoder);
+    register_avcodec(&msmpeg4v2_decoder);
+    register_avcodec(&msmpeg4v3_decoder);
     register_avcodec(&mpeg_decoder);
     register_avcodec(&h263i_decoder);
     register_avcodec(&rv10_decoder);