From ae40484c1ca6df311803f2061cda9f0b85c320f4 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <michaelni@gmx.at>
Date: Tue, 15 Jan 2002 22:22:41 +0000
Subject: [PATCH] (commit by michael) bye bye weird al rounding bug ;)

Originally committed as revision 268 to svn://svn.ffmpeg.org/ffmpeg/trunk
---
 libavcodec/h263dec.c   |  3 ++
 libavcodec/mpegvideo.c |  4 +++
 libavcodec/mpegvideo.h |  4 +++
 libavcodec/msmpeg4.c   | 73 ++++++++++++++++++++++++++++++++++++++----
 4 files changed, 78 insertions(+), 6 deletions(-)

diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c
index 5e79e20051b..aadeb8bd682 100644
--- a/libavcodec/h263dec.c
+++ b/libavcodec/h263dec.c
@@ -211,6 +211,9 @@ static int h263_decode_frame(AVCodecContext *avctx,
                                    y, s->width, h);
         }
     }
+    
+    if (s->h263_msmpeg4)
+        if(msmpeg4_decode_ext_header(s, buf_size) < 0) return -1;
 
     MPV_frame_end(s);
     
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index 432ab8cccf7..c3143ca9957 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -1052,6 +1052,10 @@ static void encode_picture(MpegEncContext *s, int picture_number)
         //                    (s->pb.buf_ptr - s->ptr_last_mb_line), s->mb_line_avgsize);
         s->ptr_last_mb_line = s->pb.buf_ptr;
     }
+    
+    if (s->h263_msmpeg4) 
+        msmpeg4_encode_ext_header(s);
+
     //if (s->gob_number)
     //    fprintf(stderr,"\nNumber of GOB: %d", s->gob_number);
 }
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 9a74b7999c4..03ddfc8de51 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -160,6 +160,8 @@ typedef struct MpegEncContext {
     int use_skip_mb_code;
     int slice_height;      /* in macroblocks */
     int first_slice_line;  
+    int flipflop_rounding;
+    int bitrate;
     /* decompression specific */
     GetBitContext gb;
 
@@ -284,11 +286,13 @@ int rv_decode_dc(MpegEncContext *s, int n);
 
 /* msmpeg4.c */
 void msmpeg4_encode_picture_header(MpegEncContext * s, int picture_number);
+void msmpeg4_encode_ext_header(MpegEncContext * s);
 void msmpeg4_encode_mb(MpegEncContext * s, 
                        DCTELEM block[6][64],
                        int motion_x, int motion_y);
 void msmpeg4_dc_scale(MpegEncContext * s);
 int msmpeg4_decode_picture_header(MpegEncContext * s);
+int msmpeg4_decode_ext_header(MpegEncContext * s, int buf_size);
 int msmpeg4_decode_mb(MpegEncContext *s, 
                       DCTELEM block[6][64]);
 int msmpeg4_decode_init_vlc(MpegEncContext *s);
diff --git a/libavcodec/msmpeg4.c b/libavcodec/msmpeg4.c
index d737bbca47d..db767422dc7 100644
--- a/libavcodec/msmpeg4.c
+++ b/libavcodec/msmpeg4.c
@@ -185,7 +185,12 @@ void msmpeg4_encode_picture_header(MpegEncContext * s, int picture_number)
         put_bits(&s->pb, 1, s->dc_table_index);
 
         put_bits(&s->pb, 1, s->mv_table_index);
-        s->no_rounding ^= 1;
+	
+	if(s->flipflop_rounding){
+	    s->no_rounding ^= 1;
+	}else{
+	    s->no_rounding = 0;
+	}
     }
 
     if (!init_done) {
@@ -203,6 +208,27 @@ void msmpeg4_encode_picture_header(MpegEncContext * s, int picture_number)
 #endif
 }
 
+void msmpeg4_encode_ext_header(MpegEncContext * s)
+{
+    if(s->pict_type == P_TYPE)
+    {
+	return; // P-Frames dont seem to have them and not even a 0 bit
+    }
+    else
+    {
+        s->flipflop_rounding=1;
+        s->bitrate= 910;
+
+	put_bits(&s->pb, 1, 1); // ext header indicator
+
+	put_bits(&s->pb, 4, 7); // ?
+
+	put_bits(&s->pb, 11, s->bitrate);
+
+	put_bits(&s->pb, 1, s->flipflop_rounding);
+    }
+}
+
 /* predict coded block */
 static inline int coded_block_pred(MpegEncContext * s, int n, UINT8 **coded_block_ptr)
 {
@@ -654,7 +680,6 @@ static int decode012(GetBitContext *gb)
 int msmpeg4_decode_picture_header(MpegEncContext * s)
 {
     int code;
-static int weirdAl=0;
 
     s->pict_type = get_bits(&s->gb, 2) + 1;
     if (s->pict_type != I_TYPE &&
@@ -696,17 +721,53 @@ static int weirdAl=0;
 		s->rl_chroma_table_index, 
 		s->dc_table_index,
 		s->mv_table_index);*/
-  if(weirdAl)
-	s->no_rounding = 0;
-  else
-	s->no_rounding ^= 1;
+	if(s->flipflop_rounding){
+	    s->no_rounding ^= 1;
+	}else{
+	    s->no_rounding = 0;
+	}
+//	printf("%d", s->no_rounding);
     }
+    
+   
 #ifdef DEBUG
     printf("*****frame %d:\n", frame_count++);
 #endif
     return 0;
 }
 
+int msmpeg4_decode_ext_header(MpegEncContext * s, int buf_size)
+{
+    int firstBit=0;
+    
+    /* the alt_bitstream reader could read over the end so we need to check it */
+    if(get_bits_count(&s->gb) < buf_size*8) firstBit= get_bits1(&s->gb);
+    
+    if(s->pict_type == P_TYPE)
+    {
+        if(firstBit) return -1; // havnt seen ext headers in P-Frames yet ;)
+    }
+    else
+    {
+        int unk;
+	if(!firstBit) // no header found
+	{
+	    s->flipflop_rounding= 0;
+	    s->bitrate= 0;
+	    return 0;
+	}
+	
+	unk= get_bits(&s->gb, 4);
+	s->bitrate= get_bits(&s->gb, 11);
+	
+//	printf("%2d %4d ;; %1X\n", unk,s->bitrate, unk);
+    
+	s->flipflop_rounding= get_bits1(&s->gb);
+    }
+    
+    return 0;
+}
+
 void memsetw(short *tab, int val, int n)
 {
     int i;
-- 
GitLab