divx 5.01 support
authorMichael Niedermayer <michaelni@gmx.at>
Mon, 22 Apr 2002 12:45:22 +0000 (12:45 +0000)
committerMichael Niedermayer <michaelni@gmx.at>
Mon, 22 Apr 2002 12:45:22 +0000 (12:45 +0000)
Originally committed as revision 412 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavcodec/h263.c
libavcodec/h263dec.c
libavcodec/mpegvideo.c
libavcodec/mpegvideo.h

index 51334809682c13982fd3c145018b984ea210a715..7638942cd37da84a0ed1406df6f9bf6a30690611 100644 (file)
@@ -2564,8 +2564,13 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
         }
         state = ((state << 8) | v) & 0xffffff;
         if( get_bits_count(&s->gb) > s->gb.size*8-32){
-            printf("no VOP startcode found\n");
-            return -1;
+            if(s->gb.size>50){
+                printf("no VOP startcode found, frame size was=%d\n", s->gb.size);
+                return -1;
+            }else{
+                printf("frame skip\n");
+                return FRAME_SKIPED;
+            }
         }
     }
 //printf("startcode %X %d\n", startcode, get_bits_count(&s->gb));
@@ -2763,16 +2768,20 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
         }
         buf[255]=0;
         e=sscanf(buf, "DivX%dBuild%d", &ver, &build);
+        if(e!=2)
+            e=sscanf(buf, "DivX%db%d", &ver, &build);
         if(e==2){
             s->divx_version= ver;
             s->divx_build= build;
             if(s->picture_number==0){
                 printf("This file was encoded with DivX%d Build%d\n", ver, build);
-                if(ver==500 && build==413){ //most likely all version are indeed totally buggy but i dunno for sure ...
+                if(ver==500 && build==413){
                     printf("WARNING: this version of DivX is not MPEG4 compatible, trying to workaround these bugs...\n");
+#if 0
                 }else{
                     printf("hmm, i havnt seen that version of divx yet, lets assume they fixed these bugs ...\n"
                            "using mpeg4 decoder, if it fails contact the developers (of ffmpeg)\n");
+#endif 
                 }
             }
         }
@@ -2887,6 +2896,7 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
          }
      }
      s->picture_number++; // better than pic number==0 allways ;)
+//printf("done\n");
      return 0;
 }
 
index 5a3d331865c320cd6025e1e7936ed30e3f7c4c6c..b3e11b9bcd48556b0a26ef50144c10033a477606 100644 (file)
@@ -119,7 +119,10 @@ static int h263_decode_frame(AVCodecContext *avctx,
         return 0;
     }
 
-    init_get_bits(&s->gb, buf, buf_size);
+    if(s->bitstream_buffer_size) //divx 5.01+ frame reorder
+        init_get_bits(&s->gb, s->bitstream_buffer, s->bitstream_buffer_size);
+    else
+        init_get_bits(&s->gb, buf, buf_size);
 
     /* let's go :-) */
     if (s->h263_msmpeg4) {
@@ -131,6 +134,7 @@ static int h263_decode_frame(AVCodecContext *avctx,
     } else {
         ret = h263_decode_picture_header(s);
     }
+    if(ret==FRAME_SKIPED) return 0;
 
         /* After H263 & mpeg4 header decode we have the height, width,*/
         /* and other parameters. So then we could init the picture   */
@@ -241,7 +245,18 @@ static int h263_decode_frame(AVCodecContext *avctx,
     
     if (s->h263_msmpeg4 && s->msmpeg4_version<4 && s->pict_type==I_TYPE)
         if(msmpeg4_decode_ext_header(s, buf_size) < 0) return -1;
-
+    
+    /* divx 5.01+ bistream reorder stuff */
+    if(s->h263_pred && s->bitstream_buffer_size==0){
+        int current_pos= get_bits_count(&s->gb)/8;
+        if(   buf_size - current_pos > 5 
+           && buf_size - current_pos < BITSTREAM_BUFFER_SIZE){
+            memcpy(s->bitstream_buffer, buf + current_pos, buf_size - current_pos);
+            s->bitstream_buffer_size= buf_size - current_pos;
+        }
+    }else
+        s->bitstream_buffer_size=0;
+  
     MPV_frame_end(s);
     
     if(s->pict_type==B_TYPE || (!s->has_b_frames)){
index 112d684373c1ca42283f96f5ca601dbb1330aad8..5885fd73d2b8666bd9e1797301dfc83f5e6de912 100644 (file)
@@ -292,6 +292,11 @@ int MPV_common_init(MpegEncContext *s)
         if (!s->mbintra_table)
             goto fail;
         memset(s->mbintra_table, 1, s->mb_num);
+        
+        /* divx501 bitstream reorder buffer */
+        s->bitstream_buffer= av_mallocz(BITSTREAM_BUFFER_SIZE);
+        if (!s->bitstream_buffer)
+            goto fail;
     }
     /* default structure is frame */
     s->picture_structure = PICT_FRAME;
@@ -340,6 +345,7 @@ void MPV_common_end(MpegEncContext *s)
     CHECK_FREE(s->me_scratchpad);
 
     CHECK_FREE(s->mbskip_table);
+    CHECK_FREE(s->bitstream_buffer);
     for(i=0;i<3;i++) {
         int j;
         CHECK_FREE(s->last_picture_base[i]);
index b0aebe89547e3b278b78af52da9304c20fce1a92..c5335aba195fd65ceee72286980b2a39f41aa69b 100644 (file)
@@ -23,6 +23,8 @@
 #define B_TYPE 3
 #define S_TYPE 4 //S(GMC)-VOP MPEG4
 
+#define FRAME_SKIPED 100 // return value for header parsers if frame is not coded
+
 enum OutputFormat {
     FMT_MPEG1,
     FMT_H263,
@@ -298,7 +300,10 @@ typedef struct MpegEncContext {
     /* divx specific, used to workaround (many) bugs in divx5 */
     int divx_version;
     int divx_build;
-
+#define BITSTREAM_BUFFER_SIZE 1024*256
+    uint8_t *bitstream_buffer; //Divx 5.01 puts several frames in a single one, this is used to reorder them
+    int bitstream_buffer_size;
+    
     /* RV10 specific */
     int rv10_version; /* RV10 version: 0 or 3 */
     int rv10_first_dc_coded[3];