Commit eec1c6b9 authored by Michael Niedermayer's avatar Michael Niedermayer

divx 5.01 support

Originally committed as revision 412 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent 976f969b
...@@ -2564,8 +2564,13 @@ int mpeg4_decode_picture_header(MpegEncContext * s) ...@@ -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"); if(s->gb.size>50){
return -1; 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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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 @@ ...@@ -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 { ...@@ -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];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment