From 0c099dc23b7b574b1218bbf891db2a9678ac3b13 Mon Sep 17 00:00:00 2001 From: arpi_esp Date: Sun, 13 May 2001 03:00:57 +0000 Subject: audio sync cleanup and -bps fixed git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@781 b3059339-0415-0410-9bf9-f77b7e298cf2 --- mplayer.c | 139 ++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 81 insertions(+), 58 deletions(-) diff --git a/mplayer.c b/mplayer.c index 30d2db67b1..720c552592 100644 --- a/mplayer.c +++ b/mplayer.c @@ -4,6 +4,7 @@ //#define SIMULATE_ALSA #define RESET_AUDIO(audio_fd) ioctl(audio_fd, SNDCTL_DSP_RESET, NULL) +//#define PAUSE_AUDIO(audio_fd) ioctl(audio_fd, SNDCTL_DSP_POST, NULL) //#define RESET_AUDIO(audio_fd) #include @@ -240,8 +241,11 @@ extern int num_elementary_packets101; extern picture_t *picture; static const int frameratecode2framerate[16] = { - 0, 24000*10000/1001, 24*10000,25*10000, 30000*10000/1001, 30*10000,50*10000,60000*10000/1001, - 60*10000, 0,0,0,0,0,0,0 + 0, + // Official mpeg1/2 framerates: + 24000*10000/1001, 24*10000,25*10000, 30000*10000/1001, 30*10000,50*10000,60000*10000/1001, 60*10000, + // libmpeg3's "Unofficial economy rates": + 1*10000,5*10000,10*10000,12*10000,15*10000,0,0 }; //**************************************************************************// @@ -455,7 +459,7 @@ int alsa=0; int audio_id=-1; int video_id=-1; int dvdsub_id=-1; -float default_max_pts_correction=0.01f; +float default_max_pts_correction=-1;//0.01f; int delay_corrected=1; float force_fps=0; float audio_delay=0; @@ -973,7 +977,15 @@ switch(file_format){ } // display info: sh_video->fps=frameratecode2framerate[picture->frame_rate_code]*0.0001f; - sh_video->frametime=10000.0f/(float)frameratecode2framerate[picture->frame_rate_code]; + if(!sh_video->fps){ + if(!force_fps){ + printf("FPS not specified (or invalid) in the header! Use the -fps option!\n"); + exit(1); + } + sh_video->frametime=0; + } else { + sh_video->frametime=10000.0f/(float)frameratecode2framerate[picture->frame_rate_code]; + } sh_video->disp_w=picture->display_picture_width; sh_video->disp_h=picture->display_picture_height; // info: @@ -1322,10 +1334,8 @@ int frame_corr_num=0; // float a_frame=0; // Audio float v_frame=0; // Video float time_frame=0; // Timer -float a_pts=0; -float v_pts=0; float c_total=0; -float max_pts_correction=default_max_pts_correction; +float max_pts_correction=0;//default_max_pts_correction; int eof=0; int force_redraw=0; float num_frames=0; // number of frames played @@ -1493,17 +1503,22 @@ if(!has_audio){ //==================== START PLAYING ======================= if(file_format==DEMUXER_TYPE_AVI && has_audio){ - a_pts=d_audio->pts; - audio_delay-=(float)(sh_audio->audio.dwInitialFrames-sh_video->video.dwInitialFrames)*sh_video->frametime; -// audio_delay-=(float)(sh_audio->audio.dwInitialFrames-sh_video->video.dwInitialFrames)/default_fps; + //a_pts=d_audio->pts; + printf("Initial frame delay A: %d V: %d\n",sh_audio->audio.dwInitialFrames,sh_video->video.dwInitialFrames); + if(!pts_from_bps){ + float x=(float)(sh_audio->audio.dwInitialFrames-sh_video->video.dwInitialFrames)*sh_video->frametime; + audio_delay-=x; + printf("AVI Initial frame delay: %5.3f\n",x); + } if(verbose){ - printf("AVI Initial frame delay: %5.3f\n",(float)(sh_audio->audio.dwInitialFrames-sh_video->video.dwInitialFrames)*sh_video->frametime); - printf("v: audio_delay=%5.3f buffer_delay=%5.3f a_pts=%5.3f a_frame=%5.3f\n", - audio_delay,audio_buffer_delay,a_pts,a_frame); +// printf("v: audio_delay=%5.3f buffer_delay=%5.3f a_pts=%5.3f a_frame=%5.3f\n", +// audio_delay,audio_buffer_delay,a_pts,a_frame); printf("START: a_pts=%5.3f v_pts=%5.3f \n",d_audio->pts,d_video->pts); } delay_corrected=0; // has to correct PTS diffs d_video->pts=0;d_audio->pts=0; // PTS is outdated now! +} else { + pts_from_bps=0; // it must be 0 for mpeg/asf ! } if(force_fps){ sh_video->fps=force_fps; @@ -1803,20 +1818,26 @@ switch(sh_video->codec->driver){ } } v_frame+=frame_time; - v_pts+=frame_time; + //v_pts+=frame_time; time_frame+=frame_time; // for nosound - // It's time to sleep... - time_frame-=GetRelativeTime(); // reset timer + if(file_format==DEMUXER_TYPE_MPEG_PS) d_video->pts+=frame_time; + + if(!drop_frame){ + + // It's time to sleep... + current_module="sleep"; + + time_frame-=GetRelativeTime(); // reset timer - if(has_audio){ + if(has_audio){ int delay=get_audio_delay(audio_fd); if(verbose>1)printf("delay=%d\n",delay); time_frame=v_frame; time_frame-=a_frame-(float)delay/(float)sh_audio->o_bps; - } else { + } else { if(time_frame<-0.1 || time_frame>0.1) time_frame=0; - } + } if(verbose>1)printf("sleep: %5.3f a:%6.3f v:%6.3f \n",time_frame,a_frame,v_frame); @@ -1828,12 +1849,13 @@ switch(sh_video->codec->driver){ time_frame-=GetRelativeTime(); } - if(!drop_frame){ current_module="flip_page"; video_out->flip_page(); - current_module=NULL; // usleep(50000); // test only! + } + + current_module=NULL; if(eof) break; if(force_redraw){ @@ -1848,66 +1870,69 @@ switch(sh_video->codec->driver){ #if 1 /*================ A-V TIMESTAMP CORRECTION: =========================*/ if(has_audio){ + float a_pts=0; + float v_pts=0; + // unplayed bytes in our and soundcard/dma buffer: int delay_bytes=get_audio_delay(audio_fd)+sh_audio->a_buffer_len; float delay=(float)delay_bytes/(float)sh_audio->o_bps; - if(pts_from_bps && (file_format==DEMUXER_TYPE_AVI)){ -// a_pts=(float)ds_tell(d_audio)/sh_audio->wf.nAvgBytesPerSec-(buffer_delay+audio_delay); - a_pts=(float)ds_tell(d_audio)/sh_audio->wf->nAvgBytesPerSec; + if(pts_from_bps){ + // PTS = (audio position)/(bytes per sec) + a_pts=(ds_tell(d_audio)-sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps; delay_corrected=1; // hack - } else - if(d_audio->pts){ -// printf("\n=== APTS a_pts=%5.3f v_pts=%5.3f === \n",d_audio->pts,d_video->pts); -#if 1 - if(!delay_corrected){ + } else { + if(!delay_corrected && d_audio->pts){ float x=d_audio->pts-d_video->pts-(delay+audio_delay); float y=-(delay+audio_delay); printf("Initial PTS delay: %5.3f sec (calculated: %5.3f)\n",x,y); audio_delay+=x; - //a_pts-=x; delay_corrected=1; if(verbose) printf("v: audio_delay=%5.3f buffer_delay=%5.3f a.pts=%5.3f v.pts=%5.3f\n", audio_delay,delay,d_audio->pts,d_video->pts); } -#endif -// a_pts=(ds_tell_pts(d_audio)+sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps; -// printf("a_pts+=%6.3f \n",a_pts); -// a_pts=d_audio->pts-a_pts; - + // PTS = (last timestamp) + (bytes after last timestamp)/(bytes per sec) a_pts=d_audio->pts; a_pts+=(ds_tell_pts(d_audio)-sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps; - - //a_pts=d_audio->pts; d_audio->pts=0; } - if(d_video->pts) v_pts=d_video->pts; - if(frame_corr_num==5){ - float x=(frame_correction/5.0f); + + v_pts=d_video->pts-frame_time; + + if(verbose)printf("### A:%8.3f (%8.3f) V:%8.3f A-V:%7.4f \n",a_pts,a_pts-audio_delay-delay,v_pts,(a_pts-delay-audio_delay)-v_pts); + + if(frame_corr_num==1){ + float x=frame_correction; if(delay_corrected){ // printf("A:%6.1f V:%6.1f A-V:%7.3f",a_pts-audio_delay-delay,v_pts,x); printf("A:%6.1f (%6.1f) V:%6.1f A-V:%7.3f",a_pts,a_pts-audio_delay-delay,v_pts,x); - x*=0.5f; + x*=0.1f; if(x<-max_pts_correction) x=-max_pts_correction; else if(x> max_pts_correction) x= max_pts_correction; - max_pts_correction=default_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 a_frame+=x; c_total+=x; - printf(" ct:%7.3f %3d %2d%% %2d%% %3.1f%% %d \r",c_total, + printf(" ct:%7.3f %3d %2d%% %2d%% %3.1f%% \r",c_total, (int)num_frames, (v_frame>0.5)?(int)(100.0*video_time_usage/(double)v_frame):0, (v_frame>0.5)?(int)(100.0*vout_time_usage/(double)v_frame):0, (v_frame>0.5)?(100.0*audio_time_usage/(double)v_frame):0 - ,drop_frame_cnt +// ,drop_frame_cnt // dbg_es_sent-dbg_es_rcvd ); fflush(stdout); } frame_corr_num=0; frame_correction=0; } + if(frame_corr_num>=0) frame_correction+=(a_pts-delay-audio_delay)-v_pts; + } else { // No audio: - if(d_video->pts) v_pts=d_video->pts; + //if(d_video->pts) + int v_pts=d_video->pts; if(frame_corr_num==5){ // printf("A: --- V:%6.1f \r",v_pts); printf("V:%6.1f %3d %2d%% %2d%% %3.1f%% \r",v_pts, @@ -1932,6 +1957,7 @@ switch(sh_video->codec->driver){ if(osd_function==OSD_PAUSE){ printf("\n------ PAUSED -------\r");fflush(stdout); + RESET_AUDIO(audio_fd); // stop audio #ifdef HAVE_GUI if ( nogui ) { @@ -2076,7 +2102,7 @@ switch(file_format){ // if(LOWORD(id)==aviTWOCC('0','0')){ // video frame if(avi_stream_id(id)==d_video->id){ // video frame if((--rel_seek_frames)<0 && ((AVIINDEXENTRY *)demuxer->idx)[video_chunk_pos].dwFlags&AVIIF_KEYFRAME) break; - v_pts+=(float)sh_video->video.dwScale/(float)sh_video->video.dwRate; + //v_pts+=(float)sh_video->video.dwScale/(float)sh_video->video.dwRate; ++skip_audio_bytes; } ++video_chunk_pos; @@ -2088,7 +2114,7 @@ switch(file_format){ // if(LOWORD(id)==aviTWOCC('0','0')){ // video frame if(avi_stream_id(id)==d_video->id){ // video frame if((++rel_seek_frames)>0 && ((AVIINDEXENTRY *)demuxer->idx)[video_chunk_pos].dwFlags&AVIIF_KEYFRAME) break; - v_pts-=(float)sh_video->video.dwScale/(float)sh_video->video.dwRate; + //v_pts-=(float)sh_video->video.dwScale/(float)sh_video->video.dwRate; --skip_audio_bytes; } --video_chunk_pos; @@ -2109,11 +2135,11 @@ switch(file_format){ } } //printf("v-pts recalc! %5.3f -> %5.3f \n",v_pts,avi_video_pts); - v_pts=avi_video_pts; -#else - avi_video_pts=v_pts; + //v_pts=avi_video_pts; +//#else + //avi_video_pts=v_pts; #endif - a_pts=avi_video_pts; + //a_pts=avi_video_pts; //a_pts=v_pts; //-(buffer_delay+audio_delay); if(has_audio){ @@ -2227,7 +2253,6 @@ switch(file_format){ newpos=demuxer->filepos+2324*75*rel_seek_secs; // 174.3 kbyte/sec else newpos=demuxer->filepos+(picture->bitrate*1000/16)*rel_seek_secs; -// picture->bitrate=2324*75*8; // standard VCD bitrate (75 sectors / sec) if(newposfilepos-demuxer->movi_start)/len; } - //printf("avi filepos = %d \n",vo_osd_progbar_value); - // printf("avi filepos = %d (len=%d) \n",demuxer->filepos,(demuxer->movi_end-demuxer->movi_start)); + //printf("avi filepos = %d (len=%d)\n",vo_osd_progbar_value,len); } //====================== re-sync audio: ===================== @@ -2329,7 +2351,7 @@ switch(file_format){ //================= Update OSD ==================== { int i; if(osd_level>=2){ - int pts=v_pts; + int pts=d_video->pts; if(pts==osd_last_pts-1) ++pts; else osd_last_pts=pts; vo_osd_text=osd_text_buffer; sprintf(vo_osd_text,"%c %02d:%02d:%02d",osd_function,pts/3600,(pts/60)%60,pts%60); @@ -2341,9 +2363,10 @@ switch(file_format){ // find sub if(subtitles){ + int pts=d_video->pts; if(sub_fps==0) sub_fps=sh_video->fps; current_module="find_sub"; - find_sub(subtitles,sub_uses_time?(100*(v_pts+sub_delay)):((v_pts+sub_delay)*sub_fps)); // FIXME! frame counter... + find_sub(subtitles,sub_uses_time?(100*(pts+sub_delay)):((pts+sub_delay)*sub_fps)); // FIXME! frame counter... current_module=NULL; } -- cgit v1.2.3