1
0
mirror of https://github.com/mpv-player/mpv synced 2025-02-19 22:36:55 +00:00

input A-V sync correction

git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@2606 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
arpi 2001-11-01 02:31:23 +00:00
parent a8a127a8bd
commit 4fa41be71e

View File

@ -40,10 +40,6 @@ extern int cache_fill_status;
#define cache_fill_status 0
#endif
// AVI demuxer params:
static float c_total=0;
int delay_corrected=1;
char *audio_codec=NULL; // override audio codec
char *video_codec=NULL; // override video codec
int audio_family=-1; // override audio codec family
@ -62,6 +58,12 @@ static double audio_time_usage=0;
static int total_time_usage_start=0;
static int benchmark=0;
// A-V sync:
int delay_corrected=1;
static float default_max_pts_correction=-1;//0.01f;
static float max_pts_correction=0;//default_max_pts_correction;
static float c_total=0;
int force_fps=0;
//#include "libmpeg2/mpeg2.h"
@ -170,6 +172,8 @@ lame_global_flags *lame;
float audio_preload=0.3;
float v_timer_corr=0;
//int out_buffer_size=0x200000;
//unsigned char* out_buffer=malloc(out_buffer_size);
@ -181,13 +185,13 @@ float audio_preload=0.3;
exit(0); // From unknown reason a hangup occurs here :((((((
}
dvd_title=2;
// dvd_title=2;
if(argc>1)
stream=open_stream(argv[1],0,&file_format);
else
stream=open_stream("/1/!ize/dinosaur.dvdrip.svcd-emb.mpg",0,&file_format);
// stream=open_stream("/3d/abcug/Weird AL - Amish Paradise (MUSIC VIDEO).mpeg",0,&file_format);
// stream=open_stream("/1/!ize/dinosaur.dvdrip.svcd-emb.mpg",0,&file_format);
stream=open_stream("/3d/abcug/Weird AL - Amish Paradise (MUSIC VIDEO).mpeg",0,&file_format);
// stream=open_stream("/3d/divx/405divx_sm_v2[1].avi",0,&file_format);
// stream=open_stream("/dev/cdrom",2,&file_format); // VCD track 2
@ -414,7 +418,7 @@ case VCODEC_DIVX4:
enc_param.x_dim=sh_video->disp_w;
enc_param.y_dim=sh_video->disp_h;
enc_param.framerate=sh_video->fps;
enc_param.bitrate=1800000;
enc_param.bitrate=800000;
enc_param.rc_period=0;
enc_param.rc_reaction_period=0;
enc_param.rc_reaction_ratio=0;
@ -475,10 +479,9 @@ while(!eof){
if(sh_audio){
// get audio:
while(mux_a->timer-audio_preload<mux_v->timer){
// copy 0.5 sec of audio
int len;
if(mux_a->h.dwSampleSize){
// CBR
// CBR - copy 0.5 sec of audio
switch(mux_a->codec){
case 0: // copy
len=sh_audio->i_bps/2;
@ -487,17 +490,17 @@ if(sh_audio){
len=demux_read_data(sh_audio->ds,mux_a->buffer,len);
break;
case ACODEC_PCM:
// printf("Decode!\n");
len=mux_a->h.dwSampleSize*(mux_a->h.dwRate/2);
len=dec_audio(sh_audio,mux_a->buffer,len);
break;
}
// printf("%d -> ",len);
// printf("%d \n",len);
} else {
// VBR
// printf("not yet implemented!\n");
// VBR - encode/copy an audio frame
switch(mux_a->codec){
case 0: // copy
printf("not yet implemented!\n");
break;
case ACODEC_VBRMP3:
while(mux_a->buffer_len<4){
unsigned char tmp[2304];
int len=dec_audio(sh_audio,tmp,2304);
@ -521,6 +524,8 @@ if(sh_audio){
if(len<0) break; // error
mux_a->buffer_len+=len;
}
break;
}
}
if(len<=0) break; // EOF?
aviwrite_write_chunk(muxer,mux_a,muxer_f,len,0);
@ -534,39 +539,12 @@ if(sh_audio){
// get video frame!
in_size=video_read_frame(sh_video,&frame_time,&start,force_fps);
if(in_size<0){ eof=1; break; }
sh_video->timer+=frame_time;
if(sh_audio){
if(pts_from_bps){
unsigned int samples=(sh_audio->audio.dwSampleSize)?
((ds_tell(d_audio)-sh_audio->a_in_buffer_len)/sh_audio->audio.dwSampleSize) :
(d_audio->pack_no); // <- used for VBR audio
a_pts=samples*(float)sh_audio->audio.dwScale/(float)sh_audio->audio.dwRate;
delay_corrected=1;
} else {
// PTS = (last timestamp) + (bytes after last timestamp)/(bytes per sec)
a_pts=d_audio->pts;
if(!delay_corrected) if(a_pts) delay_corrected=1;
//printf("*** %5.3f ***\n",a_pts);
a_pts+=(ds_tell_pts(d_audio)-sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps;
}
v_pts=d_video->pts;
}
mp_msg(MSGT_AVSYNC,MSGL_STATUS,"A:%6.1f V:%6.1f A-V:%7.3f ct:%7.3f %3d/%3d %2d%% %2d%% %4.1f%% %d%%\r",
a_pts,v_pts,a_pts-v_pts,c_total,
(int)sh_video->num_frames,(int)sh_video->num_frames_decoded,
(sh_video->timer>0.5)?(int)(100.0*video_time_usage/(double)sh_video->timer):0,
(sh_video->timer>0.5)?(int)(100.0*vout_time_usage/(double)sh_video->timer):0,
(sh_video->timer>0.5)?(100.0*audio_time_usage/(double)sh_video->timer):0
,cache_fill_status
);
fflush(stdout);
// if(!blit_frame) continue;
if(v_timer_corr<2*sh_video->frametime){
// don't have to skip frame.
switch(mux_v->codec){
case 0:
mux_v->buffer=start;
@ -601,6 +579,72 @@ case VCODEC_DIVX4:
aviwrite_write_chunk(muxer,mux_v,muxer_f,enc_frame.length,enc_result.is_key_frame?0x10:0);
break;
}
if(v_timer_corr<-2*sh_video->frametime){
// duplicate frame
printf("\nduplicate frame!!! \n");
aviwrite_write_chunk(muxer,mux_v,muxer_f,0,0);
v_timer_corr+=(float)mux_v->h.dwScale/mux_v->h.dwRate;
// v_timer_corr=0;
}
} else {
// skip frame
printf("\nskip frame!!! \n");
v_timer_corr-=(float)mux_v->h.dwScale/mux_v->h.dwRate;
// v_timer_corr=0;
}
if(sh_audio){
float AV_delay,x;
// A-V sync!
if(pts_from_bps){
unsigned int samples=(sh_audio->audio.dwSampleSize)?
((ds_tell(d_audio)-sh_audio->a_in_buffer_len)/sh_audio->audio.dwSampleSize) :
(d_audio->pack_no); // <- used for VBR audio
a_pts=samples*(float)sh_audio->audio.dwScale/(float)sh_audio->audio.dwRate;
delay_corrected=1;
} else {
// PTS = (last timestamp) + (bytes after last timestamp)/(bytes per sec)
a_pts=d_audio->pts;
if(!delay_corrected) if(a_pts) delay_corrected=1;
//printf("*** %5.3f ***\n",a_pts);
a_pts+=(ds_tell_pts(d_audio)-sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps;
}
v_pts=d_video->pts;
// av = compensated (with out buffering delay) A-V diff
AV_delay=(a_pts-v_pts); AV_delay-=mux_a->timer-(mux_v->timer-v_timer_corr);
// compensate input video timer by av:
x=AV_delay*0.1f;
if(x<-max_pts_correction) x=-max_pts_correction; else
if(x> max_pts_correction) x= max_pts_correction;
if(default_max_pts_correction>=0)
max_pts_correction=default_max_pts_correction;
else
max_pts_correction=sh_video->frametime*0.10; // +-10% of time
// sh_video->timer-=x;
c_total+=x;
v_timer_corr+=x;
printf("A:%6.1f V:%6.1f A-V:%7.3f oAV:%7.3f diff:%7.3f ct:%7.3f vtc:%7.3f \r",
a_pts,v_pts,a_pts-v_pts,
(float)(mux_a->timer-mux_v->timer),
AV_delay, c_total, v_timer_corr );
}
#if 0
mp_msg(MSGT_AVSYNC,MSGL_STATUS,"A:%6.1f V:%6.1f A-V:%7.3f ct:%7.3f %3d/%3d %2d%% %2d%% %4.1f%% %d%%\r",
a_pts,v_pts,a_pts-v_pts,c_total,
(int)sh_video->num_frames,(int)sh_video->num_frames_decoded,
(sh_video->timer>0.5)?(int)(100.0*video_time_usage/(double)sh_video->timer):0,
(sh_video->timer>0.5)?(int)(100.0*vout_time_usage/(double)sh_video->timer):0,
(sh_video->timer>0.5)?(100.0*audio_time_usage/(double)sh_video->timer):0
,cache_fill_status
);
#endif
fflush(stdout);
} // while(!eof)