From c2067cabafa272dc96d51a3969c024d09fb7a78d Mon Sep 17 00:00:00 2001 From: Uoti Urpala Date: Fri, 22 Apr 2011 07:07:54 +0300 Subject: [PATCH] audio: fill small AO buffers more often in audio-only case Commit cbeed30ae8 ("core: wake up a bit less often for audio-only files") increased the sleep time between audio buffer fills. This turned out to cause problems on some machines where available audio buffer sizes are extremely limited (example cases included 85 ms for stereo and less for multichannel audio). Change the code to check the amount of buffered audio and shorten sleep times accordingly if needed. Such short buffers violate some assumptions made by video timing code, so they may still cause visible problems in some cases. At least on some machines using ALSA the problem seems to be caused by bad configuration defaults (small buffer memory limit which can be increased). --- mplayer.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/mplayer.c b/mplayer.c index a9220797e0..d4149395cf 100644 --- a/mplayer.c +++ b/mplayer.c @@ -3353,11 +3353,14 @@ static void run_playloop(struct MPContext *mpctx) pause_player(mpctx); } // handle audio-only case: - double a_pos = 0; + double a_pos = 0, a_buf = 0; // sh_audio can be NULL due to video stream switching // TODO: handle this better - if (mpctx->sh_audio) - a_pos = playing_audio_pts(mpctx); + if (mpctx->sh_audio) { + a_buf = ao_get_delay(mpctx->ao); + a_pos = written_audio_pts(mpctx) - mpctx->opts.playback_speed * + a_buf; + } print_status(mpctx, a_pos, false); @@ -3369,18 +3372,24 @@ static void run_playloop(struct MPContext *mpctx) && mpctx->timeline_part + 1 < mpctx->num_timeline_parts && mpctx->sh_audio) { struct timeline_part *p = mpctx->timeline + mpctx->timeline_part; - double delay = ao_get_delay(mpctx->ao); if (!opts->gapless_audio && p->source != (p+1)->source - && delay > 0.05) { + && a_buf > 0.05) { mpctx->stop_play = KEEP_PLAYING; - mp_input_get_cmd(mpctx->input, (delay-.05) * 1000, true); + mp_input_get_cmd(mpctx->input, (a_buf-.05) * 1000, true); } else { seek(mpctx, (struct seek_params){ .type = MPSEEK_ABSOLUTE, .amount = (p+1)->start }, true); } } else if (!mpctx->stop_play) { - int sleep_time = full_audio_buffers || !mpctx->sh_audio ? 100 : 20; + int sleep_time = 100; + if (mpctx->sh_audio) { + if (full_audio_buffers) + sleep_time = FFMAX(20, a_buf * 1000 - 50); + else + sleep_time = 20; + sleep_time = FFMIN(sleep_time, 100); + } mp_input_get_cmd(mpctx->input, sleep_time, true); } } else { -- 2.11.4.GIT