mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2026-03-24 09:06:11 -04:00
fixup! bluetooth: Switch codecs without tearing down sink/source/thread
This commit is contained in:
parent
7fb7ed521e
commit
54ddc54254
1 changed files with 32 additions and 10 deletions
|
|
@ -893,6 +893,13 @@ static int source_set_state_in_io_thread_cb(pa_source *s, pa_source_state_t new_
|
||||||
if (!PA_SOURCE_IS_OPENED(s->thread_info.state))
|
if (!PA_SOURCE_IS_OPENED(s->thread_info.state))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* Ignore the transition if the source is suspended for internal reasons
|
||||||
|
* such as external source-output changes resulting in pa_source_reconfigure.
|
||||||
|
* Logic in our handler decides whether to release the transport or not.
|
||||||
|
*/
|
||||||
|
if (new_suspend_cause & PA_SUSPEND_INTERNAL)
|
||||||
|
break;
|
||||||
|
|
||||||
/* Stop the device if the sink is suspended as well */
|
/* Stop the device if the sink is suspended as well */
|
||||||
if (!u->sink || u->sink->state == PA_SINK_SUSPENDED)
|
if (!u->sink || u->sink->state == PA_SINK_SUSPENDED)
|
||||||
transport_release(u);
|
transport_release(u);
|
||||||
|
|
@ -910,6 +917,9 @@ static int source_set_state_in_io_thread_cb(pa_source *s, pa_source_state_t new_
|
||||||
if (s->thread_info.state != PA_SOURCE_SUSPENDED)
|
if (s->thread_info.state != PA_SOURCE_SUSPENDED)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if (s->suspend_cause & PA_SUSPEND_INTERNAL)
|
||||||
|
break;
|
||||||
|
|
||||||
/* Resume the device if the sink was suspended as well */
|
/* Resume the device if the sink was suspended as well */
|
||||||
if (!u->sink || !PA_SINK_IS_OPENED(u->sink->thread_info.state))
|
if (!u->sink || !PA_SINK_IS_OPENED(u->sink->thread_info.state))
|
||||||
if (!setup_transport_and_stream(u))
|
if (!setup_transport_and_stream(u))
|
||||||
|
|
@ -1167,6 +1177,13 @@ static int sink_set_state_in_io_thread_cb(pa_sink *s, pa_sink_state_t new_state,
|
||||||
if (!PA_SINK_IS_OPENED(s->thread_info.state))
|
if (!PA_SINK_IS_OPENED(s->thread_info.state))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* Ignore the transition if the sink is suspended for internal reasons
|
||||||
|
* such as external sink-input changes resulting in pa_sink_reconfigure.
|
||||||
|
* Logic in our handler decides whether to release the transport or not.
|
||||||
|
*/
|
||||||
|
if (new_suspend_cause & PA_SUSPEND_INTERNAL)
|
||||||
|
break;
|
||||||
|
|
||||||
/* Stop the device if the source is suspended as well */
|
/* Stop the device if the source is suspended as well */
|
||||||
if (!u->source || u->source->state == PA_SOURCE_SUSPENDED)
|
if (!u->source || u->source->state == PA_SOURCE_SUSPENDED)
|
||||||
/* We deliberately ignore whether stopping
|
/* We deliberately ignore whether stopping
|
||||||
|
|
@ -1181,6 +1198,9 @@ static int sink_set_state_in_io_thread_cb(pa_sink *s, pa_sink_state_t new_state,
|
||||||
if (s->thread_info.state != PA_SINK_SUSPENDED)
|
if (s->thread_info.state != PA_SINK_SUSPENDED)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if (s->suspend_cause & PA_SUSPEND_INTERNAL)
|
||||||
|
break;
|
||||||
|
|
||||||
/* Resume the device if the source was suspended as well */
|
/* Resume the device if the source was suspended as well */
|
||||||
if (!u->source || !PA_SOURCE_IS_OPENED(u->source->thread_info.state))
|
if (!u->source || !PA_SOURCE_IS_OPENED(u->source->thread_info.state))
|
||||||
if (!setup_transport_and_stream(u))
|
if (!setup_transport_and_stream(u))
|
||||||
|
|
@ -2563,10 +2583,7 @@ static void switch_codec_cb_handler(bool success, pa_bluetooth_profile_t profile
|
||||||
u->profile = profile;
|
u->profile = profile;
|
||||||
is_a2dp_sink = u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK;
|
is_a2dp_sink = u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK;
|
||||||
|
|
||||||
// SUSPEND callbacks release the transport and free the codec, but do not reinitialize it yet.
|
// Reacquire the transport and configure the codec
|
||||||
// Acquire the transport (could have been done in the callbacks when leaving SUSPEND) but
|
|
||||||
// _also_ reinitialize the codec with transport_config here:
|
|
||||||
|
|
||||||
r = setup_transport(u);
|
r = setup_transport(u);
|
||||||
pa_assert(!r);
|
pa_assert(!r);
|
||||||
// if (r == -EINPROGRESS)
|
// if (r == -EINPROGRESS)
|
||||||
|
|
@ -2578,11 +2595,10 @@ static void switch_codec_cb_handler(bool success, pa_bluetooth_profile_t profile
|
||||||
|
|
||||||
// Finish off by reconfiguring
|
// Finish off by reconfiguring
|
||||||
|
|
||||||
// TODO HACK: Also cork/uncork sources so that the resampler is updated
|
|
||||||
|
|
||||||
if (is_a2dp_sink) {
|
if (is_a2dp_sink) {
|
||||||
pa_sink_input *i;
|
pa_sink_input *i;
|
||||||
uint32_t idx;
|
uint32_t idx;
|
||||||
|
|
||||||
PA_IDXSET_FOREACH(i, u->sink->inputs, idx) {
|
PA_IDXSET_FOREACH(i, u->sink->inputs, idx) {
|
||||||
pa_sink_input_cork(i, true);
|
pa_sink_input_cork(i, true);
|
||||||
}
|
}
|
||||||
|
|
@ -2591,10 +2607,13 @@ static void switch_codec_cb_handler(bool success, pa_bluetooth_profile_t profile
|
||||||
pa_sink_input_cork(i, false);
|
pa_sink_input_cork(i, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
pa_sink_suspend(u->sink, false, PA_SUSPEND_INTERNAL);
|
pa_asyncmsgq_send(u->sink->asyncmsgq, PA_MSGOBJECT(u->sink), PA_SINK_MESSAGE_SETUP_STREAM, NULL, 0, NULL);
|
||||||
|
|
||||||
|
pa_sink_suspend(u->sink, false, PA_SUSPEND_UNAVAILABLE);
|
||||||
} else {
|
} else {
|
||||||
pa_source_output *i;
|
pa_source_output *i;
|
||||||
uint32_t idx;
|
uint32_t idx;
|
||||||
|
|
||||||
PA_IDXSET_FOREACH(i, u->source->outputs, idx) {
|
PA_IDXSET_FOREACH(i, u->source->outputs, idx) {
|
||||||
pa_source_output_cork(i, true);
|
pa_source_output_cork(i, true);
|
||||||
}
|
}
|
||||||
|
|
@ -2603,7 +2622,9 @@ static void switch_codec_cb_handler(bool success, pa_bluetooth_profile_t profile
|
||||||
pa_source_output_cork(i, false);
|
pa_source_output_cork(i, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
pa_source_suspend(u->source, false, PA_SUSPEND_INTERNAL);
|
pa_asyncmsgq_send(u->source->asyncmsgq, PA_MSGOBJECT(u->source), PA_SOURCE_MESSAGE_SETUP_STREAM, NULL, 0, NULL);
|
||||||
|
|
||||||
|
pa_source_suspend(u->source, false, PA_SUSPEND_UNAVAILABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
pa_log_info("Codec successfully switched to %s with profile: %s",
|
pa_log_info("Codec successfully switched to %s with profile: %s",
|
||||||
|
|
@ -2777,10 +2798,11 @@ static int bluez5_device_message_handler(const char *object_path, const char *me
|
||||||
profile = u->profile;
|
profile = u->profile;
|
||||||
|
|
||||||
// Suspending releases the transport
|
// Suspending releases the transport
|
||||||
|
|
||||||
if (is_a2dp_sink)
|
if (is_a2dp_sink)
|
||||||
pa_sink_suspend(u->sink, true, PA_SUSPEND_INTERNAL);
|
pa_sink_suspend(u->sink, true, PA_SUSPEND_UNAVAILABLE);
|
||||||
else
|
else
|
||||||
pa_source_suspend(u->source, true, PA_SUSPEND_INTERNAL);
|
pa_source_suspend(u->source, true, PA_SUSPEND_UNAVAILABLE);
|
||||||
|
|
||||||
// TODO: Can we do this if it's synchronous?
|
// TODO: Can we do this if it's synchronous?
|
||||||
release_codec(u);
|
release_codec(u);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue