router: Fix for multiplex default routing
authorJaska Uimonen <jaska.uimonen@helsinki.fi>
Wed, 30 May 2012 15:58:28 +0000 (18:58 +0300)
committerJaska Uimonen <jaska.uimonen@helsinki.fi>
Wed, 30 May 2012 15:58:28 +0000 (18:58 +0300)
combine/module-combine-sink.c
combine/userdata.h
murphy/multiplex.c
murphy/multiplex.h
murphy/switch.c

index feb8c3a..281ccb5 100644 (file)
@@ -1004,8 +1004,10 @@ static pa_hook_result_t sink_put_hook_cb(pa_core *c, pa_sink *s, struct userdata
         while (l && !pa_streq(pa_strlist_data(l), s->name))
             l = pa_strlist_next(l);
 
-        if (!l)
+        if (!l) {
+           pa_log_debug("This sink is not previously unlinked, so returning from sink put cb");
             return PA_HOOK_OK;
+       }
 
         u->unlinked_slaves = pa_strlist_remove(u->unlinked_slaves, s->name);
     }
@@ -1052,8 +1054,10 @@ static pa_hook_result_t sink_unlink_hook_cb(pa_core *c, pa_sink *s, struct userd
 
     pa_log_info("Unconfiguring sink: %s", s->name);
 
-    if (!u->automatic)
+    if (!u->automatic && !u->no_reattach) {
         u->unlinked_slaves = pa_strlist_prepend(u->unlinked_slaves, s->name);
+       pa_log_debug("Adding sink %s to the combine modules unlinked slaves list", s->name);
+    }
 
     output_free(o);
 
@@ -1419,6 +1423,11 @@ static int move_slave(struct userdata *u, pa_sink_input *i, pa_sink *s) {
 
     o = find_output(u, i->sink);
 
+    if (o == NULL) {
+       pa_log_debug("Could not find output with sink %s for moving", s->name);
+       return -1;
+    }
+
     if (i->sink == s)
        return 0;
 
index b73f0c4..7460f6f 100644 (file)
@@ -41,6 +41,7 @@ struct userdata {
 
     pa_bool_t automatic;
     pa_bool_t auto_desc;
+    pa_bool_t no_reattach;
 
     pa_strlist *unlinked_slaves;
 
index 4214c42..77ee68f 100644 (file)
@@ -80,6 +80,8 @@ pa_muxnode *pa_multiplex_create(pa_multiplex   *multiplex,
     pa_assert_se((u = module->userdata));
     pa_assert(u->sink);
 
+    u->no_reattach = TRUE;
+
     mux = pa_xnew0(pa_muxnode, 1);
     mux->module_index = module->index;
     mux->sink_index = u->sink->index;
@@ -136,6 +138,47 @@ pa_muxnode *pa_multiplex_find(pa_multiplex *multiplex, uint32_t sink_index)
 }
 
 
+pa_bool_t pa_multiplex_add_default_route(pa_core    *core,
+                                         pa_muxnode *mux,
+                                         pa_sink    *sink,
+                                         int         type)
+{
+    pa_module *module;
+    pa_sink_input *sinp;
+    struct userdata *u;         /* combine's userdata! */
+
+    pa_assert(core);
+    pa_assert(mux);
+    pa_assert(sink);
+
+    if (!(module = pa_idxset_get_by_index(core->modules, mux->module_index)))
+        pa_log("module %u is gone", mux->module_index);
+    else {
+        pa_assert_se((u = module->userdata));
+
+        if (sink == u->sink) {
+            pa_log("%s: mux %d refuses to make a loopback to itself",
+                   __FILE__, mux->module_index);
+        }
+        else {
+            pa_log_debug("adding default route to mux %u", mux->module_index);
+
+            if (!(sinp = u->add_slave(u, sink))) {
+                pa_log("failed to add new slave to mux %u", mux->module_index);
+                return FALSE;
+            }
+
+            pa_utils_set_stream_routing_properties(sinp->proplist, type, NULL);
+            mux->defstream_index = sinp->index;
+            sinp->flags &= ~(pa_sink_input_flags_t)PA_SINK_INPUT_DONT_MOVE;
+
+            return TRUE;
+        }
+    }
+
+    return FALSE;
+}
+
 pa_bool_t pa_multiplex_remove_default_route(pa_core *core,
                                             pa_muxnode *mux,
                                             pa_bool_t transfer_to_explicit)
index 4b5e1aa..506f17a 100644 (file)
@@ -30,6 +30,7 @@ void pa_multiplex_destroy(pa_multiplex *, pa_core *, pa_muxnode *);
 
 pa_muxnode *pa_multiplex_find(pa_multiplex *, uint32_t);
 
+pa_bool_t pa_multiplex_add_default_route(pa_core *, pa_muxnode *,pa_sink *,int);
 pa_bool_t pa_multiplex_remove_default_route(pa_core *,pa_muxnode *,pa_bool_t);
 pa_bool_t pa_multiplex_change_default_route(pa_core *,pa_muxnode *,pa_sink *);
 
index 52435b5..8f819a6 100644 (file)
@@ -306,24 +306,56 @@ static pa_bool_t setup_default_link_from_stream_to_device(struct userdata *u,
     }
 
     if ((mux = from->mux)) {
+        if (mux->defstream_index == PA_IDXSET_INVALID) {
+            pa_log_debug("currently mux %u has no default route",
+                         mux->module_index);
+            return TRUE;
+        }
+
         sinp = pa_idxset_get_by_index(core->sink_inputs, mux->defstream_index);
 
         if (!sinp) {
-            pa_log_debug("no default sstream found on multiplex %u",
+            /*
+             * we supposed to have a default stream but the sink-input
+             * on the combine side is not existing any more. This can
+             * happen, for instance, if the sink, where it was connected,
+             * died for some reason.
+             */
+            pa_log_debug("supposed to have a default stream on multiplex "
+                         "%u but non was found. Trying to make one",
                          mux->module_index);
-            mux->defstream_index = PA_IDXSET_INVALID;
-            return FALSE;
+            if (pa_multiplex_duplicate_route(core, mux, sinp, sink)) {                    
+                pa_log_debug("the default stream on mux %u would be a "
+                             "duplicate to an explicit route. "
+                             "Removing it ...", mux->module_index);
+                mux->defstream_index = PA_IDXSET_INVALID;
+                return TRUE; /* the routing is a success */
+            }
+
+            if (!pa_multiplex_add_default_route(core, mux,sink, from->type)) {
+                pa_log_debug("failed to add default route on mux %d",
+                             mux->module_index);
+                mux->defstream_index = PA_IDXSET_INVALID;
+                return FALSE;
+            }
         }
         else if (pa_multiplex_duplicate_route(core, mux, sinp, sink)) {
-            pa_log_debug("default stream on mux %u would be a duplicate "
+            pa_log_debug("the default stream on mux %u would be a duplicate "
                          "to an explicit route. Removing it ...",
                          mux->module_index);
             return TRUE;        /* the routing is a success */
         }
             
-        pa_log_debug("multiplex route: sink-input.%d -> (sink.%d - "
-                     "sink-input.%d) -> sink.%d", from->paidx,
-                     mux->sink_index, sinp->index, sink->index);
+        if (sinp) {
+            pa_log_debug("multiplex route: sink-input.%d -> (sink.%d - "
+                         "sink-input.%d) -> sink.%d", from->paidx,
+                         mux->sink_index, sinp->index, sink->index);
+        }
+        else {
+            pa_log_debug("multiplex route: sink-input.%d -> (sink.%d - "
+                         "sink-input) -> sink.%d", from->paidx,
+                         mux->sink_index, sink->index);
+        }
 
         if (!pa_multiplex_change_default_route(core, mux, sink))
             return FALSE;