[pulseaudio-discuss] [PATCH 13/17] Create device prototypes before profiles
Tanu Kaskinen
tanu.kaskinen at linux.intel.com
Mon Dec 30 05:04:48 PST 2013
This simplifies profile creation, and the ownership of device
prototypes is clearer.
---
src/modules/alsa/alsa-mixer.c | 18 +++++++++++++++
src/modules/alsa/alsa-mixer.h | 1 +
src/modules/alsa/module-alsa-card.c | 29 ++++++++++++++++++++-----
src/modules/bluetooth/module-bluetooth-device.c | 18 +++++++--------
src/pulsecore/card.c | 25 ++++++---------------
src/pulsecore/card.h | 13 ++++++-----
6 files changed, 64 insertions(+), 40 deletions(-)
diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c
index 14bfd88..1e08ec3 100644
--- a/src/modules/alsa/alsa-mixer.c
+++ b/src/modules/alsa/alsa-mixer.c
@@ -3382,6 +3382,24 @@ pa_alsa_mapping *pa_alsa_mapping_get(pa_alsa_profile_set *ps, const char *name)
return m;
}
+pa_device_prototype *pa_alsa_mapping_create_device_prototype(pa_alsa_mapping *mapping, pa_direction_t direction) {
+ pa_device_prototype *prototype;
+
+ pa_assert(mapping);
+
+ prototype = pa_device_prototype_new(direction);
+
+ if (direction == PA_DIRECTION_OUTPUT) {
+ pa_assert(!mapping->sink_prototype);
+ mapping->sink_prototype = prototype;
+ } else {
+ pa_assert(!mapping->source_prototype);
+ mapping->source_prototype = prototype;
+ }
+
+ return prototype;
+}
+
static pa_alsa_profile *profile_get(pa_alsa_profile_set *ps, const char *name) {
pa_alsa_profile *p;
diff --git a/src/modules/alsa/alsa-mixer.h b/src/modules/alsa/alsa-mixer.h
index 6869261..0a2a4e5 100644
--- a/src/modules/alsa/alsa-mixer.h
+++ b/src/modules/alsa/alsa-mixer.h
@@ -328,6 +328,7 @@ void pa_alsa_mapping_dump(pa_alsa_mapping *m);
void pa_alsa_profile_dump(pa_alsa_profile *p);
void pa_alsa_decibel_fix_dump(pa_alsa_decibel_fix *db_fix);
pa_alsa_mapping *pa_alsa_mapping_get(pa_alsa_profile_set *ps, const char *name);
+pa_device_prototype *pa_alsa_mapping_create_device_prototype(pa_alsa_mapping *mapping, pa_direction_t direction);
pa_alsa_profile_set* pa_alsa_profile_set_new(const char *fname, const pa_channel_map *bonus);
void pa_alsa_profile_set_probe(pa_alsa_profile_set *ps, const char *dev_id, const pa_sample_spec *ss, unsigned default_n_fragments, unsigned default_fragment_size_msec);
diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c
index 4b09c95..c427386 100644
--- a/src/modules/alsa/module-alsa-card.c
+++ b/src/modules/alsa/module-alsa-card.c
@@ -137,6 +137,28 @@ struct profile_data {
pa_alsa_profile *profile;
};
+static void add_device_prototypes(struct userdata *u, pa_card_new_data *data) {
+ pa_alsa_mapping *mapping;
+ void *state;
+
+ pa_assert(u);
+ pa_assert(data);
+
+ PA_HASHMAP_FOREACH(mapping, u->profile_set->mappings, state) {
+ pa_device_prototype *prototype;
+
+ if (mapping->direction == PA_ALSA_DIRECTION_ANY || mapping->direction == PA_ALSA_DIRECTION_OUTPUT) {
+ prototype = pa_alsa_mapping_create_device_prototype(mapping, PA_DIRECTION_OUTPUT);
+ pa_card_new_data_add_device_prototype(data, prototype);
+ }
+
+ if (mapping->direction == PA_ALSA_DIRECTION_ANY || mapping->direction == PA_ALSA_DIRECTION_INPUT) {
+ prototype = pa_alsa_mapping_create_device_prototype(mapping, PA_DIRECTION_INPUT);
+ pa_card_new_data_add_device_prototype(data, prototype);
+ }
+ }
+}
+
static void add_profiles(struct userdata *u, pa_card_new_data *data) {
pa_alsa_profile *ap;
void *state;
@@ -155,9 +177,6 @@ static void add_profiles(struct userdata *u, pa_card_new_data *data) {
if (ap->output_mappings) {
PA_IDXSET_FOREACH(m, ap->output_mappings, idx) {
- if (!m->sink_prototype)
- m->sink_prototype = pa_device_prototype_new(PA_DIRECTION_OUTPUT);
-
pa_hashmap_put(cp->sink_prototypes, m->sink_prototype, m->sink_prototype);
if (u->use_ucm)
@@ -171,9 +190,6 @@ static void add_profiles(struct userdata *u, pa_card_new_data *data) {
if (ap->input_mappings) {
PA_IDXSET_FOREACH(m, ap->input_mappings, idx) {
- if (!m->source_prototype)
- m->source_prototype = pa_device_prototype_new(PA_DIRECTION_INPUT);
-
pa_hashmap_put(cp->source_prototypes, m->source_prototype, m->source_prototype);
if (u->use_ucm)
@@ -712,6 +728,7 @@ int pa__init(pa_module *m) {
pa_reserve_wrapper_set_application_device_name(reserve, description);
pa_alsa_profile_set_create_ports(u->core, u->profile_set, data.ports);
+ add_device_prototypes(u, &data);
add_profiles(u, &data);
if (pa_hashmap_isempty(data.profiles)) {
diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c
index 59acaf8..f44eb2f 100644
--- a/src/modules/bluetooth/module-bluetooth-device.c
+++ b/src/modules/bluetooth/module-bluetooth-device.c
@@ -2203,16 +2203,6 @@ static pa_card_profile *create_card_profile(struct userdata *u, const char *uuid
else if (pa_streq(uuid, HFP_AG_UUID))
profile = PROFILE_HFGW;
- if (profile == PROFILE_A2DP || (!USE_SCO_OVER_PCM(u) && (profile == PROFILE_HSP || profile == PROFILE_HFGW))) {
- if (!u->sink_prototype)
- u->sink_prototype = pa_device_prototype_new(PA_DIRECTION_OUTPUT);
- }
-
- if (profile == PROFILE_A2DP_SOURCE || (!USE_SCO_OVER_PCM(u) && (profile == PROFILE_HSP || profile == PROFILE_HFGW))) {
- if (!u->source_prototype)
- u->source_prototype = pa_device_prototype_new(PA_DIRECTION_INPUT);
- }
-
if (profile == PROFILE_A2DP) {
p = pa_card_profile_new("a2dp", _("High Fidelity Playback (A2DP)"), sizeof(enum profile));
p->priority = 10;
@@ -2326,6 +2316,14 @@ static int add_card(struct userdata *u) {
return -1;
}
+ /* We create prototypes for both directions even if the device only
+ * supports one direction, because it makes the code simpler. Having an
+ * extra prototype does no harm. */
+ u->sink_prototype = pa_device_prototype_new(PA_DIRECTION_OUTPUT);
+ pa_card_new_data_add_device_prototype(&data, u->sink_prototype);
+ u->source_prototype = pa_device_prototype_new(PA_DIRECTION_INPUT);
+ pa_card_new_data_add_device_prototype(&data, u->source_prototype);
+
PA_LLIST_FOREACH(uuid, device->uuids) {
p = create_card_profile(u, uuid->uuid, data.ports);
diff --git a/src/pulsecore/card.c b/src/pulsecore/card.c
index 32e1652..7f57e02 100644
--- a/src/pulsecore/card.c
+++ b/src/pulsecore/card.c
@@ -131,20 +131,18 @@ void pa_card_new_data_set_name(pa_card_new_data *data, const char *name) {
data->name = pa_xstrdup(name);
}
-void pa_card_new_data_add_profile(pa_card_new_data *data, pa_card_profile *profile) {
- pa_device_prototype *prototype;
- void *state;
+void pa_card_new_data_add_device_prototype(pa_card_new_data *data, pa_device_prototype *prototype) {
+ pa_assert(data);
+ pa_assert(prototype);
+
+ pa_hashmap_put(data->device_prototypes, prototype, prototype);
+}
+void pa_card_new_data_add_profile(pa_card_new_data *data, pa_card_profile *profile) {
pa_assert(data);
pa_assert(profile);
pa_assert_se(pa_hashmap_put(data->profiles, profile->name, profile) >= 0);
-
- PA_HASHMAP_FOREACH(prototype, profile->sink_prototypes, state)
- pa_hashmap_put(data->device_prototypes, prototype, prototype);
-
- PA_HASHMAP_FOREACH(prototype, profile->source_prototypes, state)
- pa_hashmap_put(data->device_prototypes, prototype, prototype);
}
void pa_card_new_data_set_profile(pa_card_new_data *data, const char *profile) {
@@ -299,9 +297,6 @@ void pa_card_free(pa_card *c) {
}
void pa_card_add_profile(pa_card *c, pa_card_profile *profile) {
- pa_device_prototype *prototype;
- void *state;
-
pa_assert(c);
pa_assert(profile);
@@ -309,12 +304,6 @@ void pa_card_add_profile(pa_card *c, pa_card_profile *profile) {
pa_assert_se(pa_hashmap_put(c->profiles, profile->name, profile) >= 0);
profile->card = c;
- PA_HASHMAP_FOREACH(prototype, profile->sink_prototypes, state)
- pa_hashmap_put(c->device_prototypes, prototype, prototype);
-
- PA_HASHMAP_FOREACH(prototype, profile->source_prototypes, state)
- pa_hashmap_put(c->device_prototypes, prototype, prototype);
-
pa_subscription_post(c->core, PA_SUBSCRIPTION_EVENT_CARD|PA_SUBSCRIPTION_EVENT_CHANGE, c->index);
pa_hook_fire(&c->core->hooks[PA_CORE_HOOK_CARD_PROFILE_ADDED], profile);
diff --git a/src/pulsecore/card.h b/src/pulsecore/card.h
index ce1cb22..850dfa1 100644
--- a/src/pulsecore/card.h
+++ b/src/pulsecore/card.h
@@ -64,10 +64,6 @@ typedef struct pa_card_profile {
unsigned priority;
pa_available_t available; /* PA_AVAILABLE_UNKNOWN, PA_AVAILABLE_NO or PA_AVAILABLE_YES */
- /* When populating these hashmaps, note that you initially own the device
- * prototype objects that you add, but once you call
- * pa_card_new_data_add_profile(), the prototype ownership moves to
- * pa_card_new_data (and later to pa_card). */
pa_hashmap *sink_prototypes; /* pa_device_prototype -> pa_device_prototype (hashmap-as-a-set) */
pa_hashmap *source_prototypes; /* pa_device_prototype -> pa_device_prototype (hashmap-as-a-set) */
@@ -119,8 +115,6 @@ typedef struct pa_card_new_data {
const char *driver;
pa_module *module;
- /* Don't populate this manually. pa_card_new_data_add_profile() will
- * automatically add the prototypes from the added profile. */
pa_hashmap *device_prototypes; /* pa_device_prototype -> pa_device_prototype (hashmap-as-a-set) */
pa_hashmap *profiles;
@@ -156,7 +150,13 @@ 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);
+
+/* The ownership of the prototype moves to pa_card_new_data. */
+void pa_card_new_data_add_device_prototype(pa_card_new_data *data, pa_device_prototype *prototype);
+
+/* The ownership of the profile moves to pa_card_new_data. */
void pa_card_new_data_add_profile(pa_card_new_data *data, pa_card_profile *profile);
+
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);
@@ -164,6 +164,7 @@ void pa_card_new_data_done(pa_card_new_data *data);
pa_card *pa_card_new(pa_core *c, pa_card_new_data *data);
void pa_card_free(pa_card *c);
+/* The ownership of the profile moves to pa_card. */
void pa_card_add_profile(pa_card *c, pa_card_profile *profile);
int pa_card_set_profile(pa_card *c, pa_card_profile *profile, bool save, bool bypass_router);
--
1.8.3.1
More information about the pulseaudio-discuss
mailing list