1
mirror of https://github.com/mpv-player/mpv synced 2024-08-04 14:59:58 +02:00

Clean up audio pts handling, make audio pts tracking in the audio-only

case work the same as with video.


git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@18713 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
uau 2006-06-14 19:48:54 +00:00
parent 2727b16cbb
commit 6723323303
10 changed files with 66 additions and 52 deletions

View File

@ -248,7 +248,6 @@ static void demux_aac_seek(demuxer_t *demuxer, float rel_seek_secs, float audio_
nf -= num;
}
}
sh_audio->delay = priv->last_pts - (ds_tell_pts(demuxer->audio)-sh_audio->a_in_buffer_len)/(float)priv->bitrate;
}

View File

@ -493,9 +493,7 @@ static void demux_seek_asf(demuxer_t *demuxer,float rel_seek_secs,float audio_de
ds_fill_buffer(d_audio);
}
if (d_video->id < 0)
sh_audio->delay = d_audio->pts;
else
if (d_video->id >= 0)
while(1){
if(sh_audio && !d_audio->eof){
float a_pts=d_audio->pts;

View File

@ -620,8 +620,7 @@ static int demux_audio_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds) {
}
resize_demux_packet(dp, l);
ds->pts = priv->last_pts - (ds_tell_pts(demux->audio) -
sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps;
dp->pts = priv->last_pts;
ds_add_packet(ds, dp);
return 1;
}
@ -667,7 +666,6 @@ static void demux_audio_seek(demuxer_t *demuxer,float rel_seek_secs,float audio_
}
if(len > 0)
high_res_mp3_seek(demuxer,len);
sh_audio->delay = priv->last_pts - (ds_tell_pts(demuxer->audio)-sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps;
return;
}
@ -679,13 +677,10 @@ static void demux_audio_seek(demuxer_t *demuxer,float rel_seek_secs,float audio_
if(demuxer->movi_end && pos >= demuxer->movi_end) {
pos = demuxer->movi_end;
//sh_audio->delay = (stream_tell(s) - demuxer->movi_start)/(float)sh_audio->i_bps;
//return;
} else if(pos < demuxer->movi_start)
pos = demuxer->movi_start;
priv->last_pts = (pos-demuxer->movi_start)/(float)sh_audio->i_bps;
sh_audio->delay = priv->last_pts - (ds_tell_pts(demuxer->audio)-sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps;
switch(priv->frmt) {
case WAV:

View File

@ -78,7 +78,6 @@ static void demux_demuxers_seek(demuxer_t *demuxer,float rel_seek_secs,float aud
// In case the demuxer don't set pts
if(!demuxer->audio->pts)
demuxer->audio->pts = pos-((ds_tell_pts(demuxer->audio)-sh->a_in_buffer_len)/(float)sh->i_bps);
sh->delay = 0;
}
if(priv->sd != priv->vd)

View File

@ -2123,8 +2123,6 @@ static void demux_seek_mov(demuxer_t *demuxer,float pts,float audio_delay,int fl
//if(!(flags&1)) pts+=ds->pts;
ds->pts=mov_seek_track(trak,pts,flags);
if (ds->pts < 0) ds->eof = 1;
if (demuxer->video->id < 0)
((sh_audio_t*)ds->sh)->delay = ds->pts;
}
}

View File

@ -145,8 +145,7 @@ static int demux_mpc_fill_buffer(demuxer_t *demux, demux_stream_t *ds) {
priv->last_pts = 0;
else
priv->last_pts += priv->pts_per_packet;
ds->pts = priv->last_pts - (ds_tell_pts(demux->audio) -
sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps;
dp->pts = priv->last_pts;
ds_add_packet(ds, dp);
return 1;
}
@ -177,8 +176,6 @@ static void demux_mpc_seek(demuxer_t *demuxer,float rel_seek_secs,float audio_de
if (s->eof) break;
}
if (!sh_audio) return;
sh_audio->delay = priv->last_pts - (ds_tell_pts(demuxer->audio) -
sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps;
}
static void demux_close_mpc(demuxer_t* demuxer) {

View File

@ -1599,8 +1599,6 @@ static void demux_ogg_seek(demuxer_t *demuxer,float rel_seek_secs,float audio_de
vo_osd_changed(OSDTYPE_SUBTITLE);
clear_sub = -1;
demux_ogg_add_packet(ds,os,ds->id,&op);
if (demuxer->video->id < 0)
sh_audio->delay = pts;
return;
}
}

View File

@ -92,7 +92,6 @@ static void demux_rawaudio_seek(demuxer_t *demuxer,float rel_seek_secs,float aud
pos -= (pos % (sh_audio->channels * sh_audio->samplesize) );
stream_seek(s,pos);
sh_audio->delay= (pos-ds_tell_pts(demuxer->audio)-sh_audio->a_in_buffer_len) / (float)(sh_audio->wf->nAvgBytesPerSec);
// printf("demux_rawaudio: streamtell=%d\n",(int)stream_tell(demuxer->stream));
}

View File

@ -287,7 +287,7 @@ static int demux_xmms_fill_buffer(demuxer_t* demuxer, demux_stream_t *ds) {
pthread_mutex_lock(&xmms_mutex);
dp = new_demux_packet(XMMS_PACKETSIZE/2);
ds->pts = priv->spos / sh_audio->wf->nAvgBytesPerSec;
dp->pts = priv->spos / sh_audio->wf->nAvgBytesPerSec;
ds->pos = priv->spos;
memcpy(dp->buffer,xmms_audiobuffer,XMMS_PACKETSIZE/2);
@ -319,7 +319,6 @@ static void demux_xmms_seek(demuxer_t *demuxer,float rel_seek_secs,float audio_d
priv->ip->seek((pos<0)?0:pos);
priv->spos=pos * sh_audio->wf->nAvgBytesPerSec;
sh_audio->delay=pos; //priv->spos / sh_audio->wf->nAvgBytesPerSec;
}
static void demux_close_xmms(demuxer_t* demuxer) {

View File

@ -2415,6 +2415,58 @@ if(sh_audio){
///@}
// Command2Property
// Return pts value corresponding to the end point of audio written to the
// ao so far.
static double written_audio_pts(sh_audio_t *sh_audio, demux_stream_t *d_audio)
{
// first calculate the end pts of audio that has been output by decoder
double a_pts = sh_audio->pts;
if (a_pts != MP_NOPTS_VALUE)
// Good, decoder supports new way of calculating audio pts.
// sh_audio->pts is the timestamp of the latest input packet with
// known pts that the decoder has decoded. sh_audio->pts_bytes is
// the amount of bytes the decoder has written after that timestamp.
a_pts += sh_audio->pts_bytes / (double) sh_audio->o_bps;
else {
// Decoder doesn't support new way of calculating pts (or we're
// being called before it has decoded anything with known timestamp).
// Use the old method of audio pts calculation: take the timestamp
// of last packet with known pts the decoder has read data from,
// and add amount of bytes read after the beginning of that packet
// divided by input bps. This will be inaccurate if the input/output
// ratio is not constant for every audio packet or if it is constant
// but not accurately known in sh_audio->i_bps.
a_pts = d_audio->pts;
// ds_tell_pts returns gets bytes read after last timestamp from
// demuxing layer, decoder might use sh_audio->a_in_buffer for bytes
// it has read but not decoded
a_pts += (ds_tell_pts(d_audio) - sh_audio->a_in_buffer_len) /
(double)sh_audio->i_bps;
}
// Now a_pts hopefully holds the pts for end of audio from decoder.
// Substract data in buffers between decoder and audio out.
// Decoded but not filtered
a_pts -= sh_audio->a_buffer_len / (double)sh_audio->o_bps;
// Data that was ready for ao but was buffered because ao didn't fully
// accept everything to internal buffers yet
a_pts -= sh_audio->a_out_buffer_len * playback_speed / (double)ao_data.bps;
return a_pts;
}
// Return pts value corresponding to currently playing audio.
static double playing_audio_pts(sh_audio_t *sh_audio, demux_stream_t *d_audio,
ao_functions_t *audio_out)
{
return written_audio_pts(sh_audio, d_audio) - playback_speed *
audio_out->get_delay();
}
int main(int argc,char* argv[]){
@ -3539,7 +3591,6 @@ int dropped_frames=0; // how many frames dropped since last non-dropped frame
int too_slow_frame_cnt=0;
int too_fast_frame_cnt=0;
// for auto-quality:
float AV_delay=0; // average of A-V timestamp differences
double vdecode_time;
unsigned int lastframeout_ts=0;
/*float time_frame_corr_avg=0;*/ /* unused */
@ -3678,7 +3729,7 @@ while(sh_audio){
if(!sh_video) {
// handle audio-only case:
if(!quiet) {
float a_pos = sh_audio->delay - audio_out->get_delay() * playback_speed;
double a_pos = playing_audio_pts(sh_audio, d_audio, audio_out);
print_status(a_pos, 0, 0);
}
if(d_audio->eof && sh_audio->a_in_buffer_len <= 0 && sh_audio->a_buffer_len <= 0) eof = PT_NEXT_ENTRY;
@ -3923,13 +3974,9 @@ if(time_frame>0.001 && !(vo_flags&256)){
current_module="av_sync";
if(sh_audio){
double a_pts=0;
double v_pts=0;
double a_pts, v_pts;
// unplayed bytes in our and soundcard/dma buffer:
float delay=playback_speed*audio_out->get_delay()+(float)sh_audio->a_buffer_len/(float)sh_audio->o_bps;
if (autosync){
if (autosync)
/*
* If autosync is enabled, the value for delay must be calculated
* a bit differently. It is set only to the difference between
@ -3941,31 +3988,16 @@ if(time_frame>0.001 && !(vo_flags&256)){
* value here, even a "corrected" one, would be incompatible with
* autosync mode.)
*/
delay=sh_audio->delay;
delay+=(float)sh_audio->a_buffer_len/(float)sh_audio->o_bps;
}
delay += sh_audio->a_out_buffer_len*playback_speed/(float)ao_data.bps;
a_pts = written_audio_pts(sh_audio, d_audio) - sh_audio->delay;
else
a_pts = playing_audio_pts(sh_audio, d_audio, audio_out);
{
// PTS = (last timestamp) + (bytes after last timestamp)/(bytes per sec)
a_pts = sh_audio->pts;
if (a_pts == MP_NOPTS_VALUE) {
// Decoder doesn't support tracking timestamps or demuxer doesn't
// set them properly in individual packets, use old inaccurate method
a_pts=d_audio->pts;
a_pts+=(ds_tell_pts(d_audio)-sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps;
}
else
a_pts += sh_audio->pts_bytes / (float)sh_audio->o_bps;
}
v_pts=sh_video ? sh_video->pts : d_video->pts;
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);
{
static int drop_message=0;
float x;
AV_delay=(a_pts-delay-audio_delay)-v_pts;
double AV_delay = a_pts - audio_delay - v_pts;
double x;
if(AV_delay>0.5 && drop_frame_cnt>50 && drop_message==0){
++drop_message;
mp_msg(MSGT_AVSYNC,MSGL_WARN,MSGTR_SystemTooSlow);
@ -3985,7 +4017,7 @@ if(time_frame>0.001 && !(vo_flags&256)){
max_pts_correction=sh_video->frametime*0.10; // +-10% of time
if(!frame_time_remaining){ sh_audio->delay+=x; c_total+=x;} // correction
if(!quiet)
print_status(a_pts - audio_delay - delay, AV_delay, c_total);
print_status(a_pts - audio_delay, AV_delay, c_total);
}
} else {
@ -4570,7 +4602,7 @@ if (stream->type==STREAMTYPE_DVDNAV && dvd_nav_still)
pos = sh_video->pts;
else
if (sh_audio && audio_out)
pos = sh_audio->delay - audio_out->get_delay() * playback_speed;
pos = playing_audio_pts(sh_audio, d_audio, audio_out);
mp_msg(MSGT_GLOBAL, MSGL_INFO, "ANS_TIME_POSITION=%.1f\n", pos);
} break;
case MP_CMD_SWITCH_AUDIO : {