mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
correcter mpeg4 headers
Originally committed as revision 1376 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
3cef52271d
commit
41773b735e
@ -826,8 +826,10 @@ typedef struct AVCodecContext {
|
|||||||
#define FF_DEBUG_MB_TYPE 8
|
#define FF_DEBUG_MB_TYPE 8
|
||||||
#define FF_DEBUG_QP 16
|
#define FF_DEBUG_QP 16
|
||||||
#define FF_DEBUG_MV 32
|
#define FF_DEBUG_MV 32
|
||||||
#define FF_DEBUG_VIS_MV 64
|
#define FF_DEBUG_VIS_MV 0x00000040
|
||||||
#define FF_DEBUG_SKIP 128
|
#define FF_DEBUG_SKIP 0x00000080
|
||||||
|
#define FF_DEBUG_STARTCODE 0x00000100
|
||||||
|
#define FF_DEBUG_PTS 0x00000200
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* error
|
* error
|
||||||
|
@ -1564,21 +1564,77 @@ void ff_set_mpeg4_time(MpegEncContext * s, int picture_number){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mpeg4_encode_vol_header(MpegEncContext * s)
|
static void mpeg4_encode_gop_header(MpegEncContext * s){
|
||||||
|
int hours, minutes, seconds;
|
||||||
|
|
||||||
|
put_bits(&s->pb, 16, 0);
|
||||||
|
put_bits(&s->pb, 16, GOP_STARTCODE);
|
||||||
|
|
||||||
|
seconds= s->time/s->time_increment_resolution;
|
||||||
|
minutes= seconds/60; seconds %= 60;
|
||||||
|
hours= minutes/60; minutes %= 60;
|
||||||
|
hours%=24;
|
||||||
|
|
||||||
|
put_bits(&s->pb, 5, hours);
|
||||||
|
put_bits(&s->pb, 6, minutes);
|
||||||
|
put_bits(&s->pb, 1, 1);
|
||||||
|
put_bits(&s->pb, 6, seconds);
|
||||||
|
|
||||||
|
put_bits(&s->pb, 1, 0); //closed gov == NO
|
||||||
|
put_bits(&s->pb, 1, 0); //broken link == NO
|
||||||
|
|
||||||
|
ff_mpeg4_stuffing(&s->pb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mpeg4_encode_visual_object_header(MpegEncContext * s){
|
||||||
|
int profile_and_level_indication;
|
||||||
|
int vo_ver_id;
|
||||||
|
|
||||||
|
if(s->max_b_frames || s->quarter_sample){
|
||||||
|
profile_and_level_indication= 0xF1; // adv simple level 1
|
||||||
|
vo_ver_id= 5;
|
||||||
|
}else{
|
||||||
|
profile_and_level_indication= 0x01; // simple level 1
|
||||||
|
vo_ver_id= 1;
|
||||||
|
}
|
||||||
|
//FIXME levels
|
||||||
|
|
||||||
|
put_bits(&s->pb, 16, 0);
|
||||||
|
put_bits(&s->pb, 16, VOS_STARTCODE);
|
||||||
|
|
||||||
|
put_bits(&s->pb, 8, profile_and_level_indication);
|
||||||
|
|
||||||
|
put_bits(&s->pb, 16, 0);
|
||||||
|
put_bits(&s->pb, 16, VISUAL_OBJ_STARTCODE);
|
||||||
|
|
||||||
|
put_bits(&s->pb, 1, 1);
|
||||||
|
put_bits(&s->pb, 4, vo_ver_id);
|
||||||
|
put_bits(&s->pb, 3, 1); //priority
|
||||||
|
|
||||||
|
put_bits(&s->pb, 4, 1); //visual obj type== video obj
|
||||||
|
|
||||||
|
put_bits(&s->pb, 1, 0); //video signal type == no clue //FIXME
|
||||||
|
|
||||||
|
ff_mpeg4_stuffing(&s->pb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mpeg4_encode_vol_header(MpegEncContext * s, int vo_number, int vol_number)
|
||||||
{
|
{
|
||||||
int vo_ver_id=2; //must be 2 if we want GMC or q-pel
|
int vo_ver_id;
|
||||||
char buf[255];
|
char buf[255];
|
||||||
|
|
||||||
if(s->max_b_frames){
|
if(s->max_b_frames || s->quarter_sample){
|
||||||
|
vo_ver_id= 5;
|
||||||
s->vo_type= ADV_SIMPLE_VO_TYPE;
|
s->vo_type= ADV_SIMPLE_VO_TYPE;
|
||||||
}else{
|
}else{
|
||||||
|
vo_ver_id= 1;
|
||||||
s->vo_type= SIMPLE_VO_TYPE;
|
s->vo_type= SIMPLE_VO_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
put_bits(&s->pb, 16, 0);
|
put_bits(&s->pb, 16, 0);
|
||||||
put_bits(&s->pb, 16, 0x100); /* video obj */
|
put_bits(&s->pb, 16, 0x100 + vo_number); /* video obj */
|
||||||
put_bits(&s->pb, 16, 0);
|
put_bits(&s->pb, 16, 0);
|
||||||
put_bits(&s->pb, 16, 0x120); /* video obj layer */
|
put_bits(&s->pb, 16, 0x120 + vol_number); /* video obj layer */
|
||||||
|
|
||||||
put_bits(&s->pb, 1, 0); /* random access vol */
|
put_bits(&s->pb, 1, 0); /* random access vol */
|
||||||
put_bits(&s->pb, 8, s->vo_type); /* video obj type indication */
|
put_bits(&s->pb, 8, s->vo_type); /* video obj type indication */
|
||||||
@ -1621,7 +1677,7 @@ static void mpeg4_encode_vol_header(MpegEncContext * s)
|
|||||||
put_bits(&s->pb, 1, 1); /* obmc disable */
|
put_bits(&s->pb, 1, 1); /* obmc disable */
|
||||||
if (vo_ver_id == 1) {
|
if (vo_ver_id == 1) {
|
||||||
put_bits(&s->pb, 1, s->vol_sprite_usage=0); /* sprite enable */
|
put_bits(&s->pb, 1, s->vol_sprite_usage=0); /* sprite enable */
|
||||||
}else{ /* vo_ver_id == 2 */
|
}else{
|
||||||
put_bits(&s->pb, 2, s->vol_sprite_usage=0); /* sprite enable */
|
put_bits(&s->pb, 2, s->vol_sprite_usage=0); /* sprite enable */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1665,8 +1721,13 @@ void mpeg4_encode_picture_header(MpegEncContext * s, int picture_number)
|
|||||||
int time_div, time_mod;
|
int time_div, time_mod;
|
||||||
|
|
||||||
if(s->pict_type==I_TYPE){
|
if(s->pict_type==I_TYPE){
|
||||||
if(picture_number==0 || !s->strict_std_compliance)
|
if(picture_number - s->last_vo_picture_number >= 300 || picture_number==0){
|
||||||
mpeg4_encode_vol_header(s);
|
mpeg4_encode_visual_object_header(s);
|
||||||
|
mpeg4_encode_vol_header(s, 0, 0);
|
||||||
|
|
||||||
|
s->last_vo_picture_number= picture_number;
|
||||||
|
}
|
||||||
|
mpeg4_encode_gop_header(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
s->partitioned_frame= s->data_partitioning && s->pict_type!=B_TYPE;
|
s->partitioned_frame= s->data_partitioning && s->pict_type!=B_TYPE;
|
||||||
@ -1674,7 +1735,7 @@ void mpeg4_encode_picture_header(MpegEncContext * s, int picture_number)
|
|||||||
//printf("num:%d rate:%d base:%d\n", s->picture_number, s->frame_rate, FRAME_RATE_BASE);
|
//printf("num:%d rate:%d base:%d\n", s->picture_number, s->frame_rate, FRAME_RATE_BASE);
|
||||||
|
|
||||||
put_bits(&s->pb, 16, 0); /* vop header */
|
put_bits(&s->pb, 16, 0); /* vop header */
|
||||||
put_bits(&s->pb, 16, 0x1B6); /* vop header */
|
put_bits(&s->pb, 16, VOP_STARTCODE); /* vop header */
|
||||||
put_bits(&s->pb, 2, s->pict_type - 1); /* pict type: I = 0 , P = 1 */
|
put_bits(&s->pb, 2, s->pict_type - 1); /* pict type: I = 0 , P = 1 */
|
||||||
|
|
||||||
time_div= s->time/s->time_increment_resolution;
|
time_div= s->time/s->time_increment_resolution;
|
||||||
@ -4147,6 +4208,22 @@ printf("offset: %d:%d , delta: %d %d %d %d, shift %d\n",
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int mpeg4_decode_gop_header(MpegEncContext * s, GetBitContext *gb){
|
||||||
|
int hours, minutes, seconds;
|
||||||
|
|
||||||
|
hours= get_bits(gb, 5);
|
||||||
|
minutes= get_bits(gb, 6);
|
||||||
|
skip_bits1(gb);
|
||||||
|
seconds= get_bits(gb, 6);
|
||||||
|
|
||||||
|
s->time_base= seconds + 60*(minutes + 60*hours);
|
||||||
|
|
||||||
|
skip_bits1(gb);
|
||||||
|
skip_bits1(gb);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int decode_vol_header(MpegEncContext *s, GetBitContext *gb){
|
static int decode_vol_header(MpegEncContext *s, GetBitContext *gb){
|
||||||
int width, height, vo_ver_id;
|
int width, height, vo_ver_id;
|
||||||
|
|
||||||
@ -4504,6 +4581,8 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){
|
|||||||
}
|
}
|
||||||
|
|
||||||
s->current_picture.pts= s->time*1000LL*1000LL / s->time_increment_resolution;
|
s->current_picture.pts= s->time*1000LL*1000LL / s->time_increment_resolution;
|
||||||
|
if(s->avctx->debug&FF_DEBUG_PTS)
|
||||||
|
printf("MPEG4 PTS: %f\n", s->current_picture.pts/(1000.0*1000.0));
|
||||||
|
|
||||||
if(check_marker(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");
|
printf("hmm, seems the headers arnt complete, trying to guess time_increment_bits\n");
|
||||||
@ -4668,17 +4747,51 @@ int ff_mpeg4_decode_picture_header(MpegEncContext * s, GetBitContext *gb)
|
|||||||
if((startcode&0xFFFFFF00) != 0x100)
|
if((startcode&0xFFFFFF00) != 0x100)
|
||||||
continue; //no startcode
|
continue; //no startcode
|
||||||
|
|
||||||
|
if(s->avctx->debug&FF_DEBUG_STARTCODE){
|
||||||
|
printf("startcode: %3X ", startcode);
|
||||||
|
if (startcode<=0x11F) printf("Video Object Start");
|
||||||
|
else if(startcode<=0x12F) printf("Video Object Layer Start");
|
||||||
|
else if(startcode<=0x13F) printf("Reserved");
|
||||||
|
else if(startcode<=0x15F) printf("FGS bp start");
|
||||||
|
else if(startcode<=0x1AF) printf("Reserved");
|
||||||
|
else if(startcode==0x1B0) printf("Visual Object Seq Start");
|
||||||
|
else if(startcode==0x1B1) printf("Visual Object Seq End");
|
||||||
|
else if(startcode==0x1B2) printf("User Data");
|
||||||
|
else if(startcode==0x1B3) printf("Group of VOP start");
|
||||||
|
else if(startcode==0x1B4) printf("Video Session Error");
|
||||||
|
else if(startcode==0x1B5) printf("Visual Object Start");
|
||||||
|
else if(startcode==0x1B6) printf("Video Object Plane start");
|
||||||
|
else if(startcode==0x1B7) printf("slice start");
|
||||||
|
else if(startcode==0x1B8) printf("extension start");
|
||||||
|
else if(startcode==0x1B9) printf("fgs start");
|
||||||
|
else if(startcode==0x1BA) printf("FBA Object start");
|
||||||
|
else if(startcode==0x1BB) printf("FBA Object Plane start");
|
||||||
|
else if(startcode==0x1BC) printf("Mesh Object start");
|
||||||
|
else if(startcode==0x1BD) printf("Mesh Object Plane start");
|
||||||
|
else if(startcode==0x1BE) printf("Still Textutre Object start");
|
||||||
|
else if(startcode==0x1BF) printf("Textutre Spatial Layer start");
|
||||||
|
else if(startcode==0x1C0) printf("Textutre SNR Layer start");
|
||||||
|
else if(startcode==0x1C1) printf("Textutre Tile start");
|
||||||
|
else if(startcode==0x1C2) printf("Textutre Shape Layer start");
|
||||||
|
else if(startcode==0x1C3) printf("stuffing start");
|
||||||
|
else if(startcode<=0x1C5) printf("reserved");
|
||||||
|
else if(startcode<=0x1FF) printf("System start");
|
||||||
|
printf(" at %d\n", get_bits_count(gb));
|
||||||
|
}
|
||||||
|
|
||||||
switch(startcode){
|
switch(startcode){
|
||||||
case 0x120:
|
case 0x120:
|
||||||
decode_vol_header(s, gb);
|
decode_vol_header(s, gb);
|
||||||
break;
|
break;
|
||||||
case 0x1b2:
|
case USER_DATA_STARTCODE:
|
||||||
decode_user_data(s, gb);
|
decode_user_data(s, gb);
|
||||||
break;
|
break;
|
||||||
case 0x1b6:
|
case GOP_STARTCODE:
|
||||||
|
mpeg4_decode_gop_header(s, gb);
|
||||||
|
break;
|
||||||
|
case VOP_STARTCODE:
|
||||||
return decode_vop_header(s, gb);
|
return decode_vop_header(s, gb);
|
||||||
default:
|
default:
|
||||||
// printf("startcode %X found\n", startcode);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,12 @@
|
|||||||
#define MB_TYPE_B_BACKW 2
|
#define MB_TYPE_B_BACKW 2
|
||||||
#define MB_TYPE_B_FORW 3
|
#define MB_TYPE_B_FORW 3
|
||||||
|
|
||||||
|
#define VOS_STARTCODE 0x1B0
|
||||||
|
#define USER_DATA_STARTCODE 0x1B2
|
||||||
|
#define GOP_STARTCODE 0x1B3
|
||||||
|
#define VISUAL_OBJ_STARTCODE 0x1B5
|
||||||
|
#define VOP_STARTCODE 0x1B6
|
||||||
|
|
||||||
/* dc encoding for mpeg4 */
|
/* dc encoding for mpeg4 */
|
||||||
const UINT8 DCtab_lum[13][2] =
|
const UINT8 DCtab_lum[13][2] =
|
||||||
{
|
{
|
||||||
|
@ -435,6 +435,7 @@ typedef struct MpegEncContext {
|
|||||||
INT8 (*field_select_table)[2]; /* wtf, no really another table for interlaced b frames */
|
INT8 (*field_select_table)[2]; /* wtf, no really another table for interlaced b frames */
|
||||||
int t_frame; /* time distance of first I -> B, used for interlaced b frames */
|
int t_frame; /* time distance of first I -> B, used for interlaced b frames */
|
||||||
int padding_bug_score; /* used to detect the VERY common padding bug in MPEG4 */
|
int padding_bug_score; /* used to detect the VERY common padding bug in MPEG4 */
|
||||||
|
int last_vo_picture_number; /* last picture number for which we added a VOS/VO/VOL header */
|
||||||
|
|
||||||
/* divx specific, used to workaround (many) bugs in divx5 */
|
/* divx specific, used to workaround (many) bugs in divx5 */
|
||||||
int divx_version;
|
int divx_version;
|
||||||
|
@ -11,11 +11,11 @@ a6527e93fe0e2e5942934efbde59f78b *./data/a-h263.avi
|
|||||||
f3bc40b0a09eb06504fa5b51eb9135ee *./data/out.yuv
|
f3bc40b0a09eb06504fa5b51eb9135ee *./data/out.yuv
|
||||||
a11e0b741fa3c7fc491fb58ab8f7ca8d *./data/a-h263p.avi
|
a11e0b741fa3c7fc491fb58ab8f7ca8d *./data/a-h263p.avi
|
||||||
615e3db2bdc535ca5b17996b29cabf24 *./data/out.yuv
|
615e3db2bdc535ca5b17996b29cabf24 *./data/out.yuv
|
||||||
5d7af332678d590e921064337ecde8ac *./data/a-odivx.avi
|
466e2365c9027dea8695cf205adf3b9d *./data/a-odivx.avi
|
||||||
3ede54eadc97f43b4ab260faeb5e8674 *./data/out.yuv
|
3ede54eadc97f43b4ab260faeb5e8674 *./data/out.yuv
|
||||||
9638438b206816d6cca55a2f822abc24 *./data/a-mpeg4-rc.avi
|
5811f89254bc1f59528247f3daf11c1f *./data/a-mpeg4-rc.avi
|
||||||
d34057ff0806320c8be54fe34210c937 *./data/out.yuv
|
d34057ff0806320c8be54fe34210c937 *./data/out.yuv
|
||||||
4be05fbae92279715a3e88feec87da8e *./data/a-mpeg4-adv.avi
|
5fa5a878e036d459edd08d873af6a03e *./data/a-mpeg4-adv.avi
|
||||||
59d969f054ed466da9bc9b4c211620fb *./data/out.yuv
|
59d969f054ed466da9bc9b4c211620fb *./data/out.yuv
|
||||||
2846c8e3d97d7395eb746bfce44e0443 *./data/a-mjpeg.avi
|
2846c8e3d97d7395eb746bfce44e0443 *./data/a-mjpeg.avi
|
||||||
278033451d7a6bfeb8339abbe4228499 *./data/out.yuv
|
278033451d7a6bfeb8339abbe4228499 *./data/out.yuv
|
||||||
|
Loading…
Reference in New Issue
Block a user