webrtcsink: fix deadlock on encoder setup

Refactor connect_input_stream in order to avoid an ABBA deadlock
altogether: where in other spots we lock settings then state, here we
were emitting encoder-setup with state held, then locking settings in
the default handler.

We could have changed the locking order in the other spots, but instead
we can also just release the state lock when emitting the signal, which
is good practice.

Fixes #108
This commit is contained in:
Mathieu Duponchelle 2022-10-07 21:02:52 +02:00
parent c4f771dbbc
commit f82a731b3a

View file

@ -75,7 +75,7 @@ struct Settings {
} }
/// Represents a codec we can offer /// Represents a codec we can offer
#[derive(Debug)] #[derive(Debug, Clone)]
struct Codec { struct Codec {
encoder: gst::ElementFactory, encoder: gst::ElementFactory,
payloader: gst::ElementFactory, payloader: gst::ElementFactory,
@ -1858,6 +1858,7 @@ impl WebRTCSink {
fn on_remote_description_set(&self, element: &super::WebRTCSink, session_id: String) { fn on_remote_description_set(&self, element: &super::WebRTCSink, session_id: String) {
let mut state = self.state.lock().unwrap(); let mut state = self.state.lock().unwrap();
let mut remove = false; let mut remove = false;
let codecs = state.codecs.clone();
if let Some(mut session) = state.sessions.remove(&session_id) { if let Some(mut session) = state.sessions.remove(&session_id) {
for webrtc_pad in session.webrtc_pads.clone().values() { for webrtc_pad in session.webrtc_pads.clone().values() {
@ -1874,10 +1875,11 @@ impl WebRTCSink {
if let Some(producer) = state if let Some(producer) = state
.streams .streams
.get(&webrtc_pad.stream_name) .get(&webrtc_pad.stream_name)
.and_then(|stream| stream.producer.as_ref()) .and_then(|stream| stream.producer.clone())
{ {
drop(state);
if let Err(err) = if let Err(err) =
session.connect_input_stream(element, producer, webrtc_pad, &state.codecs) session.connect_input_stream(element, &producer, webrtc_pad, &codecs)
{ {
gst::error!( gst::error!(
CAT, CAT,
@ -1888,8 +1890,10 @@ impl WebRTCSink {
err err
); );
remove = true; remove = true;
state = self.state.lock().unwrap();
break; break;
} }
state = self.state.lock().unwrap();
} else { } else {
gst::error!( gst::error!(
CAT, CAT,