]> code.delx.au - pulseaudio/commitdiff
make sure to call process_rewind() under all circumstances before we do the next...
authorLennart Poettering <lennart@poettering.net>
Thu, 26 Jun 2008 00:56:00 +0000 (02:56 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 26 Jun 2008 00:56:00 +0000 (02:56 +0200)
src/modules/module-alsa-sink.c
src/modules/module-combine.c
src/modules/module-esound-sink.c
src/modules/module-jack-sink.c
src/modules/module-null-sink.c
src/modules/module-pipe-sink.c
src/modules/module-tunnel.c
src/pulsecore/sink-input.c
src/pulsecore/sink.c
src/pulsecore/sink.h

index 6765775a0b279f55b33eaf0f2471e4b0d9052d88..5818dee2ceaf71e8665f03043cfae83d79109074 100644 (file)
@@ -882,7 +882,7 @@ static void sink_update_requested_latency_cb(pa_sink *s) {
 
     if (u->hwbuf_unused_frames > before) {
         pa_log_debug("Requesting rewind due to latency change.");
-        pa_sink_request_rewind(s, 0);
+        pa_sink_request_rewind(s, (size_t) -1);
     }
 }
 
@@ -967,9 +967,12 @@ static void thread_func(void *userdata) {
             int work_done;
             pa_usec_t sleep_usec;
 
-            if (u->sink->thread_info.rewind_nbytes > 0)
-                if (process_rewind(u) < 0)
-                    goto fail;
+            if (u->sink->thread_info.rewind_requested) {
+                if (u->sink->thread_info.rewind_nbytes <= 0)
+                    pa_sink_process_rewind(u->sink, 0);
+                else if (process_rewind(u) < 0)
+                        goto fail;
+            }
 
             if (u->use_mmap)
                 work_done = mmap_write(u, &sleep_usec);
index 8c155da002196633977ff3c71a1722e63dc56228..7d8e140b3cc6ea802f0b8aba67aaa17fcba39561 100644 (file)
@@ -410,7 +410,6 @@ static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes) {
     struct output *o;
 
     pa_sink_input_assert_ref(i);
-    pa_assert(nbytes > 0);
     pa_assert_se(o = i->userdata);
 
     pa_memblockq_rewind(o->memblockq, nbytes);
index e189febdf062a9021ed13dde1c80cf2a05444cc5..6ca6497825fcc2d3be33f89ec33bb7b9d182c8ec 100644 (file)
@@ -204,6 +204,10 @@ static void thread_func(void *userdata) {
     for (;;) {
         int ret;
 
+        if (PA_SINK_IS_OPENED(u->sink->thread_info.state))
+            if (u->sink->thread_info.rewind_requested)
+                pa_sink_process_rewind(u->sink, 0);
+
         if (u->rtpoll_item) {
             struct pollfd *pollfd;
             pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL);
index c4d47f8e9f641f44d3c309dcbfa65ddde8d13e57..edc543a8520a25d6d3452e7c8c893f4051e75481 100644 (file)
@@ -222,6 +222,10 @@ static void thread_func(void *userdata) {
     for (;;) {
         int ret;
 
+        if (PA_SINK_IS_OPENED(u->sink->thread_info.state))
+            if (u->sink->thread_info.rewind_requested)
+                pa_sink_process_rewind(u->sink, 0);
+
         if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0)
             goto fail;
 
index 604ab1589e82e7f7ae8392a0ed0d9c08a8a036ca..9162960fe7a963ab86e1a3118eedfc4bd115a7b1 100644 (file)
@@ -204,8 +204,12 @@ static void thread_func(void *userdata) {
 
             now = pa_rtclock_usec();
 
-            if (u->sink->thread_info.rewind_nbytes > 0)
-                process_rewind(u, now);
+            if (u->sink->thread_info.rewind_requested) {
+                if (u->sink->thread_info.rewind_nbytes > 0)
+                    process_rewind(u, now);
+                else
+                    pa_sink_process_rewind(u->sink, 0);
+            }
 
             if (u->timestamp <= now)
                 process_render(u, now);
index cd25b890012d664ea233a79832f003f64b4ba7b3..0999935ba677352d83496f78e7f1068ca9fee5dc 100644 (file)
@@ -184,8 +184,12 @@ static void thread_func(void *userdata) {
         /* Render some data and write it to the fifo */
         if (u->sink->thread_info.state == PA_SINK_RUNNING) {
 
-            if (u->sink->thread_info.rewind_nbytes > 0)
-                process_rewind(u);
+            if (u->sink->thread_info.rewind_requested) {
+                if (u->sink->thread_info.rewind_nbytes > 0)
+                    process_rewind(u);
+                else
+                    pa_sink_process_rewind(u->sink, 0);
+            }
 
             if (pollfd->revents) {
                 if (process_render(u) < 0)
index 86f30817d82d9080b1d02cc19fbed699b93d7264..1890646f17418eeade93a90dbe036a9e3a9ac95c 100644 (file)
@@ -605,6 +605,12 @@ static void thread_func(void *userdata) {
     for (;;) {
         int ret;
 
+#ifdef TUNNEL_SINK
+        if (PA_SINK_IS_OPENED(u->sink->thread_info.state))
+            if (u->sink->thread_info.rewind_requested)
+                pa_sink_process_rewind(u->sink, 0);
+#endif
+
         if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0)
             goto fail;
 
index be169709c92cd19e698b7bee0b9a9d3bef67204e..4086b85b24c83fd44321c26a3fb3363570183f74 100644 (file)
@@ -491,12 +491,6 @@ int pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, pa
               i->thread_info.state == PA_SINK_INPUT_CORKED ||
               i->thread_info.state == PA_SINK_INPUT_DRAINED);
 
-    /* If there's still some rewrite request the handle, but the sink
-    didn't do this for us, we do it here. However, since the sink
-    apparently doesn't support rewinding, we pass 0 here. This still
-    allows rewinding through the render buffer. */
-    pa_sink_input_process_rewind(i, 0);
-
     block_size_max_sink_input = i->thread_info.resampler ?
         pa_resampler_max_block_size(i->thread_info.resampler) :
         pa_frame_align(pa_mempool_block_size_max(i->sink->core->mempool), &i->sample_spec);
@@ -633,18 +627,13 @@ void pa_sink_input_drop(pa_sink_input *i, size_t nbytes /* in sink sample spec *
 
 /*     pa_log_debug("dropping %lu", (unsigned long) nbytes); */
 
-    /* If there's still some rewrite request the handle, but the sink
-    didn't do this for us, we do it here. However, since the sink
-    apparently doesn't support rewinding, we pass 0 here. This still
-    allows rewinding through the render buffer. */
-    pa_sink_input_process_rewind(i, 0);
-
     pa_memblockq_drop(i->thread_info.render_memblockq, nbytes);
 }
 
 /* Called from thread context */
 void pa_sink_input_process_rewind(pa_sink_input *i, size_t nbytes /* in sink sample spec */) {
     size_t lbq;
+    pa_bool_t called;
     pa_sink_input_assert_ref(i);
 
     pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
@@ -685,6 +674,7 @@ void pa_sink_input_process_rewind(pa_sink_input *i, size_t nbytes /* in sink sam
             /* Tell the implementor */
             if (i->process_rewind)
                 i->process_rewind(i, amount);
+            called = TRUE;
 
             /* Convert back to to sink domain */
             if (i->thread_info.resampler)
@@ -703,6 +693,10 @@ void pa_sink_input_process_rewind(pa_sink_input *i, size_t nbytes /* in sink sam
         }
     }
 
+    if (!called)
+        if (i->process_rewind)
+            i->process_rewind(i, 0);
+
     i->thread_info.rewrite_nbytes = 0;
     i->thread_info.rewrite_flush = FALSE;
 }
@@ -1143,6 +1137,8 @@ void pa_sink_input_request_rewind(pa_sink_input *i, size_t nbytes  /* in our sam
     pa_sink_input_assert_ref(i);
     pa_assert(i->thread_info.rewrite_nbytes == 0);
 
+/*     pa_log_debug("request rewrite %lu", (unsigned long) nbytes); */
+
     /* We don't take rewind requests while we are corked */
     if (i->thread_info.state == PA_SINK_INPUT_CORKED)
         return;
@@ -1184,6 +1180,9 @@ void pa_sink_input_request_rewind(pa_sink_input *i, size_t nbytes  /* in our sam
 
     if (nbytes > lbq)
         pa_sink_request_rewind(i->sink, nbytes - lbq);
+    else
+        /* This call will make sure process_rewind() is called later */
+        pa_sink_request_rewind(i->sink, 0);
 }
 
 /* Called from main context */
index edb023b2426f7e305a7cf873b950480449073a3c..0866829a218d9a15876dd4d793b19c4db2d68ff1 100644 (file)
@@ -212,6 +212,7 @@ pa_sink* pa_sink_new(
     s->thread_info.soft_muted = FALSE;
     s->thread_info.state = s->state;
     s->thread_info.rewind_nbytes = 0;
+    s->thread_info.rewind_requested = FALSE;
     s->thread_info.max_rewind = 0;
     s->thread_info.max_request = 0;
     s->thread_info.requested_latency_valid = FALSE;
@@ -454,21 +455,20 @@ void pa_sink_process_rewind(pa_sink *s, size_t nbytes) {
     pa_sink_assert_ref(s);
     pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
 
-    /* Make sure the sink code already reset the counter! */
-    pa_assert(s->thread_info.rewind_nbytes <= 0);
-
-    if (nbytes <= 0)
-        return;
+    s->thread_info.rewind_nbytes = 0;
+    s->thread_info.rewind_requested = FALSE;
 
-    pa_log_debug("Processing rewind...");
+    if (nbytes > 0)
+        pa_log_debug("Processing rewind...");
 
     while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL))) {
         pa_sink_input_assert_ref(i);
         pa_sink_input_process_rewind(i, nbytes);
     }
 
-    if (s->monitor_source && PA_SOURCE_IS_OPENED(s->monitor_source->thread_info.state))
-        pa_source_process_rewind(s->monitor_source, nbytes);
+    if (nbytes > 0)
+        if (s->monitor_source && PA_SOURCE_IS_OPENED(s->monitor_source->thread_info.state))
+            pa_source_process_rewind(s->monitor_source, nbytes);
 }
 
 /* Called from IO thread context */
@@ -620,7 +620,8 @@ void pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result) {
 
     pa_sink_ref(s);
 
-    s->thread_info.rewind_nbytes = 0;
+    pa_assert(!s->thread_info.rewind_requested);
+    pa_assert(s->thread_info.rewind_nbytes == 0);
 
     if (length <= 0)
         length = pa_frame_align(MIX_BUFFER_LENGTH, &s->sample_spec);
@@ -696,7 +697,8 @@ void pa_sink_render_into(pa_sink*s, pa_memchunk *target) {
 
     pa_sink_ref(s);
 
-    s->thread_info.rewind_nbytes = 0;
+    pa_assert(!s->thread_info.rewind_requested);
+    pa_assert(s->thread_info.rewind_nbytes == 0);
 
     length = target->length;
     block_size_max = pa_mempool_block_size_max(s->core->mempool);
@@ -774,7 +776,8 @@ void pa_sink_render_into_full(pa_sink *s, pa_memchunk *target) {
 
     pa_sink_ref(s);
 
-    s->thread_info.rewind_nbytes = 0;
+    pa_assert(!s->thread_info.rewind_requested);
+    pa_assert(s->thread_info.rewind_nbytes == 0);
 
     l = target->length;
     d = 0;
@@ -800,7 +803,8 @@ void pa_sink_render_full(pa_sink *s, size_t length, pa_memchunk *result) {
     pa_assert(pa_frame_aligned(length, &s->sample_spec));
     pa_assert(result);
 
-    s->thread_info.rewind_nbytes = 0;
+    pa_assert(!s->thread_info.rewind_requested);
+    pa_assert(s->thread_info.rewind_nbytes == 0);
 
     /*** This needs optimization ***/
 
@@ -1067,7 +1071,7 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse
                 pa_sink_input_unref(i);
 
             pa_sink_invalidate_requested_latency(s);
-            pa_sink_request_rewind(s, 0);
+            pa_sink_request_rewind(s, (size_t) -1);
 
             return 0;
         }
@@ -1112,7 +1116,7 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse
             pa_sink_invalidate_requested_latency(s);
 
             pa_log_debug("Requesting rewind due to started move");
-            pa_sink_request_rewind(s, 0);
+            pa_sink_request_rewind(s, (size_t) -1);
 
             return 0;
         }
@@ -1162,13 +1166,13 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse
         case PA_SINK_MESSAGE_SET_VOLUME:
             s->thread_info.soft_volume = *((pa_cvolume*) userdata);
 
-            pa_sink_request_rewind(s, 0);
+            pa_sink_request_rewind(s, (size_t) -1);
             return 0;
 
         case PA_SINK_MESSAGE_SET_MUTE:
             s->thread_info.soft_muted = PA_PTR_TO_UINT(userdata);
 
-            pa_sink_request_rewind(s, 0);
+            pa_sink_request_rewind(s, (size_t) -1);
             return 0;
 
         case PA_SINK_MESSAGE_GET_VOLUME:
@@ -1309,15 +1313,17 @@ void pa_sink_request_rewind(pa_sink*s, size_t nbytes) {
     pa_sink_assert_ref(s);
     pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
 
-    if (nbytes <= 0)
+    if (nbytes == (size_t) -1)
         nbytes = s->thread_info.max_rewind;
 
     nbytes = PA_MIN(nbytes, s->thread_info.max_rewind);
 
-    if (nbytes <= s->thread_info.rewind_nbytes)
+    if (s->thread_info.rewind_requested &&
+        nbytes <= s->thread_info.rewind_nbytes)
         return;
 
     s->thread_info.rewind_nbytes = nbytes;
+    s->thread_info.rewind_requested = TRUE;
 
     if (s->request_rewind)
         s->request_rewind(s);
index b73944e8eda93865e5cb6ef2bd8f3cfce95c781b..604be26983f162dd1cdad68b20d1503ec350b0de 100644 (file)
@@ -145,6 +145,7 @@ struct pa_sink {
 
         /* Maximum of what clients requested to rewind in this cycle */
         size_t rewind_nbytes;
+        pa_bool_t rewind_requested;
 
         pa_usec_t min_latency; /* we won't go below this latency */
         pa_usec_t max_latency; /* An upper limit for the latencies */