[PATCH 26/30] Add node-based stream initial routing support to the native protocol

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

 



---
 PROTOCOL                        | 10 ++++++
 src/Makefile.am                 |  1 +
 src/pulse/stream.c              |  3 ++
 src/pulsecore/edge.h            | 27 +++++++++++++++
 src/pulsecore/protocol-native.c | 77 +++++++++++++++++++++++++++++++++++++++++
 5 files changed, 118 insertions(+)
 create mode 100644 src/pulsecore/edge.h

diff --git a/PROTOCOL b/PROTOCOL
index 31307d7..7e7d0f4 100644
--- a/PROTOCOL
+++ b/PROTOCOL
@@ -381,6 +381,16 @@ description must not be NULL or empty.
 GET_NODE_INFO_LIST reply parameters are otherwise the same as with
 GET_NODE_INFO, but the parameter list is repeated for each node.
 
+New fields added to the end of PA_COMMAND_CREATE_PLAYBACK_STREAM and
+PA_COMMAND_CREATE_RECORD_STREAM:
+    uint32_t n_initial_routing_nodes
+    string node_name [repeated n_initial_routing_nodes times]
+
+If n_initial_routing_nodes > 0, then the old device parameters, i.e. index and
+name, should be set to PA_INVALID_INDEX and NULL, respectively, and also the
+direct_on_input field of PA_COMMAND_CREATE_RECORD_STREAM should be set to
+PA_INVALID_INDEX.
+
 #### If you just changed the protocol, read this
 ## module-tunnel depends on the sink/source/sink-input/source-input protocol
 ## internals, so if you changed these, you might have broken module-tunnel.
diff --git a/src/Makefile.am b/src/Makefile.am
index 8e8f987..7498a65 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -875,6 +875,7 @@ libpulsecore_ at PA_MAJORMINOR@_la_SOURCES = \
 		pulsecore/core-scache.c pulsecore/core-scache.h \
 		pulsecore/core-subscribe.c pulsecore/core-subscribe.h \
 		pulsecore/core.c pulsecore/core.h \
+		pulsecore/edge.h \
 		pulsecore/fdsem.c pulsecore/fdsem.h \
 		pulsecore/hook-list.c pulsecore/hook-list.h \
 		pulsecore/ltdl-helper.c pulsecore/ltdl-helper.h \
diff --git a/src/pulse/stream.c b/src/pulse/stream.c
index 5c30866..7d77a0e 100644
--- a/src/pulse/stream.c
+++ b/src/pulse/stream.c
@@ -1373,6 +1373,9 @@ static int create_stream(
         pa_tagstruct_put_boolean(t, flags & (PA_STREAM_PASSTHROUGH));
     }
 
+    if (s->context->version >= 30)
+        pa_tagstruct_putu32(t, 0); /* n_initial_routing_nodes */
+
     pa_pstream_send_tagstruct(s->context->pstream, t);
     pa_pdispatch_register_reply(s->context->pdispatch, tag, DEFAULT_TIMEOUT, pa_create_stream_callback, s, NULL);
 
