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; | state = ((state << 8) | v) & 0xffffff; | ||||
| if( get_bits_count(&s->gb) > s->gb.size*8-32){ | 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)); | //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; | buf[255]=0; | ||||
| e=sscanf(buf, "DivX%dBuild%d", &ver, &build); | e=sscanf(buf, "DivX%dBuild%d", &ver, &build); | ||||
| if(e!=2) | |||||
| e=sscanf(buf, "DivX%db%d", &ver, &build); | |||||
| if(e==2){ | if(e==2){ | ||||
| s->divx_version= ver; | s->divx_version= ver; | ||||
| s->divx_build= build; | s->divx_build= build; | ||||
| if(s->picture_number==0){ | if(s->picture_number==0){ | ||||
| printf("This file was encoded with DivX%d Build%d\n", ver, build); | 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"); | printf("WARNING: this version of DivX is not MPEG4 compatible, trying to workaround these bugs...\n"); | ||||
| #if 0 | |||||
| }else{ | }else{ | ||||
| printf("hmm, i havnt seen that version of divx yet, lets assume they fixed these bugs ...\n" | 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"); | "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 ;) | s->picture_number++; // better than pic number==0 allways ;) | ||||
| //printf("done\n"); | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -119,7 +119,10 @@ static int h263_decode_frame(AVCodecContext *avctx, | |||||
| return 0; | 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 :-) */ | /* let's go :-) */ | ||||
| if (s->h263_msmpeg4) { | if (s->h263_msmpeg4) { | ||||
| @@ -131,6 +134,7 @@ static int h263_decode_frame(AVCodecContext *avctx, | |||||
| } else { | } else { | ||||
| ret = h263_decode_picture_header(s); | ret = h263_decode_picture_header(s); | ||||
| } | } | ||||
| if(ret==FRAME_SKIPED) return 0; | |||||
| /* After H263 & mpeg4 header decode we have the height, width,*/ | /* After H263 & mpeg4 header decode we have the height, width,*/ | ||||
| /* and other parameters. So then we could init the picture */ | /* 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 (s->h263_msmpeg4 && s->msmpeg4_version<4 && s->pict_type==I_TYPE) | ||||
| if(msmpeg4_decode_ext_header(s, buf_size) < 0) return -1; | 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); | MPV_frame_end(s); | ||||
| if(s->pict_type==B_TYPE || (!s->has_b_frames)){ | if(s->pict_type==B_TYPE || (!s->has_b_frames)){ | ||||
| @@ -292,6 +292,11 @@ int MPV_common_init(MpegEncContext *s) | |||||
| if (!s->mbintra_table) | if (!s->mbintra_table) | ||||
| goto fail; | goto fail; | ||||
| memset(s->mbintra_table, 1, s->mb_num); | 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 */ | /* default structure is frame */ | ||||
| s->picture_structure = PICT_FRAME; | s->picture_structure = PICT_FRAME; | ||||
| @@ -340,6 +345,7 @@ void MPV_common_end(MpegEncContext *s) | |||||
| CHECK_FREE(s->me_scratchpad); | CHECK_FREE(s->me_scratchpad); | ||||
| CHECK_FREE(s->mbskip_table); | CHECK_FREE(s->mbskip_table); | ||||
| CHECK_FREE(s->bitstream_buffer); | |||||
| for(i=0;i<3;i++) { | for(i=0;i<3;i++) { | ||||
| int j; | int j; | ||||
| CHECK_FREE(s->last_picture_base[i]); | CHECK_FREE(s->last_picture_base[i]); | ||||
| @@ -23,6 +23,8 @@ | |||||
| #define B_TYPE 3 | #define B_TYPE 3 | ||||
| #define S_TYPE 4 //S(GMC)-VOP MPEG4 | #define S_TYPE 4 //S(GMC)-VOP MPEG4 | ||||
| #define FRAME_SKIPED 100 // return value for header parsers if frame is not coded | |||||
| enum OutputFormat { | enum OutputFormat { | ||||
| FMT_MPEG1, | FMT_MPEG1, | ||||
| FMT_H263, | FMT_H263, | ||||
| @@ -298,7 +300,10 @@ typedef struct MpegEncContext { | |||||
| /* divx specific, used to workaround (many) bugs in divx5 */ | /* divx specific, used to workaround (many) bugs in divx5 */ | ||||
| int divx_version; | int divx_version; | ||||
| int divx_build; | 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 */ | /* RV10 specific */ | ||||
| int rv10_version; /* RV10 version: 0 or 3 */ | int rv10_version; /* RV10 version: 0 or 3 */ | ||||
| int rv10_first_dc_coded[3]; | int rv10_first_dc_coded[3]; | ||||