[pulseaudio-commits] [SCM] PulseAudio Sound Server branch, master, updated. 05400321c0a87ccda505f04e376e1a8c910d6525

Lennart Poettering gitmailer-noreply at 0pointer.de
Thu Jun 26 15:36:56 PDT 2008


This is an automated email from the git hooks/post-receive script. It was
generated because of a push to the "PulseAudio Sound Server" repository.

The master branch has been updated
      from  9f0afb391a0748b2e1e78d5b19f1af48a249a674 (commit)

- Log -----------------------------------------------------------------
0540032... fix underrun detection for prebuf=0 streams
7755f75... use (uint32_t) -1 to signify default buffer_attr values instead of 0, to allow prebuf=0
2b764d4... fix crash when using sync'ed streams
06ab488... cork/uncork before we ask for the rewrite, to make sure the rewrite actually gets trhough
-----------------------------------------------------------------------

Summary of changes:
 src/pulse/stream.c              |   17 ++++++++----
 src/pulsecore/protocol-native.c |   54 +++++++++++++++++++++++++-------------
 src/pulsecore/sink-input.c      |   22 +++++++++++-----
 src/pulsecore/sink.c            |    4 +-
 src/tests/sync-playback.c       |    5 ++-
 src/utils/pacat.c               |    2 +
 6 files changed, 68 insertions(+), 36 deletions(-)

-----------------------------------------------------------------------

commit 06ab488f7338d41b749320f60b86f22dcb848514
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Jun 27 00:28:17 2008 +0200

    cork/uncork before we ask for the rewrite, to make sure the rewrite actually gets trhough

diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
index 4086b85..dedcf95 100644
--- a/src/pulsecore/sink-input.c
+++ b/src/pulsecore/sink-input.c
@@ -1004,6 +1004,7 @@ int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest) {
 
 /* Called from IO thread context */
 void pa_sink_input_set_state_within_thread(pa_sink_input *i, pa_sink_input_state_t state) {
+    pa_bool_t corking, uncorking;
     pa_sink_input_assert_ref(i);
 
     if (state == i->thread_info.state)
@@ -1013,23 +1014,30 @@ void pa_sink_input_set_state_within_thread(pa_sink_input *i, pa_sink_input_state
         !(i->thread_info.state == PA_SINK_INPUT_DRAINED || i->thread_info.state != PA_SINK_INPUT_RUNNING))
         pa_atomic_store(&i->thread_info.drained, 1);
 
-    if (state == PA_SINK_INPUT_CORKED && i->thread_info.state != PA_SINK_INPUT_CORKED) {
+    corking = state == PA_SINK_INPUT_CORKED && i->thread_info.state == PA_SINK_INPUT_RUNNING;
+    uncorking = i->thread_info.state == PA_SINK_INPUT_CORKED && state == PA_SINK_INPUT_RUNNING;
+
+    if (i->state_change)
+        i->state_change(i, state);
+
+    i->thread_info.state = state;
+
+    if (corking) {
+
+        pa_log_debug("Requesting rewind due to corking");
 
         /* This will tell the implementing sink input driver to rewind
          * so that the unplayed already mixed data is not lost */
         pa_sink_input_request_rewind(i, 0, TRUE, TRUE);
 
-    } else if (i->thread_info.state == PA_SINK_INPUT_CORKED && state != PA_SINK_INPUT_CORKED) {
+    } else if (uncorking) {
+
+        pa_log_debug("Requesting rewind due to uncorking");
 
         /* OK, we're being uncorked. Make sure we're not rewound when
          * the hw buffer is remixed and request a remix. */
         pa_sink_input_request_rewind(i, 0, FALSE, TRUE);
     }
-
-    if (i->state_change)
-        i->state_change(i, state);
-
-    i->thread_info.state = state;
 }
 
 /* Called from thread context, except when it is not. */

commit 2b764d429425bfe30879bca2bca0cbe6c83965e0
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Jun 27 00:28:42 2008 +0200

    fix crash when using sync'ed streams

diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
index 0866829..7497103 100644
--- a/src/pulsecore/sink.c
+++ b/src/pulsecore/sink.c
@@ -1054,8 +1054,8 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse
              * we can safely access data outside of thread_info even
              * though it is mutable */
 
-            pa_assert(!i->thread_info.sync_prev);
-            pa_assert(!i->thread_info.sync_next);
+            pa_assert(!i->sync_prev);
+            pa_assert(!i->sync_next);
 
             if (i->thread_info.sync_prev) {
                 i->thread_info.sync_prev->thread_info.sync_next = i->thread_info.sync_prev->sync_next;

commit 7755f759aae60b279b9a18e3856ff89720105914
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Jun 27 00:34:17 2008 +0200

    use (uint32_t) -1 to signify default buffer_attr values instead of 0, to allow prebuf=0

diff --git a/src/pulse/stream.c b/src/pulse/stream.c
index 89838c5..585518f 100644
--- a/src/pulse/stream.c
+++ b/src/pulse/stream.c
@@ -122,7 +122,12 @@ pa_stream *pa_stream_new_with_proplist(
     /* We initialize der target length here, so that if the user
      * passes no explicit buffering metrics the default is similar to
      * what older PA versions provided. */
+
+    s->buffer_attr.maxlength = (uint32_t) -1;
     s->buffer_attr.tlength = pa_usec_to_bytes(250*PA_USEC_PER_MSEC, ss); /* 250ms of buffering */
+    s->buffer_attr.minreq = (uint32_t) -1;
+    s->buffer_attr.prebuf = (uint32_t) -1;
+    s->buffer_attr.fragsize = (uint32_t) -1;
 
     s->device_index = PA_INVALID_INDEX;
     s->device_name = NULL;
@@ -713,20 +718,20 @@ static void automatic_buffer_attr(pa_stream *s, pa_buffer_attr *attr, const pa_s
     /* We choose fairly conservative values here, to not confuse
      * old clients with extremely large playback buffers */
 
-    if (!attr->maxlength <= 0)
+    if (attr->maxlength == (uint32_t) -1)
         attr->maxlength = 4*1024*1024; /* 4MB is the maximum queue length PulseAudio <= 0.9.9 supported. */
 
-    if (!attr->tlength <= 0)
+    if (attr->tlength == (uint32_t) -1)
         attr->tlength = pa_usec_to_bytes(250*PA_USEC_PER_MSEC, ss); /* 250ms of buffering */
 
-    if (!attr->minreq <= 0)
+    if (attr->minreq == (uint32_t) -1)
         attr->minreq = (attr->tlength)/5; /* Ask for more data when there are only 200ms left in the playback buffer */
 
-    if (!attr->prebuf)
+    if (attr->prebuf == (uint32_t) -1)
         attr->prebuf = attr->tlength; /* Start to play only when the playback is fully filled up once */
 
-    if (!attr->fragsize)
-        attr->fragsize  = attr->tlength; /* Pass data to the app only when the buffer is filled up once */
+    if (attr->fragsize == (uint32_t) -1)
+        attr->fragsize = attr->tlength; /* Pass data to the app only when the buffer is filled up once */
 }
 
 void pa_create_stream_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c
index 862b062..2974dc0 100644
--- a/src/pulsecore/protocol-native.c
+++ b/src/pulsecore/protocol-native.c
@@ -474,11 +474,15 @@ static void fix_record_buffer_attr_pre(record_stream *s, pa_bool_t adjust_latenc
     pa_assert(maxlength);
     pa_assert(fragsize);
 
-    if (*maxlength <= 0 || *maxlength > MAX_MEMBLOCKQ_LENGTH)
+    if (*maxlength == (uint32_t) -1 || *maxlength > MAX_MEMBLOCKQ_LENGTH)
         *maxlength = MAX_MEMBLOCKQ_LENGTH;
+    if (*maxlength <= 0)
+        *maxlength = pa_frame_size(&s->source_output->sample_spec);
 
-    if (*fragsize <= 0)
+    if (*fragsize == (uint32_t) -1)
         *fragsize = pa_usec_to_bytes(DEFAULT_FRAGSIZE_MSEC*PA_USEC_PER_MSEC, &s->source_output->sample_spec);
+    if (*fragsize <= 0)
+        *fragsize = pa_frame_size(&s->source_output->sample_spec);
 
     if (adjust_latency) {
         pa_usec_t fragsize_usec;
@@ -729,16 +733,23 @@ static void fix_playback_buffer_attr_pre(playback_stream *s, pa_bool_t adjust_la
     pa_assert(prebuf);
     pa_assert(minreq);
 
-    if (*maxlength <= 0 || *maxlength > MAX_MEMBLOCKQ_LENGTH)
+    frame_size = pa_frame_size(&s->sink_input->sample_spec);
+
+    if (*maxlength == (uint32_t) -1 || *maxlength > MAX_MEMBLOCKQ_LENGTH)
         *maxlength = MAX_MEMBLOCKQ_LENGTH;
-    if (*tlength <= 0)
+    if (*maxlength <= 0)
+        *maxlength = frame_size;
+
+    if (*tlength == (uint32_t) -1)
         *tlength = pa_usec_to_bytes(DEFAULT_TLENGTH_MSEC*PA_USEC_PER_MSEC, &s->sink_input->sample_spec);
-    if (*minreq <= 0)
-        *minreq = pa_usec_to_bytes(DEFAULT_PROCESS_MSEC*PA_USEC_PER_MSEC, &s->sink_input->sample_spec);
+    if (*tlength <= 0)
+        *tlength = frame_size;
 
-    frame_size = pa_frame_size(&s->sink_input->sample_spec);
+    if (*minreq == (uint32_t) -1)
+        *minreq = pa_usec_to_bytes(DEFAULT_PROCESS_MSEC*PA_USEC_PER_MSEC, &s->sink_input->sample_spec);
     if (*minreq <= 0)
         *minreq = frame_size;
+
     if (*tlength < *minreq+frame_size)
         *tlength = *minreq+frame_size;
 
@@ -810,7 +821,7 @@ static void fix_playback_buffer_attr_pre(playback_stream *s, pa_bool_t adjust_la
     if (*tlength <= *minreq)
         *tlength =  *minreq*2 + frame_size;
 
-    if (*prebuf <= 0 || *prebuf > *tlength)
+    if (*prebuf == (uint32_t) -1 || *prebuf > *tlength)
         *prebuf = *tlength;
 }
 
diff --git a/src/tests/sync-playback.c b/src/tests/sync-playback.c
index 7ab3a25..7e36468 100644
--- a/src/tests/sync-playback.c
+++ b/src/tests/sync-playback.c
@@ -54,9 +54,10 @@ static const pa_sample_spec sample_spec = {
 
 static const pa_buffer_attr buffer_attr = {
     .maxlength = SAMPLE_HZ*sizeof(float)*NSTREAMS, /* exactly space for the entire play time */
-    .tlength = 0,
+    .tlength = (uint32_t) -1,
     .prebuf = 0, /* Setting prebuf to 0 guarantees us the the streams will run synchronously, no matter what */
-    .minreq = 0
+    .minreq = (uint32_t) -1,
+    .fragsize = 0
 };
 
 static void nop_free_cb(void *p) {}
diff --git a/src/utils/pacat.c b/src/utils/pacat.c
index ee784a9..78b9cef 100644
--- a/src/utils/pacat.c
+++ b/src/utils/pacat.c
@@ -278,6 +278,8 @@ static void context_state_callback(pa_context *c, void *userdata) {
                 memset(&buffer_attr, 0, sizeof(buffer_attr));
                 buffer_attr.tlength = latency;
                 buffer_attr.minreq = process_time;
+                buffer_attr.maxlength = (uint32_t) -1;
+                buffer_attr.prebuf = (uint32_t) -1;
                 flags |= PA_STREAM_ADJUST_LATENCY;
             }
 

commit 05400321c0a87ccda505f04e376e1a8c910d6525
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Jun 27 00:35:40 2008 +0200

    fix underrun detection for prebuf=0 streams

diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c
index 2974dc0..cd3056d 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);
 

-- 
hooks/post-receive
PulseAudio Sound Server



More information about the pulseaudio-commits mailing list