I intend to write a router module that rescues streams from removed devices when a card profile changes. If a device is part of both the old and new profile, it may or may not get recreated (alsa doesn't recreate such devices, bluetooth does). If it's not recreated, then rescuing is not needed, so it would be good to have this information about the behaviour available for the new router module. --- src/modules/alsa/module-alsa-card.c | 2 ++ src/modules/bluetooth/module-bluetooth-device.c | 2 ++ src/pulsecore/card.c | 8 ++++++++ src/pulsecore/card.h | 9 +++++++++ 4 files changed, 21 insertions(+) diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c index 96e88e5..e6e426e 100644 --- a/src/modules/alsa/module-alsa-card.c +++ b/src/modules/alsa/module-alsa-card.c @@ -740,6 +740,8 @@ int pa__init(pa_module *m) { if ((profile = pa_modargs_get_value(ma, "profile", NULL))) pa_card_new_data_set_profile(&data, profile); + pa_card_new_data_set_recreate_devices_on_profile_switch(&data, false); + u->card = pa_card_new(m->core, &data); pa_card_new_data_done(&data); diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index 5562f6d..e51da4d 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -2327,6 +2327,8 @@ static int add_card(struct userdata *u) { pa_log_warn("Profile '%s' not valid or not supported by device.", default_profile); } + pa_card_new_data_set_recreate_devices_on_profile_switch(&data, true); + u->card = pa_card_new(u->core, &data); pa_card_new_data_done(&data); diff --git a/src/pulsecore/card.c b/src/pulsecore/card.c index e930a43..fb28ff9 100644 --- a/src/pulsecore/card.c +++ b/src/pulsecore/card.c @@ -90,6 +90,7 @@ pa_card_new_data* pa_card_new_data_init(pa_card_new_data *data) { memset(data, 0, sizeof(*data)); data->proplist = pa_proplist_new(); data->profiles = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, (pa_free_cb_t) pa_card_profile_free); + data->recreate_devices_on_profile_switch = true; data->ports = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, (pa_free_cb_t) pa_device_port_unref); return data; } @@ -108,6 +109,12 @@ void pa_card_new_data_set_profile(pa_card_new_data *data, const char *profile) { data->active_profile = pa_xstrdup(profile); } +void pa_card_new_data_set_recreate_devices_on_profile_switch(pa_card_new_data *data, bool recreate) { + pa_assert(data); + + data->recreate_devices_on_profile_switch = recreate; +} + void pa_card_new_data_done(pa_card_new_data *data) { pa_assert(data); @@ -175,6 +182,7 @@ pa_card *pa_card_new(pa_core *core, pa_card_new_data *data) { port->card = c; c->active_profile = NULL; + c->recreate_devices_on_profile_switch = data->recreate_devices_on_profile_switch; c->save_profile = false; if (data->active_profile) diff --git a/src/pulsecore/card.h b/src/pulsecore/card.h index 7d59f59..950fe68 100644 --- a/src/pulsecore/card.h +++ b/src/pulsecore/card.h @@ -73,6 +73,13 @@ struct pa_card { pa_hashmap *profiles; pa_card_profile *active_profile; + /* When switching the profile, it may happen that some of the devices of + * the old and new profile are same. In that case the card implementation + * may optimize the profile switch so that it doesn't recreate those + * devices. If the card implements that optimization, then this flag should + * set to false, otherwise this must be set to true. */ + bool recreate_devices_on_profile_switch; + pa_hashmap *ports; bool save_profile:1; @@ -91,6 +98,7 @@ typedef struct pa_card_new_data { pa_hashmap *profiles; char *active_profile; + bool recreate_devices_on_profile_switch; pa_hashmap *ports; @@ -117,6 +125,7 @@ void pa_card_profile_set_available(pa_card_profile *c, pa_available_t available) pa_card_new_data *pa_card_new_data_init(pa_card_new_data *data); void pa_card_new_data_set_name(pa_card_new_data *data, const char *name); void pa_card_new_data_set_profile(pa_card_new_data *data, const char *profile); +void pa_card_new_data_set_recreate_devices_on_profile_switch(pa_card_new_data *data, bool recreate); void pa_card_new_data_done(pa_card_new_data *data); pa_card *pa_card_new(pa_core *c, pa_card_new_data *data); -- 1.8.3.1