comparison mplayer.c @ 18710:c528c6c518f1

Clean up audio pts handling, make audio pts tracking in the audio-only case work the same as with video.
author uau
date Wed, 14 Jun 2006 19:48:54 +0000
parents bee3186a06f7
children 4d87a5c4611c
comparison
equal deleted inserted replaced
18709:7ca8f5ab5136 18710:c528c6c518f1
2413 2413
2414 2414
2415 ///@} 2415 ///@}
2416 // Command2Property 2416 // Command2Property
2417 2417
2418
2419 // Return pts value corresponding to the end point of audio written to the
2420 // ao so far.
2421 static double written_audio_pts(sh_audio_t *sh_audio, demux_stream_t *d_audio)
2422 {
2423 // first calculate the end pts of audio that has been output by decoder
2424 double a_pts = sh_audio->pts;
2425 if (a_pts != MP_NOPTS_VALUE)
2426 // Good, decoder supports new way of calculating audio pts.
2427 // sh_audio->pts is the timestamp of the latest input packet with
2428 // known pts that the decoder has decoded. sh_audio->pts_bytes is
2429 // the amount of bytes the decoder has written after that timestamp.
2430 a_pts += sh_audio->pts_bytes / (double) sh_audio->o_bps;
2431 else {
2432 // Decoder doesn't support new way of calculating pts (or we're
2433 // being called before it has decoded anything with known timestamp).
2434 // Use the old method of audio pts calculation: take the timestamp
2435 // of last packet with known pts the decoder has read data from,
2436 // and add amount of bytes read after the beginning of that packet
2437 // divided by input bps. This will be inaccurate if the input/output
2438 // ratio is not constant for every audio packet or if it is constant
2439 // but not accurately known in sh_audio->i_bps.
2440
2441 a_pts = d_audio->pts;
2442 // ds_tell_pts returns gets bytes read after last timestamp from
2443 // demuxing layer, decoder might use sh_audio->a_in_buffer for bytes
2444 // it has read but not decoded
2445 a_pts += (ds_tell_pts(d_audio) - sh_audio->a_in_buffer_len) /
2446 (double)sh_audio->i_bps;
2447 }
2448 // Now a_pts hopefully holds the pts for end of audio from decoder.
2449 // Substract data in buffers between decoder and audio out.
2450
2451 // Decoded but not filtered
2452 a_pts -= sh_audio->a_buffer_len / (double)sh_audio->o_bps;
2453
2454 // Data that was ready for ao but was buffered because ao didn't fully
2455 // accept everything to internal buffers yet
2456 a_pts -= sh_audio->a_out_buffer_len * playback_speed / (double)ao_data.bps;
2457
2458 return a_pts;
2459 }
2460
2461 // Return pts value corresponding to currently playing audio.
2462 static double playing_audio_pts(sh_audio_t *sh_audio, demux_stream_t *d_audio,
2463 ao_functions_t *audio_out)
2464 {
2465 return written_audio_pts(sh_audio, d_audio) - playback_speed *
2466 audio_out->get_delay();
2467 }
2468
2469
2418 int main(int argc,char* argv[]){ 2470 int main(int argc,char* argv[]){
2419 2471
2420 2472
2421 char * mem_ptr; 2473 char * mem_ptr;
2422 2474
3537 int drop_frame=0; // current dropping status 3589 int drop_frame=0; // current dropping status
3538 int dropped_frames=0; // how many frames dropped since last non-dropped frame 3590 int dropped_frames=0; // how many frames dropped since last non-dropped frame
3539 int too_slow_frame_cnt=0; 3591 int too_slow_frame_cnt=0;
3540 int too_fast_frame_cnt=0; 3592 int too_fast_frame_cnt=0;
3541 // for auto-quality: 3593 // for auto-quality:
3542 float AV_delay=0; // average of A-V timestamp differences
3543 double vdecode_time; 3594 double vdecode_time;
3544 unsigned int lastframeout_ts=0; 3595 unsigned int lastframeout_ts=0;
3545 /*float time_frame_corr_avg=0;*/ /* unused */ 3596 /*float time_frame_corr_avg=0;*/ /* unused */
3546 3597
3547 float next_frame_time=0; 3598 float next_frame_time=0;
3676 } // while(sh_audio) 3727 } // while(sh_audio)
3677 3728
3678 if(!sh_video) { 3729 if(!sh_video) {
3679 // handle audio-only case: 3730 // handle audio-only case:
3680 if(!quiet) { 3731 if(!quiet) {
3681 float a_pos = sh_audio->delay - audio_out->get_delay() * playback_speed; 3732 double a_pos = playing_audio_pts(sh_audio, d_audio, audio_out);
3682 print_status(a_pos, 0, 0); 3733 print_status(a_pos, 0, 0);
3683 } 3734 }
3684 if(d_audio->eof && sh_audio->a_in_buffer_len <= 0 && sh_audio->a_buffer_len <= 0) eof = PT_NEXT_ENTRY; 3735 if(d_audio->eof && sh_audio->a_in_buffer_len <= 0 && sh_audio->a_buffer_len <= 0) eof = PT_NEXT_ENTRY;
3685 3736
3686 } else { 3737 } else {
3921 //====================== A-V TIMESTAMP CORRECTION: ========================= 3972 //====================== A-V TIMESTAMP CORRECTION: =========================
3922 3973
3923 current_module="av_sync"; 3974 current_module="av_sync";
3924 3975
3925 if(sh_audio){ 3976 if(sh_audio){
3926 double a_pts=0; 3977 double a_pts, v_pts;
3927 double v_pts=0; 3978
3928 3979 if (autosync)
3929 // unplayed bytes in our and soundcard/dma buffer:
3930 float delay=playback_speed*audio_out->get_delay()+(float)sh_audio->a_buffer_len/(float)sh_audio->o_bps;
3931
3932 if (autosync){
3933 /* 3980 /*
3934 * If autosync is enabled, the value for delay must be calculated 3981 * If autosync is enabled, the value for delay must be calculated
3935 * a bit differently. It is set only to the difference between 3982 * a bit differently. It is set only to the difference between
3936 * the audio and video timers. Any attempt to include the real 3983 * the audio and video timers. Any attempt to include the real
3937 * or corrected delay causes the pts_correction code below to 3984 * or corrected delay causes the pts_correction code below to
3939 * trying to measure. This keeps the two from competing, but still 3986 * trying to measure. This keeps the two from competing, but still
3940 * allows the code to correct for PTS drift *only*. (Using a delay 3987 * allows the code to correct for PTS drift *only*. (Using a delay
3941 * value here, even a "corrected" one, would be incompatible with 3988 * value here, even a "corrected" one, would be incompatible with
3942 * autosync mode.) 3989 * autosync mode.)
3943 */ 3990 */
3944 delay=sh_audio->delay; 3991 a_pts = written_audio_pts(sh_audio, d_audio) - sh_audio->delay;
3945 delay+=(float)sh_audio->a_buffer_len/(float)sh_audio->o_bps; 3992 else
3946 } 3993 a_pts = playing_audio_pts(sh_audio, d_audio, audio_out);
3947 delay += sh_audio->a_out_buffer_len*playback_speed/(float)ao_data.bps; 3994
3948
3949 {
3950 // PTS = (last timestamp) + (bytes after last timestamp)/(bytes per sec)
3951 a_pts = sh_audio->pts;
3952 if (a_pts == MP_NOPTS_VALUE) {
3953 // Decoder doesn't support tracking timestamps or demuxer doesn't
3954 // set them properly in individual packets, use old inaccurate method
3955 a_pts=d_audio->pts;
3956 a_pts+=(ds_tell_pts(d_audio)-sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps;
3957 }
3958 else
3959 a_pts += sh_audio->pts_bytes / (float)sh_audio->o_bps;
3960 }
3961 v_pts=sh_video ? sh_video->pts : d_video->pts; 3995 v_pts=sh_video ? sh_video->pts : d_video->pts;
3962
3963 mp_dbg(MSGT_AVSYNC,MSGL_DBG2,"### 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);
3964 3996
3965 { 3997 {
3966 static int drop_message=0; 3998 static int drop_message=0;
3967 float x; 3999 double AV_delay = a_pts - audio_delay - v_pts;
3968 AV_delay=(a_pts-delay-audio_delay)-v_pts; 4000 double x;
3969 if(AV_delay>0.5 && drop_frame_cnt>50 && drop_message==0){ 4001 if(AV_delay>0.5 && drop_frame_cnt>50 && drop_message==0){
3970 ++drop_message; 4002 ++drop_message;
3971 mp_msg(MSGT_AVSYNC,MSGL_WARN,MSGTR_SystemTooSlow); 4003 mp_msg(MSGT_AVSYNC,MSGL_WARN,MSGTR_SystemTooSlow);
3972 } 4004 }
3973 if (autosync) 4005 if (autosync)
3983 max_pts_correction=default_max_pts_correction; 4015 max_pts_correction=default_max_pts_correction;
3984 else 4016 else
3985 max_pts_correction=sh_video->frametime*0.10; // +-10% of time 4017 max_pts_correction=sh_video->frametime*0.10; // +-10% of time
3986 if(!frame_time_remaining){ sh_audio->delay+=x; c_total+=x;} // correction 4018 if(!frame_time_remaining){ sh_audio->delay+=x; c_total+=x;} // correction
3987 if(!quiet) 4019 if(!quiet)
3988 print_status(a_pts - audio_delay - delay, AV_delay, c_total); 4020 print_status(a_pts - audio_delay, AV_delay, c_total);
3989 } 4021 }
3990 4022
3991 } else { 4023 } else {
3992 // No audio: 4024 // No audio:
3993 4025
4568 float pos = 0; 4600 float pos = 0;
4569 if (sh_video) 4601 if (sh_video)
4570 pos = sh_video->pts; 4602 pos = sh_video->pts;
4571 else 4603 else
4572 if (sh_audio && audio_out) 4604 if (sh_audio && audio_out)
4573 pos = sh_audio->delay - audio_out->get_delay() * playback_speed; 4605 pos = playing_audio_pts(sh_audio, d_audio, audio_out);
4574 mp_msg(MSGT_GLOBAL, MSGL_INFO, "ANS_TIME_POSITION=%.1f\n", pos); 4606 mp_msg(MSGT_GLOBAL, MSGL_INFO, "ANS_TIME_POSITION=%.1f\n", pos);
4575 } break; 4607 } break;
4576 case MP_CMD_SWITCH_AUDIO : { 4608 case MP_CMD_SWITCH_AUDIO : {
4577 int current_id = demuxer->audio->id; 4609 int current_id = demuxer->audio->id;
4578 int v = demuxer_switch_audio(demuxer, cmd->args[0].v.i); 4610 int v = demuxer_switch_audio(demuxer, cmd->args[0].v.i);