Mercurial > mplayer.hg
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); |