}
}
+static pa_sink *load_combine_sink_module(struct userdata *u, const char *combine_sink_name, pa_sink *sink1, pa_sink *sink2, pa_sink_input *stream)
+{
+ pa_module **combine_sink_module = NULL;
+ pa_sink *sink;
+ pa_sink_input *i;
+
+ pa_assert(u);
+ pa_assert(combine_sink_name);
+ pa_assert(sink1);
+ pa_assert(sink2);
+
+ if (pa_safe_streq(combine_sink_name, SINK_NAME_COMBINED)) {
+ combine_sink_module = &u->module_combine_sink;
+ } else if (pa_safe_streq(combine_sink_name, SINK_NAME_COMBINED_EX)) {
+ combine_sink_module = &u->module_combine_sink_for_ex;
+ } else {
+ pa_log_error("unknown combine_sink_name(%s)", combine_sink_name);
+ return NULL;
+ }
+
+ if (!*combine_sink_module) {
+ char *args = pa_sprintf_malloc("sink_name=%s slaves=\"%s,%s\"", combine_sink_name, sink1->name, sink2->name);
+ pa_log_info("load combine sink module[%s]", args);
+ /* FIXME: load combine module per each stream role. */
+ if (pa_module_load(combine_sink_module, u->core, MODULE_COMBINE_SINK, args))
+ pa_log_error("failed to load module-combine-sink with args(%s)", args);
+ pa_xfree(args);
+ }
+
+ sink = (pa_sink *)pa_namereg_get(u->core, combine_sink_name, PA_NAMEREG_SINK);
+ if (!sink) {
+ pa_log_error("failed to pa_namereg_get() for [%s]", combine_sink_name);
+ return NULL;
+ }
+
+ sink->use_internal_codec = pa_safe_streq(combine_sink_name, SINK_NAME_COMBINED);
+
+ if (stream) {
+ if ((i = pa_idxset_get_by_data(sink1->inputs, stream, NULL)) ||
+ (i = pa_idxset_get_by_data(sink2->inputs, stream, NULL))) {
+ pa_sink_input_move_to(i, sink, false);
+ pa_log_info("*** sink-input(%p,%u) moves to sink(%p,%s)", i, i->index, sink, sink->name);
+ }
+ }
+
+ return sink;
+}
+
static void unload_combine_sink_module(struct userdata *u, const char *combine_sink_name, pa_sink *dst_sink)
{
pa_module **combine_sink_module = NULL;
return;
}
- if (*combine_sink_module) {
- combine_sink = (pa_sink*)pa_namereg_get(u->core, combine_sink_name, PA_NAMEREG_SINK);
- if (!combine_sink)
- pa_log_error("could not get combine_sink(%s)", combine_sink_name);
- else {
- PA_IDXSET_FOREACH(s, combine_sink->inputs, idx) {
- pa_sink_input_move_to(s, dst_sink, false);
- pa_log_info("[UNLOAD COMBINE SINK MODULE] *** sink-input(%p,%u) of (%s) moves to another sink(%p,%s)",
- s, ((pa_sink_input*)s)->index, combine_sink_name, dst_sink, dst_sink->name);
- }
- pa_sink_suspend(combine_sink, true, PA_SUSPEND_USER);
- }
- pa_log_info("unload combine sink module[%s]", combine_sink_name);
- pa_module_unload(*combine_sink_module, true);
- *combine_sink_module = NULL;
- } else
+ if (!*combine_sink_module) {
pa_log_warn("module combine sink(%s) has been already unloaded", combine_sink_name);
+ return;
+ }
+
+ combine_sink = (pa_sink*)pa_namereg_get(u->core, combine_sink_name, PA_NAMEREG_SINK);
+ if (!combine_sink) {
+ pa_log_error("could not get combine_sink(%s)", combine_sink_name);
+ } else {
+ PA_IDXSET_FOREACH(s, combine_sink->inputs, idx) {
+ pa_sink_input_move_to(s, dst_sink, false);
+ pa_log_info("*** sink-input(%p,%u) of (%s) moves to another sink(%p,%s)",
+ s, ((pa_sink_input*)s)->index, combine_sink_name, dst_sink, dst_sink->name);
+ }
+ pa_sink_suspend(combine_sink, true, PA_SUSPEND_USER);
+ }
+
+ pa_log_info("unload combine sink module[%s]", combine_sink_name);
+ pa_module_unload(*combine_sink_module, true);
+ *combine_sink_module = NULL;
}
static bool skip_device(const char *stream_role, const char *device_type)
pa_source *source = NULL;
pa_sink *combine_sink_arg1 = NULL;
pa_sink *combine_sink_arg2 = NULL;
- void *stream = NULL;
pa_assert(u);
pa_assert(data);
} else if (!combine_sink_arg2) {
sink = combine_sink_arg2 = pa_tz_device_get_sink(device, NULL);
if (sink && !pa_safe_streq(sink->name, combine_sink_arg1->name)) {
- uint32_t s_idx = 0;
-
pa_log_info(" -- combine_sink_arg2[%s]", sink->name);
- /* load combine sink */
- if (!u->module_combine_sink_for_ex) {
- char *args = pa_sprintf_malloc("sink_name=%s slaves=\"%s,%s\"",
- SINK_NAME_COMBINED_EX, combine_sink_arg1->name, combine_sink_arg2->name);
- pa_log_info(" -- combined sink is not prepared, now load module[%s]", args);
- if (pa_module_load(&u->module_combine_sink_for_ex, u->core, MODULE_COMBINE_SINK, args))
- pa_log_error("failed to load module-combine-sink with args(%s)", args);
- pa_xfree(args);
- }
- sink = (pa_sink*)pa_namereg_get(u->core, SINK_NAME_COMBINED_EX, PA_NAMEREG_SINK);
- PA_IDXSET_FOREACH(stream, combine_sink_arg1->inputs, s_idx) {
- if (sink && stream == data->stream) {
- pa_sink_input_move_to(stream, sink, false);
- pa_log_info(" -- *** sink-input(%p,%u) moves to sink(%p,%s)", stream, ((pa_sink_input*)stream)->index, sink, sink->name);
- break;
- }
- }
+ sink = load_combine_sink_module(u, SINK_NAME_COMBINED_EX, combine_sink_arg1, combine_sink_arg2, data->stream);
+
} else if (!sink) {
pa_log_warn(" -- could not get combine_sink_arg2");
}
sink = *combine_sink_arg2 = pa_tz_device_get_sink(device, data->device_role);
if (sink && !pa_safe_streq(sink->name, (*combine_sink_arg1)->name)) {
pa_log_info("[ROUTE][AUTO_ALL] combine_sink_arg2[%s]", sink->name);
- /* load combine sink */
- if (!u->module_combine_sink) {
- char *args = pa_sprintf_malloc("sink_name=%s slaves=\"%s,%s\"",
- SINK_NAME_COMBINED, (*combine_sink_arg1)->name, (*combine_sink_arg2)->name);
- pa_log_info("[ROUTE][AUTO_ALL] combined sink is not prepared, now load module[%s]", args);
- if (pa_module_load(&u->module_combine_sink, u->core, MODULE_COMBINE_SINK, args))
- pa_log_error("failed to load module-combine-sink with args(%s)", args);
- pa_xfree(args);
- }
- if ((sink = (pa_sink*)pa_namereg_get(u->core, SINK_NAME_COMBINED, PA_NAMEREG_SINK))) {
- PA_IDXSET_FOREACH(s, (*combine_sink_arg1)->inputs, s_idx) {
- if (s == data->stream) {
- pa_sink_input_move_to(s, sink, false);
- pa_log_info("[ROUTE][AUTO_ALL] *** sink-nput(%p,%u) moves to sink(%p,%s)",
- s, ((pa_sink_input*)s)->index, sink, sink->name);
- }
- }
- }
+ sink = load_combine_sink_module(u, SINK_NAME_COMBINED, *combine_sink_arg1, *combine_sink_arg2, data->stream);
}
} else if (data->stream_type == STREAM_SOURCE_OUTPUT) {