diff --git a/libavcodec/h263.c b/libavcodec/h263.c index 5133480968..7638942cd3 100644 --- a/libavcodec/h263.c +++ b/libavcodec/h263.c @@ -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; } diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c index 5a3d331865..b3e11b9bcd 100644 --- a/libavcodec/h263dec.c +++ b/libavcodec/h263dec.c @@ -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)){ diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index 112d684373..5885fd73d2 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -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]); diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h index b0aebe8954..c5335aba19 100644 --- a/libavcodec/mpegvideo.h +++ b/libavcodec/mpegvideo.h @@ -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];