# HG changeset patch # User michaelni # Date 1034598114 0 # Node ID 3d4377531f6c072670b8b2635895f0b3187e1b2e # Parent fccad7166d5af9c4b0727ca80dc5fcecfe852a09 mpeg4 header parser clenup (needed for parsing of VOL header in avctx->extradata) diff -r fccad7166d5a -r 3d4377531f6c avcodec.h --- 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. */ diff -r fccad7166d5a -r 3d4377531f6c h263.c --- 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) { diff -r fccad7166d5a -r 3d4377531f6c h263dec.c --- 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); diff -r fccad7166d5a -r 3d4377531f6c mpegvideo.h --- 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]);