[pulseaudio-discuss] [PATCH v3 06/11] tunnel-manager: Load tunnel sinks and sources
Tanu Kaskinen
tanu.kaskinen at linux.intel.com
Thu Dec 4 10:44:49 PST 2014
This makes the tunnel manager load tunnel sinks and sources for all
devices in the remote servers, except for monitor sources.
---
src/modules/tunnel-manager/remote-device.c | 93 ++++++++++++++++++++++++++++++
src/modules/tunnel-manager/remote-device.h | 3 +
2 files changed, 96 insertions(+)
diff --git a/src/modules/tunnel-manager/remote-device.c b/src/modules/tunnel-manager/remote-device.c
index a6c9cb1..859800b 100644
--- a/src/modules/tunnel-manager/remote-device.c
+++ b/src/modules/tunnel-manager/remote-device.c
@@ -32,6 +32,9 @@
#include <pulsecore/device-type.h>
#include <pulsecore/namereg.h>
+static void tear_down_tunnel_module(pa_tunnel_manager_remote_device *device);
+static void apply_tunnel_enabled_policy(pa_tunnel_manager_remote_device *device);
+
void pa_tunnel_manager_remote_device_new(pa_tunnel_manager_remote_server *server, pa_device_type_t type, const void *info) {
const char *name = NULL;
uint32_t idx = PA_INVALID_INDEX;
@@ -129,6 +132,68 @@ void pa_tunnel_manager_remote_device_new(pa_tunnel_manager_remote_server *server
pa_log_debug(" Sample spec: %s", pa_sample_spec_snprint(sample_spec_str, sizeof(sample_spec_str), sample_spec));
pa_log_debug(" Channel map: %s", pa_channel_map_snprint(channel_map_str, sizeof(channel_map_str), channel_map));
pa_log_debug(" Is monitor: %s", pa_boolean_to_string(device->is_monitor));
+ pa_log_debug(" Tunnel enabled: %s", pa_boolean_to_string(device->tunnel_enabled));
+
+ apply_tunnel_enabled_policy(device);
+}
+
+static pa_hook_result_t module_unload_cb(void *hook_data, void *call_data, void *userdata) {
+ pa_module *module = call_data;
+ pa_tunnel_manager_remote_device *device = userdata;
+
+ pa_assert(module);
+ pa_assert(device);
+
+ if (module == device->tunnel_module)
+ tear_down_tunnel_module(device);
+
+ return PA_HOOK_OK;
+}
+
+static void set_up_tunnel_module(pa_tunnel_manager_remote_device *device) {
+ const char *module_name = NULL;
+ char *args;
+
+ pa_assert(device);
+ pa_assert(!device->tunnel_module);
+
+ switch (device->type) {
+ case PA_DEVICE_TYPE_SINK:
+ module_name = "module-tunnel-sink-new";
+ break;
+
+ case PA_DEVICE_TYPE_SOURCE:
+ module_name = "module-tunnel-source-new";
+ break;
+ }
+
+ args = pa_sprintf_malloc("server=%s "
+ "%s=%s "
+ "%s_name=tunnel_manager.%s.%s",
+ device->server->address,
+ pa_device_type_to_string(device->type), device->name,
+ pa_device_type_to_string(device->type), device->server->name, device->name);
+ device->tunnel_module = pa_module_load(device->server->manager->core, module_name, args);
+ pa_xfree(args);
+ if (!device->tunnel_module)
+ return;
+
+ device->module_unload_slot = pa_hook_connect(&device->server->manager->core->hooks[PA_CORE_HOOK_MODULE_UNLOAD],
+ PA_HOOK_NORMAL, module_unload_cb, device);
+}
+
+static void tear_down_tunnel_module(pa_tunnel_manager_remote_device *device) {
+ pa_assert(device);
+
+ if (device->module_unload_slot) {
+ pa_hook_slot_free(device->module_unload_slot);
+ device->module_unload_slot = NULL;
+ }
+
+ if (device->tunnel_module) {
+ pa_module_unload(device->tunnel_module->core, device->tunnel_module, true);
+ device->tunnel_module = NULL;
+ }
}
void pa_tunnel_manager_remote_device_free(pa_tunnel_manager_remote_device *device) {
@@ -149,6 +214,8 @@ void pa_tunnel_manager_remote_device_free(pa_tunnel_manager_remote_device *devic
pa_hashmap_remove(device->server->devices, device->name);
pa_hook_fire(&device->hooks[PA_TUNNEL_MANAGER_REMOTE_DEVICE_HOOK_UNLINKED], NULL);
+ tear_down_tunnel_module(device);
+
if (device->get_info_operation) {
pa_operation_cancel(device->get_info_operation);
pa_operation_unref(device->get_info_operation);
@@ -184,6 +251,23 @@ static void set_proplist(pa_tunnel_manager_remote_device *device, pa_proplist *p
pa_hook_fire(&device->hooks[PA_TUNNEL_MANAGER_REMOTE_DEVICE_HOOK_PROPLIST_CHANGED], NULL);
}
+static void set_tunnel_enabled(pa_tunnel_manager_remote_device *device, bool enabled) {
+ pa_assert(device);
+
+ if (enabled == device->tunnel_enabled)
+ return;
+
+ device->tunnel_enabled = enabled;
+
+ pa_log_debug("[%s %s] Tunnel enabled changed from %s to %s.", device->server->name, device->name,
+ pa_boolean_to_string(!enabled), pa_boolean_to_string(enabled));
+
+ if (enabled)
+ set_up_tunnel_module(device);
+ else
+ tear_down_tunnel_module(device);
+}
+
static void get_info_cb(pa_context *context, const void *info, int is_last, void *userdata) {
pa_tunnel_manager_remote_device *device = userdata;
pa_proplist *proplist = NULL;
@@ -253,3 +337,12 @@ void pa_tunnel_manager_remote_device_update(pa_tunnel_manager_remote_device *dev
pa_tunnel_manager_remote_server_set_failed(device->server, true);
}
}
+
+static void apply_tunnel_enabled_policy(pa_tunnel_manager_remote_device *device) {
+ bool enabled;
+
+ pa_assert(device);
+
+ enabled = !device->is_monitor;
+ set_tunnel_enabled(device, enabled);
+}
diff --git a/src/modules/tunnel-manager/remote-device.h b/src/modules/tunnel-manager/remote-device.h
index a766763..b08424c 100644
--- a/src/modules/tunnel-manager/remote-device.h
+++ b/src/modules/tunnel-manager/remote-device.h
@@ -41,9 +41,12 @@ struct pa_tunnel_manager_remote_device {
pa_sample_spec sample_spec;
pa_channel_map channel_map;
bool is_monitor;
+ bool tunnel_enabled;
pa_hook hooks[PA_TUNNEL_MANAGER_REMOTE_DEVICE_HOOK_MAX];
pa_operation *get_info_operation;
+ pa_module *tunnel_module;
+ pa_hook_slot *module_unload_slot;
/* These are a workaround for the problem that the introspection API's info
* callbacks are called multiple times, which means that if the userdata
--
1.9.3
More information about the pulseaudio-discuss
mailing list