1
0
mirror of https://github.com/mpv-player/mpv synced 2024-12-12 01:46:16 +00:00

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

View File

@ -3353,11 +3353,14 @@ static void run_playloop(struct MPContext *mpctx)
pause_player(mpctx); pause_player(mpctx);
} }
// handle audio-only case: // 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 // sh_audio can be NULL due to video stream switching
// TODO: handle this better // TODO: handle this better
if (mpctx->sh_audio) if (mpctx->sh_audio) {
a_pos = playing_audio_pts(mpctx); 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); 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->timeline_part + 1 < mpctx->num_timeline_parts
&& mpctx->sh_audio) { && mpctx->sh_audio) {
struct timeline_part *p = mpctx->timeline + mpctx->timeline_part; 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 if (!opts->gapless_audio && p->source != (p+1)->source
&& delay > 0.05) { && a_buf > 0.05) {
mpctx->stop_play = KEEP_PLAYING; 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 { } else {
seek(mpctx, (struct seek_params){ .type = MPSEEK_ABSOLUTE, seek(mpctx, (struct seek_params){ .type = MPSEEK_ABSOLUTE,
.amount = (p+1)->start }, .amount = (p+1)->start },
true); true);
} }
} else if (!mpctx->stop_play) { } 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); mp_input_get_cmd(mpctx->input, sleep_time, true);
} }
} else { } else {