pa_device_init_icon(data->proplist, false);
pa_device_init_intended_roles(data->proplist);
+ if (!data->active_port) {
+ pa_device_port *p = pa_device_port_find_best(data->ports);
+ if (p)
+ pa_source_new_data_set_port(data, p->name);
+ }
+
if (pa_hook_fire(&core->hooks[PA_CORE_HOOK_SOURCE_FIXATE], data) < 0) {
pa_xfree(s);
pa_namereg_unregister(core, name);
if ((s->active_port = pa_hashmap_get(s->ports, data->active_port)))
s->save_port = data->save_port;
- if (!s->active_port) {
- void *state;
- pa_device_port *p;
-
- PA_HASHMAP_FOREACH(p, s->ports, state) {
- if (p->available == PA_AVAILABLE_NO)
- continue;
-
- if (!s->active_port || p->priority > s->active_port->priority)
- s->active_port = p;
- }
-
- if (!s->active_port) {
- PA_HASHMAP_FOREACH(p, s->ports, state)
- if (!s->active_port || p->priority > s->active_port->priority)
- s->active_port = p;
- }
- }
+ /* Hopefully the active port has already been assigned in the previous call
+ to pa_device_port_find_best, but better safe than sorry */
+ if (!s->active_port)
+ s->active_port = pa_device_port_find_best(s->ports);
if (s->active_port)
s->latency_offset = s->active_port->latency_offset;
pa_cvolume_remap(&volume, channel_map, &s->channel_map);
reference_volume_changed = !pa_cvolume_equal(&volume, &s->reference_volume);
- s->reference_volume = volume;
+ pa_source_set_reference_volume_direct(s, &volume);
s->save_volume = (!reference_volume_changed && s->save_volume) || save;
- if (reference_volume_changed)
- pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
- else if (!(s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER))
+ if (!reference_volume_changed && !(s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER))
/* If the root source's volume doesn't change, then there can't be any
* changes in the other source in the source tree either.
*
o->thread_info.direct_on_input = NULL;
}
- if (pa_hashmap_remove(s->thread_info.outputs, PA_UINT32_TO_PTR(o->index)))
- pa_source_output_unref(o);
-
+ pa_hashmap_remove_and_free(s->thread_info.outputs, PA_UINT32_TO_PTR(o->index));
pa_source_invalidate_requested_latency(s, true);
/* In flat volume mode we need to update the volume as
return out_formats;
}
+
+/* Called from the main thread. */
+void pa_source_set_reference_volume_direct(pa_source *s, const pa_cvolume *volume) {
+ pa_cvolume old_volume;
+ char old_volume_str[PA_CVOLUME_SNPRINT_VERBOSE_MAX];
+ char new_volume_str[PA_CVOLUME_SNPRINT_VERBOSE_MAX];
+
+ pa_assert(s);
+ pa_assert(volume);
+
+ old_volume = s->reference_volume;
+
+ if (pa_cvolume_equal(volume, &old_volume))
+ return;
+
+ s->reference_volume = *volume;
+ pa_log_debug("The reference volume of source %s changed from %s to %s.", s->name,
+ pa_cvolume_snprint_verbose(old_volume_str, sizeof(old_volume_str), &old_volume, &s->channel_map,
+ s->flags & PA_SOURCE_DECIBEL_VOLUME),
+ pa_cvolume_snprint_verbose(new_volume_str, sizeof(new_volume_str), volume, &s->channel_map,
+ s->flags & PA_SOURCE_DECIBEL_VOLUME));
+
+ pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
+}