mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-10-29 05:40:23 -04:00
sink, source: Fix reconfiguration of monitor sources
We should only reconfigure monitor sources when the corresponding sink is reconfigured (and when it is, we should unconditionally set it to the requested spec/map of whatever the sink got reconfigured to). The previous logic was incorrect on all 3 counts.
This commit is contained in:
parent
2046afe683
commit
9f3e82ac31
2 changed files with 19 additions and 29 deletions
|
|
@ -1630,13 +1630,15 @@ int pa_sink_reconfigure(pa_sink *s, pa_sample_spec *spec, pa_channel_map *map, b
|
|||
|
||||
if (s->reconfigure(s, &desired_spec, new_map, passthrough) >= 0) {
|
||||
char spec_str[PA_SAMPLE_SPEC_SNPRINT_MAX];
|
||||
char map_str[PA_CHANNEL_MAP_SNPRINT_MAX];
|
||||
|
||||
/* update monitor source as well */
|
||||
if (s->monitor_source && !passthrough)
|
||||
pa_source_reconfigure(s->monitor_source, &desired_spec, new_map, false);
|
||||
pa_source_reconfigure(s->monitor_source, &s->sample_spec, &s->channel_map, false);
|
||||
|
||||
pa_log_info("Reconfigured successfully to: %s",
|
||||
pa_sample_spec_snprint(spec_str, sizeof(spec_str), &desired_spec));
|
||||
pa_log_info("Reconfigured successfully to: %s, %s",
|
||||
pa_sample_spec_snprint(spec_str, sizeof(spec_str), &s->sample_spec),
|
||||
pa_channel_map_snprint(map_str, sizeof(map_str), &s->channel_map));
|
||||
}
|
||||
|
||||
PA_IDXSET_FOREACH(i, s->inputs, idx) {
|
||||
|
|
|
|||
|
|
@ -1105,6 +1105,12 @@ int pa_source_reconfigure(pa_source *s, pa_sample_spec *spec, pa_channel_map *ma
|
|||
}
|
||||
|
||||
if (s->monitor_of) {
|
||||
/* We only allow monitor source reconfiguration to match its sink */
|
||||
if (!pa_sample_spec_equal(spec, &s->monitor_of->sample_spec) ||
|
||||
!pa_channel_map_equal(map, &s->monitor_of->channel_map)) {
|
||||
pa_log_info("Skipping monitor source reconfigruation to different spec from sink.");
|
||||
return -1;
|
||||
}
|
||||
if (PA_SINK_IS_RUNNING(s->monitor_of->state)) {
|
||||
pa_log_info("Cannot update sample spec, this is a monitor source and the sink is running.");
|
||||
return -1;
|
||||
|
|
@ -1195,31 +1201,13 @@ int pa_source_reconfigure(pa_source *s, pa_sample_spec *spec, pa_channel_map *ma
|
|||
|
||||
if (s->reconfigure)
|
||||
ret = s->reconfigure(s, &desired_spec, new_map, passthrough);
|
||||
else {
|
||||
/* This is a monitor source. */
|
||||
|
||||
/* XXX: This code is written with non-passthrough streams in mind. I
|
||||
* have no idea whether the behaviour with passthrough streams is
|
||||
* sensible. */
|
||||
if (!passthrough) {
|
||||
pa_sample_spec old_spec = s->sample_spec;
|
||||
else if (s->monitor_of) {
|
||||
/* This is a monitor source, just set the desired spec and map */
|
||||
s->sample_spec = desired_spec;
|
||||
ret = pa_sink_reconfigure(s->monitor_of, &desired_spec, new_map, false);
|
||||
|
||||
if (ret < 0) {
|
||||
/* Changing the sink rate failed, roll back the old rate for
|
||||
* the monitor source. Why did we set the source rate before
|
||||
* calling pa_sink_reconfigure(), you may ask. The reason is
|
||||
* that pa_sink_reconfigure() tries to update the monitor
|
||||
* source rate, but we are already in the process of updating
|
||||
* the monitor source rate, so there's a risk of entering an
|
||||
* infinite loop. Setting the source rate before calling
|
||||
* pa_sink_reconfigure() makes the rate == s->sample_spec.rate
|
||||
* check in the beginning of this function return early, so we
|
||||
* avoid looping. */
|
||||
s->sample_spec = old_spec;
|
||||
}
|
||||
} else
|
||||
s->channel_map = *new_map;
|
||||
ret = 0;
|
||||
} else {
|
||||
ret = -1;
|
||||
goto unsuspend;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue