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: <https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/merge_requests/1341>
This commit is contained in:
Guillaume Desmottes 2023-10-03 09:15:11 +02:00 committed by Sebastian Dröge
parent ae76c83ddf
commit 1915957409

View file

@ -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(),