Originally committed as revision 412 to svn://svn.ffmpeg.org/ffmpeg/trunktags/v0.5
| @@ -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; | |||
| } | |||
| @@ -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)){ | |||
| @@ -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]); | |||
| @@ -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]; | |||