changeset 747:3d4377531f6c libavcodec

mpeg4 header parser clenup (needed for parsing of VOL header in avctx->extradata)
author michaelni
date Mon, 14 Oct 2002 12:21:54 +0000
parents fccad7166d5a
children 14d84a5e77a4
files avcodec.h h263.c h263dec.c mpegvideo.h
diffstat 4 files changed, 367 insertions(+), 340 deletions(-) [+]
line wrap: on
line diff
--- a/avcodec.h	Sun Oct 13 19:53:32 2002 +0000
+++ b/avcodec.h	Mon Oct 14 12:21:54 2002 +0000
@@ -180,6 +180,7 @@
      * some codecs need / can use extra-data like huffman tables
      * mjpeg: huffman tables
      * rv10: additional flags
+     * mpeg4: global headers (they can be in the bitstream or here)
      * encoding: set/allocated/freed by lavc.
      * decoding: set/allocated/freed by user.
      */
--- a/h263.c	Sun Oct 13 19:53:32 2002 +0000
+++ b/h263.c	Mon Oct 14 12:21:54 2002 +0000
@@ -4040,320 +4040,290 @@
 //printf("%d %d %d %d\n", d[0][0], d[0][1], s->sprite_offset[0][0], s->sprite_offset[0][1]);
 }
 