diff --git a/src/pulsecore/edge.h b/src/pulsecore/edge.h
new file mode 100644
index 0000000..e7f73ea
--- /dev/null
+++ b/src/pulsecore/edge.h
@@ -0,0 +1,27 @@
+#ifndef fooedgehfoo
+#define fooedgehfoo
+
+/***
+  This file is part of PulseAudio.
+
+  Copyright (c) 2014 Intel Corporation
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as published
+  by the Free Software Foundation; either version 2.1 of the License,
+  or (at your option) any later version.
+
+  PulseAudio is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with PulseAudio; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#define PA_MAX_EDGES 1024
+
+#endif
diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c
index ec8cee7..3434d2b 100644
--- a/src/pulsecore/protocol-native.c
+++ b/src/pulsecore/protocol-native.c
@@ -36,6 +36,7 @@
 #include <pulse/xmalloc.h>
 #include <pulse/internal.h>
 
+#include <pulsecore/edge.h>
 #include <pulsecore/native-common.h>
 #include <pulsecore/packet.h>
 #include <pulsecore/client.h>
@@ -2146,6 +2147,41 @@ static void command_create_playback_stream(pa_pdispatch *pd, uint32_t command, u
         }
     }
 
+    if (c->version >= 30) {
+        if (pa_tagstruct_getu32(t, &n_nodes) < 0 || n_nodes > PA_MAX_EDGES) {
+            pa_log_info("Failed to read n_nodes.");
+            protocol_error(c);
+            goto finish;
+        }
+
+        if (n_nodes > 0) {
+            if (sink_index != PA_INVALID_INDEX || sink_name) {
+                pa_log_info("The sink is set, but so are the initial routing nodes. Too confusing.");
+                protocol_error(c);
+                goto finish;
+            }
+
+            nodes = pa_xnew(pa_node *, n_nodes);
+
+            for (i = 0; i < n_nodes; i++) {
+                const char *node_name;
+
+                if (pa_tagstruct_gets(t, &node_name) < 0 || !node_name) {
+                    pa_log_info("Failed to read node_name.");
+                    protocol_error(c);
+                    goto finish;
+                }
+
+                nodes[i] = pa_namereg_get(c->protocol->core, node_name, PA_NAMEREG_NODE);
+                if (!nodes[i]) {
+                    pa_log_info("No such node: %s", node_name);
+                    pa_pstream_send_error(c->pstream, tag, PA_ERR_NOENTITY);
+                    goto finish;
+                }
+            }
+        }
+    }
+
     if (!pa_tagstruct_eof(t)) {
         protocol_error(c);
         goto finish;
@@ -2479,12 +2515,53 @@ static void command_create_record_stream(pa_pdispatch *pd, uint32_t command, uin
         }
     }
 
+    if (c->version >= 30) {
+        if (pa_tagstruct_getu32(t, &n_nodes) || n_nodes > PA_MAX_EDGES) {
+            pa_log_info("Failed to read n_nodes.");
+            protocol_error(c);
+            goto finish;
+        }
+
+        if (n_nodes > 0) {
+            if (source_index != PA_INVALID_INDEX || source_name) {
+                pa_log_info("The source is set, but so are the initial routing nodes. Too confusing.");
+                protocol_error(c);
+                goto finish;
+            }
+
+            nodes = pa_xnew(pa_node *, n_nodes);
+
+            for (i = 0; i < n_nodes; i++) {
+                const char *node_name;
+
+                if (pa_tagstruct_gets(t, &node_name) || !node_name) {
+                    pa_log_info("Failed to read node_name.");
+                    protocol_error(c);
+                    goto finish;
+                }
+
+                nodes[i] = pa_namereg_get(c->protocol->core, node_name, PA_NAMEREG_NODE);
+                if (!nodes[i]) {
+                    pa_log_info("No such node: %s", node_name);
+                    pa_pstream_send_error(c->pstream, tag, PA_ERR_NOENTITY);
+                    goto finish;
+                }
+            }
+        }
+    }
+
     if (!pa_tagstruct_eof(t)) {
         protocol_error(c);
         goto finish;
     }
 
     if (direct_on_input_idx != PA_INVALID_INDEX) {
+        if (n_nodes > 0) {
+            pa_log_info("The initial routing nodes are set, but so is direct_on_input_idx. Too confusing.");
+            pa_pstream_send_error(c->pstream, tag, PA_ERR_INVALID);
+            goto finish;
+        }
+
         if (!(direct_on_input = pa_idxset_get_by_index(c->protocol->core->sink_inputs, direct_on_input_idx))) {
             pa_pstream_send_error(c->pstream, tag, PA_ERR_NOENTITY);
             goto finish;
-- 
1.8.3.1



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

  Powered by Linux