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).
This commit is contained in:
Uoti Urpala 2011-04-22 07:07:54 +03:00
parent d33877acb6
commit c2067cabaf
1 changed files with 16 additions and 7 deletions

View File

@ -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 {