path: root/audio/out/push.c
diff options
authorwm4 <wm4@nowhere>2014-05-30 23:56:10 +0200
committerwm4 <wm4@nowhere>2014-05-31 01:26:50 +0200
commit4fa3ffebfe41b0c4ffed6f952cc05a7c275275f4 (patch)
tree740d6a918ee93d91747e3362de24ca1e936aa6b0 /audio/out/push.c
parent9c9f23eee90f1df49098080dee0c10c7b9883ea6 (diff)
audio/out/push: keep some extra buffer
So the device buffer can be refilled quickly. Fixes dropouts in certain cases: if all data is moved from the soft buffer to the audio device buffer, the waiting code thinks it has to enter the mode in which it waits for new data from the decoder. This doesn't work, because the get_space() logic tries to keep the total buffer size down. get_space() will return 0 (or a very low value) because the device buffer is full, and the decoder can't refill the soft buffer. But this means if the AO buffer runs out, the device buffer can't be refilled from the soft buffer. I guess this mess happened because the code is trying to deal with both AOs with proper event handling, and AOs with arbitrary behavior. Unfortunately this increases latency, as the total buffered audio becomes larger. There are other ways to fix this again, but not today. Fixes #818.
Diffstat (limited to 'audio/out/push.c')
1 files changed, 4 insertions, 6 deletions
diff --git a/audio/out/push.c b/audio/out/push.c
index cd7b8dc329..4c789ef3a1 100644
--- a/audio/out/push.c
+++ b/audio/out/push.c
@@ -163,15 +163,13 @@ static int unlocked_get_space(struct ao *ao)
int space = mp_audio_buffer_get_write_available(p->buffer);
if (ao->driver->get_space) {
// The following code attempts to keep the total buffered audio to
- // MIN_BUFFER in order to improve latency.
+ // MIN_BUFFER/2+device_buffer in order to improve latency.
int device_space = ao->driver->get_space(ao);
int device_buffered = ao->device_buffer - device_space;
int soft_buffered = mp_audio_buffer_samples(p->buffer);
- int min_buffer = MIN_BUFFER * ao->samplerate;
- int missing = min_buffer - device_buffered - soft_buffered;
- // But always keep the device's buffer filled as much as we can.
- int device_missing = device_space - soft_buffered;
- missing = MPMAX(missing, device_missing);
+ int min_buffer = MIN_BUFFER / 2 * ao->samplerate + ao->device_buffer;
+ int total_buffer = device_buffered + soft_buffered;
+ int missing = min_buffer - total_buffer;
space = MPMIN(space, missing);
space = MPMAX(0, space);