diff options
author | David Henningsson <david.henningsson@canonical.com> | 2013-03-01 11:51:54 +0100 |
---|---|---|
committer | David Henningsson <david.henningsson@canonical.com> | 2013-03-20 11:55:42 +0100 |
commit | e87eb85474e0d357d82a9a38097144b607e1ef57 (patch) | |
tree | bb59e3eadbd936480b08238f7b8e0ef3ade44b2d /src/pulsecore/sink.c | |
parent | ada92732f0086035c850e877c791e23a79bf923d (diff) | |
download | pulseaudio-e87eb85474e0d357d82a9a38097144b607e1ef57.tar.gz |
core, alsa: Better drain reporting
Previously, a drain request was acknowledged up to two hw buffers
too late, causing unnecessary delays.
This implements a new chain of events called process_underrun
which triggers exactly when the sink input has finished playing,
so the drain can be acknowledged quicker.
It could later be improved to give better underrun reporting to
clients too.
Tested-by: Dmitri Paduchikh <dpaduchikh@gmail.com>
Signed-off-by: David Henningsson <david.henningsson@canonical.com>
Diffstat (limited to 'src/pulsecore/sink.c')
-rw-r--r-- | src/pulsecore/sink.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 6ebe95637..718d39281 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -915,6 +915,32 @@ void pa_sink_move_all_fail(pa_queue *q) { pa_queue_free(q, NULL); } + /* Called from IO thread context */ +size_t pa_sink_process_input_underruns(pa_sink *s, size_t left_to_play) { + pa_sink_input *i; + void *state = NULL; + size_t result = 0; + + pa_sink_assert_ref(s); + pa_sink_assert_io_context(s); + + PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state) { + size_t uf = i->thread_info.underrun_for_sink; + if (uf == 0) + continue; + if (uf >= left_to_play) { + if (pa_sink_input_process_underrun(i)) + continue; + } + else if (uf > result) + result = uf; + } + + if (result > 0) + pa_log_debug("Found underrun %ld bytes ago (%ld bytes ahead in playback buffer)", (long) result, (long) left_to_play - result); + return left_to_play - result; +} + /* Called from IO thread context */ void pa_sink_process_rewind(pa_sink *s, size_t nbytes) { pa_sink_input *i; |