struct {
int32_t latency_msec;
int32_t adjust_sec;
- pa_sink *sink;
- pa_source *source;
} loopback_args;
pa_time_event *time_event_bt_sco_close;
};
pa_hashmap_remove_and_free(u->loopback_modules, (const void*)parent_id);
}
-/* Load/Unload module-loopback */
-static void update_loopback_module(struct userdata *u, bool load) {
- char *args = NULL;
- const char *volume_type;
-
- pa_assert(u);
-
- if (load && u->loopback_args.sink && u->loopback_args.source) {
- if (!u->loopback_args.latency_msec)
- u->loopback_args.latency_msec = LOOPBACK_DEFAULT_LATENCY_MSEC;
- if (!u->loopback_args.adjust_sec)
- u->loopback_args.adjust_sec = LOOPBACK_DEFAULT_ADJUST_SEC;
-
- volume_type = pa_stream_manager_get_volume_type(u->stream_manager, STREAM_SINK_INPUT, STREAM_ROLE_LOOPBACK);
- args = pa_sprintf_malloc("sink=%s source=%s latency_msec=%d adjust_time=%d sink_input_properties=%s=%s",
- u->loopback_args.sink->name, u->loopback_args.source->name,
- u->loopback_args.latency_msec, u->loopback_args.adjust_sec,
- PA_PROP_MEDIA_TIZEN_VOLUME_TYPE, volume_type);
- if (u->module_loopback)
- pa_module_unload(u->module_loopback, true);
-
- if (pa_module_load(&u->module_loopback, u->core, MODULE_LOOPBACK, args))
- pa_log_error("failed to load module-loopback with (%s)", args);
- else
- pa_log_info(" -- load module-loopback with (%s)", args);
- pa_xfree(args);
-
- } else if (!load) {
- if (u->module_loopback) {
- pa_module_unload(u->module_loopback, true);
- u->module_loopback = NULL;
- u->loopback_args.sink = NULL;
- u->loopback_args.source = NULL;
- pa_log_info(" -- unload module-loopback");
- }
- } else {
- pa_log_error(" -- failed to update loopback module");
- }
-}
-
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;
else
*(data->proper_source) = pa_tz_device_get_source(device, data->device_role);
}
+ /* Update in/out devices for the loopback module arguments and load the module. */
+ if (pa_safe_streq(data->stream_role, STREAM_ROLE_LOOPBACK)) {
+ if ((data->stream_type == STREAM_SINK_INPUT) && (dm_device_direction & DM_DEVICE_DIRECTION_OUT))
+ update_loopback_module_args(u, data->parent_id, pa_tz_device_get_sink(device, NULL), NULL);
+ else if ((data->stream_type == STREAM_SOURCE_OUTPUT) && (dm_device_direction & DM_DEVICE_DIRECTION_IN))
+ update_loopback_module_args(u, data->parent_id, NULL, pa_tz_device_get_source(device, NULL));
+ load_loopback_module_by_parent_id(u, data->parent_id);
+ }
}
}
}
pa_assert(u);
- if (u->module_loopback) {
- if (stream_type == STREAM_SINK_INPUT && u->loopback_args.sink->use_internal_codec)
- update_loopback_module(u, false);
- else if (stream_type == STREAM_SOURCE_OUTPUT && u->loopback_args.source->use_internal_codec)
- update_loopback_module(u, false);
- }
-
/* update BT SCO: close */
update_bt_sco_state(u, false, true, NULL);
/* update BT SCO: close */
update_bt_sco_state(u, false, false, NULL);
}
- /* Check for in/out devices in case of loopback */
- if (pa_safe_streq(data->stream_role, STREAM_ROLE_LOOPBACK)) {
- if ((data->stream_type == STREAM_SINK_INPUT) && (dm_device_direction & DM_DEVICE_DIRECTION_OUT))
- u->loopback_args.sink = pa_tz_device_get_sink(*device, NULL);
- else if ((data->stream_type == STREAM_SOURCE_OUTPUT) && (dm_device_direction & DM_DEVICE_DIRECTION_IN))
- u->loopback_args.source = pa_tz_device_get_source(*device, NULL);
- }
if (IS_AVAILABLE_DIRECTION(data->stream_type, dm_device_direction)) {
if ((use_internal_codec = pa_tz_device_is_use_internal_codec(*device)))
}
}
}
- if (pa_safe_streq(data->stream_role, STREAM_ROLE_LOOPBACK)) {
- /* load module-loopback */
- if (u->loopback_args.sink && u->loopback_args.source)
- update_loopback_module(u, true);
- }
return PA_HOOK_OK;
}
route_info.role = data->stream_role;
if (IS_AUTO_ROUTE_TYPE_SERIES(data->route_type)) {
- pa_idxset *conn_devices = NULL;
-
- /* unload module-loopback */
- if (u->module_loopback) {
- if (data->stream_type == STREAM_SINK_INPUT && u->loopback_args.sink->use_internal_codec)
- update_loopback_module(u, false);
- else if (data->stream_type == STREAM_SOURCE_OUTPUT && u->loopback_args.source->use_internal_codec)
- update_loopback_module(u, false);
- }
+ pa_idxset *conn_devices = pa_device_manager_get_device_list(u->device_manager);
- /* get current connected devices */
- conn_devices = pa_device_manager_get_device_list(u->device_manager);
if (data->route_type == STREAM_ROUTE_TYPE_AUTO || data->route_type == STREAM_ROUTE_TYPE_AUTO_ALL) {
if ((result = handle_auto_or_auto_all_routing(u, data, &route_info, conn_devices, &device)))
return result;
data->is_connected ? "connected" : "disconnected",
data->stream, data->stream_type, data->stream_role, data->parent_id);
+ if (pa_safe_streq(data->stream_role, STREAM_ROLE_LOOPBACK) && !data->is_connected) {
+ pa_sink_input *i = data->stream_type == STREAM_SINK_INPUT ? (pa_sink_input *)data->stream : NULL;
+ pa_source_output *o = data->stream_type == STREAM_SINK_INPUT ? NULL : (pa_source_output *)data->stream;
+
+ unload_loopback_modules_by_stream_disconnect(u, data->parent_id, i, o);
+ }
+
return PA_HOOK_OK;
}
/* unload combine sink for external devices */
unload_combine_sink_module(u, SINK_NAME_COMBINED_EX, null_sink);
- /* unload loopback module */
- if (u->module_loopback)
- if (u->loopback_args.sink == pa_tz_device_get_sink(conn->device, NULL))
- update_loopback_module(u, false);
- }
- if (device_direction & DM_DEVICE_DIRECTION_IN) {
- /* unload loopback module */
- if (u->module_loopback)
- if (u->loopback_args.source == pa_tz_device_get_source(conn->device, NULL))
- update_loopback_module(u, false);
+ unload_loopback_modules_by_device_disconnect(u, pa_tz_device_get_sink(conn->device, NULL), NULL);
}
+
+ if (device_direction & DM_DEVICE_DIRECTION_IN)
+ unload_loopback_modules_by_device_disconnect(u, NULL, pa_tz_device_get_source(conn->device, NULL));
}
return PA_HOOK_OK;