-/* decode mpeg4 VOP header */
-int mpeg4_decode_picture_header(MpegEncContext * s)
-{
-    int time_incr, startcode, state, v;
-    int time_increment;
-
- redo:
-    /* search next start code */
-    align_get_bits(&s->gb);
-    state = 0xff;
-    for(;;) {
-        v = get_bits(&s->gb, 8);
-        if (state == 0x000001) {
-            state = ((state << 8) | v) & 0xffffff;
-            startcode = state;
-            break;
+static int decode_vol_header(MpegEncContext *s, GetBitContext *gb){
+    int width, height, vo_ver_id;
+
+    /* vol header */
+    skip_bits(gb, 1); /* random access */
+    s->vo_type= get_bits(gb, 8);
+    if (get_bits1(gb) != 0) { /* is_ol_id */
+        vo_ver_id = get_bits(gb, 4); /* vo_ver_id */
+        skip_bits(gb, 3); /* vo_priority */
+    } else {
+        vo_ver_id = 1;
+    }
+//printf("vo type:%d\n",s->vo_type);
+    s->aspect_ratio_info= get_bits(gb, 4);
+    if(s->aspect_ratio_info == FF_ASPECT_EXTENDED){	    
+        s->aspected_width = get_bits(gb, 8); // par_width
+        s->aspected_height = get_bits(gb, 8); // par_height
+    }
+
+    if ((s->vol_control_parameters=get_bits1(gb))) { /* vol control parameter */
+        int chroma_format= get_bits(gb, 2);
+        if(chroma_format!=1){
+            printf("illegal chroma format\n");
+        }
+        s->low_delay= get_bits1(gb);
+        if(get_bits1(gb)){ /* vbv parameters */
+            get_bits(gb, 15);	/* first_half_bitrate */
+            skip_bits1(gb);	/* marker */
+            get_bits(gb, 15);	/* latter_half_bitrate */
+            skip_bits1(gb);	/* marker */
+            get_bits(gb, 15);	/* first_half_vbv_buffer_size */
+            skip_bits1(gb);	/* marker */
+            get_bits(gb, 3);	/* latter_half_vbv_buffer_size */
+            get_bits(gb, 11);	/* first_half_vbv_occupancy */
+            skip_bits1(gb);	/* marker */
+            get_bits(gb, 15);	/* latter_half_vbv_occupancy */
+            skip_bits1(gb);	/* marker */               
+        }
+    }else{
+        // set low delay flag only once so the smart? low delay detection wont be overriden
+        if(s->picture_number==0)
+            s->low_delay=0;
+    }
+
+    s->shape = get_bits(gb, 2); /* vol shape */
+    if(s->shape != RECT_SHAPE) printf("only rectangular vol supported\n");
+    if(s->shape == GRAY_SHAPE && vo_ver_id != 1){
+        printf("Gray shape not supported\n");
+        skip_bits(gb, 4);  //video_object_layer_shape_extension
+    }
+
+    skip_bits1(gb);   /* marker */
+    
+    s->time_increment_resolution = get_bits(gb, 16);
+    
+    s->time_increment_bits = av_log2(s->time_increment_resolution - 1) + 1;
+    if (s->time_increment_bits < 1)
+        s->time_increment_bits = 1;
+    skip_bits1(gb);   /* marker */
+
+    if (get_bits1(gb) != 0) {   /* fixed_vop_rate  */
+        skip_bits(gb, s->time_increment_bits);
+    }
+
+    if (s->shape != BIN_ONLY_SHAPE) {
+        if (s->shape == RECT_SHAPE) {
+            skip_bits1(gb);   /* marker */
+            width = get_bits(gb, 13);
+            skip_bits1(gb);   /* marker */
+            height = get_bits(gb, 13);
+            skip_bits1(gb);   /* marker */
+            if(width && height){ /* they should be non zero but who knows ... */
+                s->width = width;
+                s->height = height;
+//                printf("width/height: %d %d\n", width, height);
+            }
+        }
+        
+        s->progressive_sequence= get_bits1(gb)^1;
+        if(!get_bits1(gb)) printf("OBMC not supported (very likely buggy encoder)\n");   /* OBMC Disable */
+        if (vo_ver_id == 1) {
+            s->vol_sprite_usage = get_bits1(gb); /* vol_sprite_usage */
+        } else {
+            s->vol_sprite_usage = get_bits(gb, 2); /* vol_sprite_usage */
+        }
+        if(s->vol_sprite_usage==STATIC_SPRITE) printf("Static Sprites not supported\n");
+        if(s->vol_sprite_usage==STATIC_SPRITE || s->vol_sprite_usage==GMC_SPRITE){
+            if(s->vol_sprite_usage==STATIC_SPRITE){
+                s->sprite_width = get_bits(gb, 13);
+                skip_bits1(gb); /* marker */
+                s->sprite_height= get_bits(gb, 13);
+                skip_bits1(gb); /* marker */
+                s->sprite_left  = get_bits(gb, 13);
+                skip_bits1(gb); /* marker */
+                s->sprite_top   = get_bits(gb, 13);
+                skip_bits1(gb); /* marker */
+            }
+            s->num_sprite_warping_points= get_bits(gb, 6);
+            s->sprite_warping_accuracy = get_bits(gb, 2);
+            s->sprite_brightness_change= get_bits1(gb);
+            if(s->vol_sprite_usage==STATIC_SPRITE)
+                s->low_latency_sprite= get_bits1(gb);            
+        }
+        // FIXME sadct disable bit if verid!=1 && shape not rect
+        
+        if (get_bits1(gb) == 1) {   /* not_8_bit */
+            s->quant_precision = get_bits(gb, 4); /* quant_precision */
+            if(get_bits(gb, 4)!=8) printf("N-bit not supported\n"); /* bits_per_pixel */
+            if(s->quant_precision!=5) printf("quant precission %d\n", s->quant_precision);
+        } else {
+            s->quant_precision = 5;
         }
-        state = ((state << 8) | v) & 0xffffff;
-        if( get_bits_count(&s->gb) > s->gb.size*8-32){
-            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;
+        
+        // FIXME a bunch of grayscale shape things
+
+        if((s->mpeg_quant=get_bits1(gb))){ /* vol_quant_type */
+            int i, j, v;
+            
+            /* load default matrixes */
+            for(i=0; i<64; i++){
+                int j= s->idct_permutation[i];
+                v= ff_mpeg4_default_intra_matrix[i];
+                s->intra_matrix[j]= v;
+                s->chroma_intra_matrix[j]= v;
+                
+                v= ff_mpeg4_default_non_intra_matrix[i];
+                s->inter_matrix[j]= v;
+                s->chroma_inter_matrix[j]= v;
+            }
+
+            /* load custom intra matrix */
+            if(get_bits1(gb)){
+                int last=0;
+                for(i=0; i<64; i++){
+                    v= get_bits(gb, 8);
+                    if(v==0) break;
+                    
+                    last= v;
+                    j= s->idct_permutation[ ff_zigzag_direct[i] ];
+                    s->intra_matrix[j]= v;
+                    s->chroma_intra_matrix[j]= v;
+                }
+
+                /* replicate last value */
+                for(; i<64; i++){
+                    j= s->idct_permutation[ ff_zigzag_direct[i] ];
+                    s->intra_matrix[j]= v;
+                    s->chroma_intra_matrix[j]= v;
+                }
+            }
+
+            /* load custom non intra matrix */
+            if(get_bits1(gb)){
+                int last=0;
+                for(i=0; i<64; i++){
+                    v= get_bits(gb, 8);
+                    if(v==0) break;
+
+                    last= v;
+                    j= s->idct_permutation[ ff_zigzag_direct[i] ];
+                    s->inter_matrix[j]= v;
+                    s->chroma_inter_matrix[j]= v;
+                }
+
+                /* replicate last value */
+                for(; i<64; i++){
+                    j= s->idct_permutation[ ff_zigzag_direct[i] ];
+                    s->inter_matrix[j]= last;
+                    s->chroma_inter_matrix[j]= last;
+                }
+            }
+
+            // FIXME a bunch of grayscale shape things
+        }
+
+        if(vo_ver_id != 1)
+             s->quarter_sample= get_bits1(gb);
+        else s->quarter_sample=0;
+
+        if(!get_bits1(gb)) printf("Complexity estimation not supported\n");
+
+        s->resync_marker= !get_bits1(gb); /* resync_marker_disabled */
+
+        s->data_partitioning= get_bits1(gb);
+        if(s->data_partitioning){
+            s->rvlc= get_bits1(gb);
+            if(s->rvlc){
+                printf("reversible vlc not supported\n");
+            }
+        }
+        
+        if(vo_ver_id != 1) {
+            s->new_pred= get_bits1(gb);
+            if(s->new_pred){
+                printf("new pred not supported\n");
+                skip_bits(gb, 2); /* requested upstream message type */
+                skip_bits1(gb); /* newpred segment type */
+            }
+            s->reduced_res_vop= get_bits1(gb);
+            if(s->reduced_res_vop) printf("reduced resolution VOP not supported\n");
+        }
+        else{
+            s->new_pred=0;
+            s->reduced_res_vop= 0;
+        }
+
+        s->scalability= get_bits1(gb);
+
+        if (s->scalability) {
+            GetBitContext bak= *gb;
+            int dummy= s->hierachy_type= get_bits1(gb);
+            int ref_layer_id= get_bits(gb, 4);
+            int ref_layer_sampling_dir= get_bits1(gb);
+            int h_sampling_factor_n= get_bits(gb, 5);
+            int h_sampling_factor_m= get_bits(gb, 5);
+            int v_sampling_factor_n= get_bits(gb, 5);
+            int v_sampling_factor_m= get_bits(gb, 5);
+            s->enhancement_type= get_bits1(gb);
+            
+            if(   h_sampling_factor_n==0 || h_sampling_factor_m==0 
+               || v_sampling_factor_n==0 || v_sampling_factor_m==0){
+               
+//                fprintf(stderr, "illegal scalability header (VERY broken encoder), trying to workaround\n");
+                s->scalability=0;
+               
+                *gb= bak;
+            }else
+                printf("scalability not supported\n");
+            
+            // bin shape stuff FIXME
+        }
+    }
+    return 0;
+}
+
+static int decode_user_data(MpegEncContext *s, GetBitContext *gb){
+    char buf[256];
+    int i;
+    int e;
+    int ver, build, ver2, ver3;
+
+    buf[0]= show_bits(gb, 8);
+    for(i=1; i<256; i++){
+        buf[i]= show_bits(gb, 16)&0xFF;
+        if(buf[i]==0) break;
+        skip_bits(gb, 8);
+    }
+    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){
+                printf("WARNING: this version of DivX is not MPEG4 compatible, trying to workaround these bugs...\n");
             }
         }
     }
-//printf("startcode %X %d\n", startcode, get_bits_count(&s->gb));
-    if (startcode == 0x120) { // Video Object Layer
-        int width, height, vo_ver_id;
-
-        /* vol header */
-        skip_bits(&s->gb, 1); /* random access */
-        s->vo_type= get_bits(&s->gb, 8);
-        if (get_bits1(&s->gb) != 0) { /* is_ol_id */
-            vo_ver_id = get_bits(&s->gb, 4); /* vo_ver_id */
-            skip_bits(&s->gb, 3); /* vo_priority */
-        } else {
-            vo_ver_id = 1;
-        }
-//printf("vo type:%d\n",s->vo_type);
-        s->aspect_ratio_info= get_bits(&s->gb, 4);
-	if(s->aspect_ratio_info == FF_ASPECT_EXTENDED){	    
-	    s->aspected_width = get_bits(&s->gb, 8); // par_width
-	    s->aspected_height = get_bits(&s->gb, 8); // par_height
-        }
-
-        if ((s->vol_control_parameters=get_bits1(&s->gb))) { /* vol control parameter */
-            int chroma_format= get_bits(&s->gb, 2);
-            if(chroma_format!=1){
-                printf("illegal chroma format\n");
-            }
-            s->low_delay= get_bits1(&s->gb);
-            if(get_bits1(&s->gb)){ /* vbv parameters */
-                get_bits(&s->gb, 15);	/* first_half_bitrate */
-                skip_bits1(&s->gb);	/* marker */
-                get_bits(&s->gb, 15);	/* latter_half_bitrate */
-                skip_bits1(&s->gb);	/* marker */
-                get_bits(&s->gb, 15);	/* first_half_vbv_buffer_size */
-                skip_bits1(&s->gb);	/* marker */
-                get_bits(&s->gb, 3);	/* latter_half_vbv_buffer_size */
-                get_bits(&s->gb, 11);	/* first_half_vbv_occupancy */
-                skip_bits1(&s->gb);	/* marker */
-                get_bits(&s->gb, 15);	/* latter_half_vbv_occupancy */
-                skip_bits1(&s->gb);	/* marker */               
-            }
-        }else{
-            // set low delay flag only once so the smart? low delay detection wont be overriden
-            if(s->picture_number==0)
-                s->low_delay=0;
-        }
-
-        s->shape = get_bits(&s->gb, 2); /* vol shape */
-        if(s->shape != RECT_SHAPE) printf("only rectangular vol supported\n");
-        if(s->shape == GRAY_SHAPE && vo_ver_id != 1){
-            printf("Gray shape not supported\n");
-            skip_bits(&s->gb, 4);  //video_object_layer_shape_extension
-        }
-
-        skip_bits1(&s->gb);   /* marker */
-        
-        s->time_increment_resolution = get_bits(&s->gb, 16);
-        
-        s->time_increment_bits = av_log2(s->time_increment_resolution - 1) + 1;
-        if (s->time_increment_bits < 1)
-            s->time_increment_bits = 1;
-        skip_bits1(&s->gb);   /* marker */
-
-        if (get_bits1(&s->gb) != 0) {   /* fixed_vop_rate  */
-            skip_bits(&s->gb, s->time_increment_bits);
+    e=sscanf(buf, "FFmpeg%d.%d.%db%d", &ver, &ver2, &ver3, &build);
+    if(e!=4)
+        e=sscanf(buf, "FFmpeg v%d.%d.%d / libavcodec build: %d", &ver, &ver2, &ver3, &build); 
+    if(e!=4){
+        if(strcmp(buf, "ffmpeg")==0){
+            s->ffmpeg_version= 0x000406;
+            s->lavc_build= 4600;
         }
-
-        if (s->shape != BIN_ONLY_SHAPE) {
-            if (s->shape == RECT_SHAPE) {
-                skip_bits1(&s->gb);   /* marker */
-                width = get_bits(&s->gb, 13);
-                skip_bits1(&s->gb);   /* marker */
-                height = get_bits(&s->gb, 13);
-                skip_bits1(&s->gb);   /* marker */
-                if(width && height){ /* they should be non zero but who knows ... */
-                    s->width = width;
-                    s->height = height;
-//                    printf("width/height: %d %d\n", width, height);
-                }
-            }
-            
-            s->progressive_sequence= get_bits1(&s->gb)^1;
-            if(!get_bits1(&s->gb)) printf("OBMC not supported (very likely buggy encoder)\n");   /* OBMC Disable */
-            if (vo_ver_id == 1) {
-                s->vol_sprite_usage = get_bits1(&s->gb); /* vol_sprite_usage */
-            } else {
-                s->vol_sprite_usage = get_bits(&s->gb, 2); /* vol_sprite_usage */
-            }
-            if(s->vol_sprite_usage==STATIC_SPRITE) printf("Static Sprites not supported\n");
-            if(s->vol_sprite_usage==STATIC_SPRITE || s->vol_sprite_usage==GMC_SPRITE){
-                if(s->vol_sprite_usage==STATIC_SPRITE){
-                    s->sprite_width = get_bits(&s->gb, 13);
-                    skip_bits1(&s->gb); /* marker */
-                    s->sprite_height= get_bits(&s->gb, 13);
-                    skip_bits1(&s->gb); /* marker */
-                    s->sprite_left  = get_bits(&s->gb, 13);
-                    skip_bits1(&s->gb); /* marker */
-                    s->sprite_top   = get_bits(&s->gb, 13);
-                    skip_bits1(&s->gb); /* marker */
-                }
-                s->num_sprite_warping_points= get_bits(&s->gb, 6);
-                s->sprite_warping_accuracy = get_bits(&s->gb, 2);
-                s->sprite_brightness_change= get_bits1(&s->gb);
-                if(s->vol_sprite_usage==STATIC_SPRITE)
-                    s->low_latency_sprite= get_bits1(&s->gb);            
-            }
-            // FIXME sadct disable bit if verid!=1 && shape not rect
-            
-            if (get_bits1(&s->gb) == 1) {   /* not_8_bit */
-                s->quant_precision = get_bits(&s->gb, 4); /* quant_precision */
-                if(get_bits(&s->gb, 4)!=8) printf("N-bit not supported\n"); /* bits_per_pixel */
-                if(s->quant_precision!=5) printf("quant precission %d\n", s->quant_precision);
-            } else {
-                s->quant_precision = 5;
-            }
-            
-            // FIXME a bunch of grayscale shape things
-
-            if((s->mpeg_quant=get_bits1(&s->gb))){ /* vol_quant_type */
-                int i, j, v;
-                
-                /* load default matrixes */
-                for(i=0; i<64; i++){
-                    int j= s->idct_permutation[i];
-                    v= ff_mpeg4_default_intra_matrix[i];
-                    s->intra_matrix[j]= v;
-                    s->chroma_intra_matrix[j]= v;
-                    
-                    v= ff_mpeg4_default_non_intra_matrix[i];
-                    s->inter_matrix[j]= v;
-                    s->chroma_inter_matrix[j]= v;
-                }
-
-                /* load custom intra matrix */
-                if(get_bits1(&s->gb)){
-                    int last=0;
-                    for(i=0; i<64; i++){
-                        v= get_bits(&s->gb, 8);
-                        if(v==0) break;
-                        
-                        last= v;
-                        j= s->idct_permutation[ ff_zigzag_direct[i] ];
-                        s->intra_matrix[j]= v;
-                        s->chroma_intra_matrix[j]= v;
-                    }
-
-                    /* replicate last value */
-                    for(; i<64; i++){
-                        j= s->idct_permutation[ ff_zigzag_direct[i] ];
-                        s->intra_matrix[j]= v;
-                        s->chroma_intra_matrix[j]= v;
-                    }
-                }
-
-                /* load custom non intra matrix */
-                if(get_bits1(&s->gb)){
-                    int last=0;
-                    for(i=0; i<64; i++){
-                        v= get_bits(&s->gb, 8);
-                        if(v==0) break;
-
-                        last= v;
-                        j= s->idct_permutation[ ff_zigzag_direct[i] ];
-                        s->inter_matrix[j]= v;
-                        s->chroma_inter_matrix[j]= v;
-                    }
-
-                    /* replicate last value */
-                    for(; i<64; i++){
-                        j= s->idct_permutation[ ff_zigzag_direct[i] ];
-                        s->inter_matrix[j]= last;
-                        s->chroma_inter_matrix[j]= last;
-                    }
-                }
-
-                // FIXME a bunch of grayscale shape things
-            }
-
-            if(vo_ver_id != 1)
-                 s->quarter_sample= get_bits1(&s->gb);
-            else s->quarter_sample=0;
-
-            if(!get_bits1(&s->gb)) printf("Complexity estimation not supported\n");
-
-            s->resync_marker= !get_bits1(&s->gb); /* resync_marker_disabled */
-
-            s->data_partitioning= get_bits1(&s->gb);
-            if(s->data_partitioning){
-                s->rvlc= get_bits1(&s->gb);
-                if(s->rvlc){
-                    printf("reversible vlc not supported\n");
-                }
-            }
-            
-            if(vo_ver_id != 1) {
-                s->new_pred= get_bits1(&s->gb);
-                if(s->new_pred){
-                    printf("new pred not supported\n");
-                    skip_bits(&s->gb, 2); /* requested upstream message type */
-                    skip_bits1(&s->gb); /* newpred segment type */
-                }
-                s->reduced_res_vop= get_bits1(&s->gb);
-                if(s->reduced_res_vop) printf("reduced resolution VOP not supported\n");
-            }
-            else{
-                s->new_pred=0;
-                s->reduced_res_vop= 0;
-            }
-
-            s->scalability= get_bits1(&s->gb);
-
-            if (s->scalability) {
-                GetBitContext bak= s->gb;
-                int dummy= s->hierachy_type= get_bits1(&s->gb);
-                int ref_layer_id= get_bits(&s->gb, 4);
-                int ref_layer_sampling_dir= get_bits1(&s->gb);
-                int h_sampling_factor_n= get_bits(&s->gb, 5);
-                int h_sampling_factor_m= get_bits(&s->gb, 5);
-                int v_sampling_factor_n= get_bits(&s->gb, 5);
-                int v_sampling_factor_m= get_bits(&s->gb, 5);
-                s->enhancement_type= get_bits1(&s->gb);
-                
-                if(   h_sampling_factor_n==0 || h_sampling_factor_m==0 
-                   || v_sampling_factor_n==0 || v_sampling_factor_m==0){
-                   
-//                    fprintf(stderr, "illegal scalability header (VERY broken encoder), trying to workaround\n");
-                    s->scalability=0;
-                   
-                    s->gb= bak;
-                    goto redo;
-                }
-                
-                // bin shape stuff FIXME
-                printf("scalability not supported\n");
-            }
-        }
-//printf("end Data %X %d\n", show_bits(&s->gb, 32), get_bits_count(&s->gb)&0x7);
-        goto redo;
-    } else if (startcode == 0x1b2) { //userdata
-        char buf[256];
-        int i;
-        int e;
-        int ver, build, ver2, ver3;
-
-//printf("user Data %X\n", show_bits(&s->gb, 32));
-        buf[0]= show_bits(&s->gb, 8);
-        for(i=1; i<256; i++){
-            buf[i]= show_bits(&s->gb, 16)&0xFF;
-            if(buf[i]==0) break;
-            skip_bits(&s->gb, 8);
-        }
-        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){
-                    printf("WARNING: this version of DivX is not MPEG4 compatible, trying to workaround these bugs...\n");
-                }
-            }
-        }
-        e=sscanf(buf, "FFmpeg%d.%d.%db%d", &ver, &ver2, &ver3, &build);
-        if(e!=4)
-            e=sscanf(buf, "FFmpeg v%d.%d.%d / libavcodec build: %d", &ver, &ver2, &ver3, &build); 
-        if(e!=4){
-            if(strcmp(buf, "ffmpeg")==0){
-                s->ffmpeg_version= 0x000406;
-                s->lavc_build= 4600;
-            }
-        }
-        if(e==4){
-            s->ffmpeg_version= ver*256*256 + ver2*256 + ver3;
-            s->lavc_build= build;
-            if(s->picture_number==0)
-                printf("This file was encoded with libavcodec build %d\n", build);
-        }
+    }
+    if(e==4){
+        s->ffmpeg_version= ver*256*256 + ver2*256 + ver3;
+        s->lavc_build= build;
+        if(s->picture_number==0)
+            printf("This file was encoded with libavcodec build %d\n", build);
+    }
 //printf("User Data: %s\n", buf);
-        goto redo;
-    } else if (startcode != 0x1b6) { //VOP
-        goto redo;
-    }
-    
-    s->pict_type = get_bits(&s->gb, 2) + I_TYPE;	/* pict type: I = 0 , P = 1 */
-//if(s->pict_type!=I_TYPE) return FRAME_SKIPED;
+    return 0;
+}
+
+static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){
+    int time_incr, time_increment;
+
+    s->pict_type = get_bits(gb, 2) + I_TYPE;	/* pict type: I = 0 , P = 1 */
     if(s->pict_type==B_TYPE && s->low_delay && s->vol_control_parameters==0){
         printf("low_delay flag set, but shouldnt, clearing it\n");
         s->low_delay=0;
@@ -4371,11 +4341,11 @@
 //        fprintf(stderr, "time_increment_resolution is illegal\n");
     }
     time_incr=0;
-    while (get_bits1(&s->gb) != 0) 
+    while (get_bits1(gb) != 0) 
         time_incr++;
 
-    check_marker(&s->gb, "before time_increment");
-    time_increment= get_bits(&s->gb, s->time_increment_bits);
+    check_marker(gb, "before time_increment");
+    time_increment= get_bits(gb, s->time_increment_bits);
 //printf(" type:%d modulo_time_base:%d increment:%d\n", s->pict_type, time_incr, time_increment);
     if(s->pict_type!=B_TYPE){
         s->last_time_base= s->time_base;
@@ -4409,22 +4379,24 @@
     
     s->avctx->pts= s->time*1000LL*1000LL / s->time_increment_resolution;
     
-    if(check_marker(&s->gb, "before vop_coded")==0 && s->picture_number==0){
+    if(check_marker(gb, "before vop_coded")==0 && s->picture_number==0){
         printf("hmm, seems the headers arnt complete, trying to guess time_increment_bits\n");
         for(s->time_increment_bits++ ;s->time_increment_bits<16; s->time_increment_bits++){
-            if(get_bits1(&s->gb)) break;
+            if(get_bits1(gb)) break;
         }
         printf("my guess is %d bits ;)\n",s->time_increment_bits);
     }
     /* vop coded */
-    if (get_bits1(&s->gb) != 1)
-        goto redo;
+    if (get_bits1(gb) != 1){
+        printf("vop not coded\n");
+        return FRAME_SKIPED;
+    }
 //printf("time %d %d %d || %Ld %Ld %Ld\n", s->time_increment_bits, s->time_increment_resolution, s->time_base,
 //s->time, s->last_non_b_time, s->last_non_b_time - s->pp_time);  
     if (s->shape != BIN_ONLY_SHAPE && ( s->pict_type == P_TYPE
                           || (s->pict_type == S_TYPE && s->vol_sprite_usage==GMC_SPRITE))) {
         /* rounding type for motion estimation */
-	s->no_rounding = get_bits1(&s->gb);
+	s->no_rounding = get_bits1(gb);
     } else {
 	s->no_rounding = 0;
     }
@@ -4434,29 +4406,29 @@
          if (s->vol_sprite_usage != 1 || s->pict_type != I_TYPE) {
              int width, height, hor_spat_ref, ver_spat_ref;
  
-             width = get_bits(&s->gb, 13);
-             skip_bits1(&s->gb);   /* marker */
-             height = get_bits(&s->gb, 13);
-             skip_bits1(&s->gb);   /* marker */
-             hor_spat_ref = get_bits(&s->gb, 13); /* hor_spat_ref */
-             skip_bits1(&s->gb);   /* marker */
-             ver_spat_ref = get_bits(&s->gb, 13); /* ver_spat_ref */
+             width = get_bits(gb, 13);
+             skip_bits1(gb);   /* marker */
+             height = get_bits(gb, 13);
+             skip_bits1(gb);   /* marker */
+             hor_spat_ref = get_bits(gb, 13); /* hor_spat_ref */
+             skip_bits1(gb);   /* marker */
+             ver_spat_ref = get_bits(gb, 13); /* ver_spat_ref */
          }
-         skip_bits1(&s->gb); /* change_CR_disable */
+         skip_bits1(gb); /* change_CR_disable */
  
-         if (get_bits1(&s->gb) != 0) {
-             skip_bits(&s->gb, 8); /* constant_alpha_value */
+         if (get_bits1(gb) != 0) {
+             skip_bits(gb, 8); /* constant_alpha_value */
          }
      }
 //FIXME complexity estimation stuff
      
      if (s->shape != BIN_ONLY_SHAPE) {
          int t;
-         t=get_bits(&s->gb, 3); /* intra dc VLC threshold */
+         t=get_bits(gb, 3); /* intra dc VLC threshold */
 //printf("threshold %d\n", t);
          if(!s->progressive_sequence){
-             s->top_field_first= get_bits1(&s->gb);
-             s->alternate_scan= get_bits1(&s->gb);
+             s->top_field_first= get_bits1(gb);
+             s->alternate_scan= get_bits1(gb);
          }else
              s->alternate_scan= 0;
      }
@@ -4482,14 +4454,14 @@
      }
 
      if (s->shape != BIN_ONLY_SHAPE) {
-         s->qscale = get_bits(&s->gb, s->quant_precision);
+         s->qscale = get_bits(gb, s->quant_precision);
          if(s->qscale==0){
              printf("Error, header damaged or not MPEG4 header (qscale=0)\n");
              return -1; // makes no sense to continue, as there is nothing left from the image then
          }
   
          if (s->pict_type != I_TYPE) {
-             s->f_code = get_bits(&s->gb, 3);	/* fcode_for */
+             s->f_code = get_bits(gb, 3);	/* fcode_for */
              if(s->f_code==0){
                  printf("Error, header damaged or not MPEG4 header (f_code=0)\n");
                  return -1; // makes no sense to continue, as the MV decoding will break very quickly
@@ -4498,28 +4470,28 @@
              s->f_code=1;
      
          if (s->pict_type == B_TYPE) {
-             s->b_code = get_bits(&s->gb, 3);
+             s->b_code = get_bits(gb, 3);
          }else
              s->b_code=1;
 #if 0
 printf("qp:%d fc:%d bc:%d type:%s size:%d pro:%d alt:%d top:%d qpel:%d part:%d resync:%d\n", 
     s->qscale, s->f_code, s->b_code, 
     s->pict_type == I_TYPE ? "I" : (s->pict_type == P_TYPE ? "P" : (s->pict_type == B_TYPE ? "B" : "S")), 
-    s->gb.size,s->progressive_sequence, s->alternate_scan, s->top_field_first, 
+    gb->size,s->progressive_sequence, s->alternate_scan, s->top_field_first, 
     s->quarter_sample, s->data_partitioning, s->resync_marker); 
 #endif
          if(!s->scalability){
              if (s->shape!=RECT_SHAPE && s->pict_type!=I_TYPE) {
-                 skip_bits1(&s->gb); // vop shape coding type
+                 skip_bits1(gb); // vop shape coding type
              }
          }else{
              if(s->enhancement_type){
-                 int load_backward_shape= get_bits1(&s->gb);
+                 int load_backward_shape= get_bits1(gb);
                  if(load_backward_shape){
                      printf("load backward shape isnt supported\n");
                  }
              }
-             skip_bits(&s->gb, 2); //ref_select_code
+             skip_bits(gb, 2); //ref_select_code
          }
      }
      /* detect buggy encoders which dont set the low_delay flag (divx4/xvid/opendivx)*/
@@ -4541,6 +4513,53 @@
      return 0;
 }
 
+/**
+ * decode mpeg4 headers
+ * @return <0 if no VOP found (or a damaged one)
+ *         FRAME_SKIPPED if a not coded VOP is found
+ *         0 if a VOP is found
+ */
+int ff_mpeg4_decode_picture_header(MpegEncContext * s, GetBitContext *gb)
+{
+    int startcode, v;
+
+    /* search next start code */
+    align_get_bits(gb);
+    startcode = 0xff;
+    for(;;) {
+        v = get_bits(gb, 8);
+        startcode = ((startcode << 8) | v) & 0xffffffff;
+        
+        if(get_bits_count(gb) >= gb->size*8){
+            if(gb->size==1 && s->divx_version){
+                printf("frame skip %d\n", gb->size);
+                return FRAME_SKIPED; //divx bug
+            }else
+                return -1; //end of stream
+        }
+
+        if((startcode&0xFFFFFF00) != 0x100)
+            continue; //no startcode
+        
+        switch(startcode){
+        case 0x120:
+            decode_vol_header(s, gb);
+            break;
+        case 0x1b2:
+            decode_user_data(s, gb);
+            break;
+        case 0x1b6:
+            return decode_vop_header(s, gb);
+        default:
+//            printf("startcode %X found\n", startcode);
+            break;
+        }
+
+        align_get_bits(gb);
+        startcode = 0xff;
+    }
+}
+
 /* don't understand why they choose a different header ! */
 int intel_h263_decode_picture_header(MpegEncContext *s)
 {
--- a/h263dec.c	Sun Oct 13 19:53:32 2002 +0000
+++ b/h263dec.c	Mon Oct 14 12:21:54 2002 +0000
@@ -40,8 +40,6 @@
 }
 #endif
 
-const UINT16 ff_mpeg4_resync_prefix[8];
-
 static int h263_decode_init(AVCodecContext *avctx)
 {
     MpegEncContext *s = avctx->priv_data;
@@ -313,7 +311,14 @@
     if (s->h263_msmpeg4) {
         ret = msmpeg4_decode_picture_header(s);
     } else if (s->h263_pred) {
-        ret = mpeg4_decode_picture_header(s);
+        if(s->avctx->extradata_size && s->picture_number==0){
+            GetBitContext gb;
+            
+            init_get_bits(&gb, s->avctx->extradata, s->avctx->extradata_size);
+            ret = ff_mpeg4_decode_picture_header(s, &gb);
+        }
+        ret = ff_mpeg4_decode_picture_header(s, &s->gb);
+
         s->has_b_frames= !s->low_delay;
     } else if (s->h263_intel) {
         ret = intel_h263_decode_picture_header(s);
--- a/mpegvideo.h	Sun Oct 13 19:53:32 2002 +0000
+++ b/mpegvideo.h	Mon Oct 14 12:21:54 2002 +0000
@@ -624,7 +624,9 @@
 void h263_decode_init_vlc(MpegEncContext *s);
 int h263_decode_picture_header(MpegEncContext *s);
 int ff_h263_decode_gob_header(MpegEncContext *s);
-int mpeg4_decode_picture_header(MpegEncContext * s);
+int ff_mpeg4_decode_picture_header(MpegEncContext * s, GetBitContext *gb);
+
+
 int intel_h263_decode_picture_header(MpegEncContext *s);
 int ff_h263_decode_mb(MpegEncContext *s,
                       DCTELEM block[6][64]);