mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-04 13:29:59 -05:00
sink,source: Handle missing in the shared volume case
This makes sure that when we're traversing the device chain for sources and sinks with shared volume, we handle the case that a sink-input or source-output of one of these might be unlinked (while unloading a module, for example).
This commit is contained in:
parent
fde703be75
commit
cae3235369
6 changed files with 74 additions and 32 deletions
|
|
@ -618,10 +618,9 @@ void pa_sink_put(pa_sink* s) {
|
|||
enable_flat_volume(s, TRUE);
|
||||
|
||||
if (s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER) {
|
||||
pa_sink *root_sink = s->input_to_master->sink;
|
||||
pa_sink *root_sink = pa_sink_get_master(s);
|
||||
|
||||
while (root_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)
|
||||
root_sink = root_sink->input_to_master->sink;
|
||||
pa_assert(root_sink);
|
||||
|
||||
s->reference_volume = root_sink->reference_volume;
|
||||
pa_cvolume_remap(&s->reference_volume, &root_sink->channel_map, &s->channel_map);
|
||||
|
|
@ -1370,10 +1369,27 @@ pa_usec_t pa_sink_get_latency_within_thread(pa_sink *s) {
|
|||
pa_bool_t pa_sink_flat_volume_enabled(pa_sink *s) {
|
||||
pa_sink_assert_ref(s);
|
||||
|
||||
while (s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)
|
||||
s = s->input_to_master->sink;
|
||||
s = pa_sink_get_master(s);
|
||||
|
||||
return (s->flags & PA_SINK_FLAT_VOLUME);
|
||||
if (PA_LIKELY(s))
|
||||
return (s->flags & PA_SINK_FLAT_VOLUME);
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Called from the main thread (and also from the IO thread while the main
|
||||
* thread is waiting). */
|
||||
pa_sink *pa_sink_get_master(pa_sink *s) {
|
||||
pa_sink_assert_ref(s);
|
||||
|
||||
while (s && (s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)) {
|
||||
if (PA_UNLIKELY(!s->input_to_master))
|
||||
return NULL;
|
||||
|
||||
s = s->input_to_master->sink;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Called from main context */
|
||||
|
|
@ -1804,7 +1820,7 @@ void pa_sink_set_volume(
|
|||
pa_bool_t save) {
|
||||
|
||||
pa_cvolume new_reference_volume;
|
||||
pa_sink *root_sink = s;
|
||||
pa_sink *root_sink;
|
||||
|
||||
pa_sink_assert_ref(s);
|
||||
pa_assert_ctl_context();
|
||||
|
|
@ -1822,8 +1838,10 @@ void pa_sink_set_volume(
|
|||
|
||||
/* In case of volume sharing, the volume is set for the root sink first,
|
||||
* from which it's then propagated to the sharing sinks. */
|
||||
while (root_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)
|
||||
root_sink = root_sink->input_to_master->sink;
|
||||
root_sink = pa_sink_get_master(s);
|
||||
|
||||
if (PA_UNLIKELY(!root_sink))
|
||||
return;
|
||||
|
||||
/* As a special exception we accept mono volumes on all sinks --
|
||||
* even on those with more complex channel maps */
|
||||
|
|
@ -2447,12 +2465,11 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse
|
|||
}
|
||||
|
||||
case PA_SINK_MESSAGE_SET_SHARED_VOLUME: {
|
||||
pa_sink *root_sink = s;
|
||||
pa_sink *root_sink = pa_sink_get_master(s);
|
||||
|
||||
while (root_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)
|
||||
root_sink = root_sink->input_to_master->sink;
|
||||
if (PA_LIKELY(root_sink))
|
||||
set_shared_volume_within_thread(root_sink);
|
||||
|
||||
set_shared_volume_within_thread(root_sink);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue