summaryrefslogtreecommitdiffstats
path: root/src/pulsecore
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2008-06-27 00:35:40 +0200
committerLennart Poettering <lennart@poettering.net>2008-06-27 00:35:40 +0200
commit05400321c0a87ccda505f04e376e1a8c910d6525 (patch)
treefb6be2ce1fdb7e2e7cd7d50125fe2aab46dbec90 /src/pulsecore
parent7755f759aae60b279b9a18e3856ff89720105914 (diff)
fix underrun detection for prebuf=0 streams
Diffstat (limited to 'src/pulsecore')
-rw-r--r--src/pulsecore/protocol-native.c27
1 files changed, 16 insertions, 11 deletions
diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c
index 2974dc0e..cd3056d9 100644
--- a/src/pulsecore/protocol-native.c
+++ b/src/pulsecore/protocol-native.c
@@ -100,7 +100,8 @@ typedef struct playback_stream {
pa_sink_input *sink_input;
pa_memblockq *memblockq;
- pa_bool_t drain_request;
+ pa_bool_t is_underrun:1;
+ pa_bool_t drain_request:1;
uint32_t drain_tag;
uint32_t syncid;
@@ -920,6 +921,9 @@ static playback_stream* playback_stream_new(
s->connection = c;
s->syncid = syncid;
s->sink_input = sink_input;
+ s->is_underrun = TRUE;
+ s->drain_request = FALSE;
+ pa_atomic_store(&s->missing, 0);
s->sink_input->parent.process_msg = sink_input_process_msg;
s->sink_input->pop = sink_input_pop_cb;
@@ -953,9 +957,6 @@ static playback_stream* playback_stream_new(
*ss = s->sink_input->sample_spec;
*map = s->sink_input->channel_map;
- pa_atomic_store(&s->missing, 0);
- s->drain_request = FALSE;
-
pa_idxset_put(c->output_streams, s, &s->index);
pa_log_info("Final latency %0.2f ms = %0.2f ms + 2*%0.2f ms + %0.2f ms",
@@ -1297,24 +1298,28 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk
playback_stream_assert_ref(s);
pa_assert(chunk);
- if (pa_memblockq_peek(s->memblockq, chunk) < 0) {
+/* pa_log("%s, pop(): %lu", pa_proplist_gets(i->proplist, PA_PROP_MEDIA_NAME), (unsigned long) pa_memblockq_get_length(s->memblockq)); */
-/* pa_log("UNDERRUN: %lu", (unsigned long) pa_memblockq_get_length(s->memblockq)); */
+ if (pa_memblockq_is_readable(s->memblockq))
+ s->is_underrun = FALSE;
+ else {
+/* pa_log("%s, UNDERRUN: %lu", pa_proplist_gets(i->proplist, PA_PROP_MEDIA_NAME), (unsigned long) pa_memblockq_get_length(s->memblockq)); */
if (s->drain_request && pa_sink_input_safe_to_remove(i)) {
s->drain_request = FALSE;
pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_DRAIN_ACK, PA_UINT_TO_PTR(s->drain_tag), 0, NULL, NULL);
- } else if (i->thread_info.playing_for > 0)
+ } else if (!s->is_underrun)
pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_UNDERFLOW, NULL, 0, NULL, NULL);
-/* pa_log("adding %llu bytes", (unsigned long long) nbytes); */
+ s->is_underrun = TRUE;
request_bytes(s);
-
- return -1;
}
-/* pa_log("NOTUNDERRUN %lu", (unsigned long) chunk->length); */
+ /* This call will not fail with prebuf=0, hence we check for
+ underrun explicitly above */
+ if (pa_memblockq_peek(s->memblockq, chunk) < 0)
+ return -1;
chunk->length = PA_MIN(nbytes, chunk->length);