ao_alsa: don't silence legitimate underrun if final chunk underruns

It turns out that case 2) mentioned in the previous commit happened
quite often when playback ended normally.

There is probably a legitimate underrun with normal buffer sizes (100
ms, 4 fragments, gapless audio in "weak" mode). This is a result of the
player waiting for video to end, and/or the time needed to kill the
video window. The former case means that it depends on your test case
whether it happens (a file where video ends slightly before audio is
less likely to trigger it).

This in turn is due to how gapless playback works. Achieving not having
a "gap" requires queuing the audio of the next file without playing a
partial chunk (as AOPLAY_FINAL_CHUNK would do). The partial chunk is
then played as part of the first chunk played from the next file. But if
it detects "later" that there is no next file, it still needs to get rid
of the last fragment with AOPLAY_FINAL_CHUNK. At this point it's too
late, and an underrun may have actually happened. The way the player
uninits and reinits the entire playback engine for the next file in a
"serial" manner means it cannot know in advance whether this works.

This is the reason why the idiot who added the underrun exception for
the last chunk in play() was wrong (I wrote that btw., before you accuse
me of being rude). Yes, it's a real underrun, and you could probably
hear it.
This commit is contained in:
wm4 2019-10-06 20:13:28 +02:00
parent 81e51a15f7
commit e38b0b245e
1 changed files with 1 additions and 4 deletions

View File

@ -1121,10 +1121,7 @@ static int play(struct ao *ao, void **data, int samples, int flags)
if (res == -ESTRPIPE) { /* suspend */
resume_device(ao);
} else if (res == -EPIPE) {
// For some reason, writing a smaller fragment at the end
// immediately underruns.
if (!(flags & AOPLAY_FINAL_CHUNK))
MP_WARN(ao, "Device underrun detected.\n");
MP_WARN(ao, "Device underrun detected.\n");
} else {
MP_ERR(ao, "Write error: %s\n", snd_strerror(res));
}