[PATCH] tunnel-new: cork the stream when sink/source gets suspended and uncork it when resumed

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



---
 src/modules/module-tunnel-sink-new.c   | 33 ++++++++++++++++++++++++++++++
 src/modules/module-tunnel-source-new.c | 37 ++++++++++++++++++++++++++++++++--
 2 files changed, 68 insertions(+), 2 deletions(-)

diff --git a/src/modules/module-tunnel-sink-new.c b/src/modules/module-tunnel-sink-new.c
index d9fe0e6..2d732bf 100644
--- a/src/modules/module-tunnel-sink-new.c
+++ b/src/modules/module-tunnel-sink-new.c
@@ -102,6 +102,17 @@ static const char* const valid_modargs[] = {
     NULL,
 };
 
+static void cork_stream(struct userdata *u, int cork) {
+    pa_operation *operation;
+
+    pa_assert(u);
+    pa_assert(u->stream);
+
+    if ((operation = pa_stream_cork(u->stream, cork, NULL, NULL))) {
+        pa_operation_unref(operation);
+    }
+}
+
 static void reset_bufferattr(pa_buffer_attr *bufferattr) {
     pa_assert(bufferattr);
     bufferattr->fragsize = (uint32_t) -1;
@@ -244,6 +255,9 @@ static void stream_state_cb(pa_stream *stream, void *userdata) {
             pa_log_debug("Stream terminated.");
             break;
         case PA_STREAM_READY:
+            if (PA_SINK_IS_OPENED(u->sink->thread_info.state))
+                cork_stream(u, 0);
+
             /* Only call our requested_latency_cb when requested_latency
              * changed between PA_STREAM_CREATING -> PA_STREAM_READY, because
              * we don't want to override the initial tlength set by the server
@@ -413,6 +427,25 @@ static int sink_process_msg_cb(pa_msgobject *o, int code, void *data, int64_t of
             *((pa_usec_t*) data) = remote_latency;
             return 0;
         }
+        case PA_SINK_MESSAGE_SET_STATE:
+            if (!u->stream || !PA_STREAM_IS_GOOD(pa_stream_get_state(u->stream)))
+                break;
+
+            switch ((pa_sink_state_t) PA_PTR_TO_UINT(data)) {
+                case PA_SINK_SUSPENDED: {
+                    cork_stream(u, 1);
+                    break;
+                }
+                case PA_SINK_IDLE:
+                case PA_SINK_RUNNING: {
+                    cork_stream(u, 0);
+                    break;
+                }
+                case PA_SINK_INVALID_STATE:
+                case PA_SINK_INIT:
+                case PA_SINK_UNLINKED:
+                    break;
+            }
     }
     return pa_sink_process_msg(o, code, data, offset, chunk);
 }
diff --git a/src/modules/module-tunnel-source-new.c b/src/modules/module-tunnel-source-new.c
index d2e2d6c..317007f 100644
--- a/src/modules/module-tunnel-source-new.c
+++ b/src/modules/module-tunnel-source-new.c
@@ -101,6 +101,17 @@ static const char* const valid_modargs[] = {
     NULL,
 };
 
+static void cork_stream(struct userdata *u, int cork) {
+    pa_operation *operation;
+
+    pa_assert(u);
+    pa_assert(u->stream);
+
+    if ((operation = pa_stream_cork(u->stream, cork, NULL, NULL))) {
+        pa_operation_unref(operation);
+    }
+}
+
 static void reset_bufferattr(pa_buffer_attr *bufferattr) {
     pa_assert(bufferattr);
     bufferattr->fragsize = (uint32_t) -1;
@@ -262,6 +273,9 @@ static void stream_state_cb(pa_stream *stream, void *userdata) {
             pa_log_debug("Stream terminated.");
             break;
         case PA_STREAM_READY:
+            if (PA_SOURCE_IS_OPENED(u->source->thread_info.state))
+                cork_stream(u, 0);
+
             /* Only call our requested_latency_cb when requested_latency
              * changed between PA_STREAM_CREATING -> PA_STREAM_READY, because
              * we don't want to override the initial fragsize set by the server
@@ -325,7 +339,7 @@ static void context_state_cb(pa_context *c, void *userdata) {
             if (pa_stream_connect_record(u->stream,
                                          u->remote_source_name,
                                          &bufferattr,
-                                         PA_STREAM_INTERPOLATE_TIMING|PA_STREAM_DONT_MOVE|PA_STREAM_AUTO_TIMING_UPDATE) < 0) {
+                                         PA_STREAM_INTERPOLATE_TIMING|PA_STREAM_DONT_MOVE|PA_STREAM_AUTO_TIMING_UPDATE|PA_STREAM_START_CORKED) < 0) {
                 pa_log_debug("Could not create stream: %s", pa_strerror(pa_context_errno(u->context)));
                 u->thread_mainloop_api->quit(u->thread_mainloop_api, TUNNEL_THREAD_FAILED_MAINLOOP);
             }
@@ -417,7 +431,26 @@ static int source_process_msg_cb(pa_msgobject *o, int code, void *data, int64_t
 
             return 0;
         }
-    }
+        case PA_SOURCE_MESSAGE_SET_STATE:
+            if (!u->stream || !PA_STREAM_IS_GOOD(pa_stream_get_state(u->stream)))
+                break;
+
+            switch ((pa_source_state_t) PA_PTR_TO_UINT(data)) {
+                case PA_SOURCE_SUSPENDED: {
+                    cork_stream(u, 1);
+                    break;
+                }
+                case PA_SOURCE_IDLE:
+                case PA_SOURCE_RUNNING: {
+                    cork_stream(u, 0);
+                    break;
+                }
+                case PA_SOURCE_INVALID_STATE:
+                case PA_SOURCE_INIT:
+                case PA_SOURCE_UNLINKED:
+                    break;
+            }
+        }
     return pa_source_process_msg(o, code, data, offset, chunk);
 }
 
-- 
1.8.4



[Index of Archives]     [Linux Audio Users]     [AMD Graphics]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux