[PATCH v3 1/2] loopback: Enable routing on loopback streams

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

 



At module-loopback load, if no sink is given, the default sink is used. If the
stream has a media.role property, the property cannot be used because a the
source or sink is forced to default. Both module-intended-roles and
module-device-manager are affected. The same apply to sources.

With this patch, if sink or source is missing, routing modules can be used.
---
 src/modules/module-loopback.c |   39 +++++++++++++++++++++++++++------------
 1 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/src/modules/module-loopback.c b/src/modules/module-loopback.c
index 0d65682..1fdf273 100644
--- a/src/modules/module-loopback.c
+++ b/src/modules/module-loopback.c
@@ -645,10 +645,10 @@ static pa_bool_t sink_input_may_move_to_cb(pa_sink_input *i, pa_sink *dest) {
 int pa__init(pa_module *m) {
     pa_modargs *ma = NULL;
     struct userdata *u;
-    pa_sink *sink;
+    pa_sink *sink = NULL;
     pa_sink_input_new_data sink_input_data;
     pa_bool_t sink_dont_move;
-    pa_source *source;
+    pa_source *source = NULL;
     pa_source_output_new_data source_output_data;
     pa_bool_t source_dont_move;
     uint32_t latency_msec;
@@ -666,12 +666,14 @@ int pa__init(pa_module *m) {
         goto fail;
     }
 
-    if (!(source = pa_namereg_get(m->core, pa_modargs_get_value(ma, "source", NULL), PA_NAMEREG_SOURCE))) {
+    n = pa_modargs_get_value(ma, "source", NULL);
+    if (n && !(source = pa_namereg_get(m->core, n, PA_NAMEREG_SOURCE))) {
         pa_log("No such source.");
         goto fail;
     }
 
-    if (!(sink = pa_namereg_get(m->core, pa_modargs_get_value(ma, "sink", NULL), PA_NAMEREG_SINK))) {
+    n = pa_modargs_get_value(ma, "sink", NULL);
+    if (n && !(sink = pa_namereg_get(m->core, n, PA_NAMEREG_SINK))) {
         pa_log("No such sink.");
         goto fail;
     }
@@ -681,8 +683,18 @@ int pa__init(pa_module *m) {
         goto fail;
     }
 
-    ss = sink->sample_spec;
-    map = sink->channel_map;
+    if (!sink && !source)
+        sink = pa_namereg_get_default_sink(m->core);
+
+    if (sink) {
+        ss = sink->sample_spec;
+        map = sink->channel_map;
+    } else if (source) {
+        ss = source->sample_spec;
+        map = source->channel_map;
+    } else
+        goto fail;
+
     if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) {
         pa_log("Invalid sample format specification or channel map");
         goto fail;
@@ -713,7 +725,9 @@ int pa__init(pa_module *m) {
     pa_sink_input_new_data_init(&sink_input_data);
     sink_input_data.driver = __FILE__;
     sink_input_data.module = m;
-    pa_sink_input_new_data_set_sink(&sink_input_data, sink, FALSE);
+
+    if(sink)
+        pa_sink_input_new_data_set_sink(&sink_input_data, sink, FALSE);
 
     if (pa_modargs_get_proplist(ma, "sink_input_properties", sink_input_data.proplist, PA_UPDATE_REPLACE) < 0) {
         pa_log("Failed to parse the sink_input_properties value.");
@@ -723,12 +737,12 @@ int pa__init(pa_module *m) {
 
     if (!pa_proplist_contains(sink_input_data.proplist, PA_PROP_MEDIA_NAME))
         pa_proplist_setf(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "Loopback from %s",
-                         pa_strnull(pa_proplist_gets(source->proplist, PA_PROP_DEVICE_DESCRIPTION)));
+                         source ? pa_strnull(pa_proplist_gets(source->proplist, PA_PROP_DEVICE_DESCRIPTION)) : "unspecified source");
 
     if (!pa_proplist_contains(sink_input_data.proplist, PA_PROP_MEDIA_ROLE))
         pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "abstract");
 
-    if (!pa_proplist_contains(sink_input_data.proplist, PA_PROP_MEDIA_ICON_NAME)
+    if (source && !pa_proplist_contains(sink_input_data.proplist, PA_PROP_MEDIA_ICON_NAME)
             && (n = pa_proplist_gets(source->proplist, PA_PROP_DEVICE_ICON_NAME)))
         pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ICON_NAME, n);
 
@@ -768,7 +782,8 @@ int pa__init(pa_module *m) {
     pa_source_output_new_data_init(&source_output_data);
     source_output_data.driver = __FILE__;
     source_output_data.module = m;
-    pa_source_output_new_data_set_source(&source_output_data, source, FALSE);
+    if (source)
+        pa_source_output_new_data_set_source(&source_output_data, source, FALSE);
 
     if (pa_modargs_get_proplist(ma, "source_output_properties", source_output_data.proplist, PA_UPDATE_REPLACE) < 0) {
         pa_log("Failed to parse the source_output_properties value.");
@@ -778,12 +793,12 @@ int pa__init(pa_module *m) {
 
     if (!pa_proplist_contains(source_output_data.proplist, PA_PROP_MEDIA_NAME))
         pa_proplist_setf(source_output_data.proplist, PA_PROP_MEDIA_NAME, "Loopback to %s",
-                         pa_strnull(pa_proplist_gets(sink->proplist, PA_PROP_DEVICE_DESCRIPTION)));
+                         sink ? pa_strnull(pa_proplist_gets(sink->proplist, PA_PROP_DEVICE_DESCRIPTION)) : "unspecified sink");
 
     if (!pa_proplist_contains(source_output_data.proplist, PA_PROP_MEDIA_ROLE))
         pa_proplist_sets(source_output_data.proplist, PA_PROP_MEDIA_ROLE, "abstract");
 
-    if (!pa_proplist_contains(source_output_data.proplist, PA_PROP_MEDIA_ICON_NAME)
+    if (sink && !pa_proplist_contains(source_output_data.proplist, PA_PROP_MEDIA_ICON_NAME)
             && (n = pa_proplist_gets(sink->proplist, PA_PROP_DEVICE_ICON_NAME)))
         pa_proplist_sets(source_output_data.proplist, PA_PROP_MEDIA_ICON_NAME, n);
 
-- 
1.7.5.4



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

  Powered by Linux