From 19159574097272245d238684b191e3d176dde465 Mon Sep 17 00:00:00 2001 From: Guillaume Desmottes Date: Tue, 3 Oct 2023 09:15:11 +0200 Subject: [PATCH] gst-utils: prevent dead lock when requesting key unit Sending the UpstreamForceKeyUnitEvent using gst_element_send_event() internally takes the state lock. If appsink is pre-rolling we are also holding the preroll lock. This may result in a dead lock with the thread doing the state change as this one takes the state lock and then the pre-roll lock. Part-of: --- gstreamer-utils/src/streamproducer.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/gstreamer-utils/src/streamproducer.rs b/gstreamer-utils/src/streamproducer.rs index 409e4f2b2..4ee5718ff 100644 --- a/gstreamer-utils/src/streamproducer.rs +++ b/gstreamer-utils/src/streamproducer.rs @@ -136,7 +136,9 @@ impl StreamProducer { if let Some(gst::PadProbeData::Event(ref ev)) = info.data { if gst_video::UpstreamForceKeyUnitEvent::parse(ev).is_ok() { gst::debug!(CAT, obj: &appsink, "Requesting keyframe"); - let _ = appsink.send_event(ev.clone()); + // Do not use `gst_element_send_event()` as it takes the state lock which may lead to dead locks. + let pad = appsink.static_pad("sink").unwrap(); + let _ = pad.push_event(ev.clone()); } } @@ -311,7 +313,9 @@ impl<'a> From<&'a gst_app::AppSink> for StreamProducer { drop(consumers); if needs_keyframe_request { - appsink.send_event( + // Do not use `gst_element_send_event()` as it takes the state lock which may lead to dead locks. + let pad = appsink.static_pad("sink").unwrap(); + pad.push_event( gst_video::UpstreamForceKeyUnitEvent::builder() .all_headers(true) .build(),