I’m using the very nice Rust gstreamer bindings to create a pipeline that delivers video from an rtpsrc to an appsink, for delivery to another external system. The part of the pipeline I’m setting up looks like this:
rtspsrc → rtph264depay → h264parse → appsink
The problem I’m having is that when a new client on the external system connects, I would like the pipeline to request a key frame from the rtsp server. Based on this document, my plan so far was to inject a GstForceKeyUnit upstream to encourage the rtpsession to send a PLI packet.
However, I can’t seem to get it working. The send_event()
call always returns false and the PLI isn’t generated. I’ve tried a few different strategies, including sending the event from appsink and from the src pad of the depay.
Is what I’m trying to do possible?
Thanks!
Sending the event to the appsink:
fn send_force_keyunit_upstream(data: Weak<Mutex<CustomData>>) {
let event = gstreamer_video::UpstreamForceKeyUnitEvent::builder()
.all_headers(true)
.build();
let data = data
.upgrade()
.expect("failed to get data");
let mut d = data.lock().unwrap();
if let Some(appsink) = &d.video_appsink {
let pad = appsink
.static_pad("sink")
.expect("failed to get appsink pad");
if pad.send_event(event) {
info!("GstForceKeyUnit Send Suceessfullyl!");
} else {
error!("SENDING GstForceKeyUnit Failed!");
}
}
}
Sending the event to the depay src pad:
fn send_force_keyunit_upstream(pipeline: &gstreamer::Pipeline) {
let iter = pipeline.iterate_recurse();
for element in iter {
if let Ok(element) = element {
if element
.factory()
.map(|f| f.name() == "rtph264depay")
.unwrap_or(false)
{
let event = gstreamer_video::UpstreamForceKeyUnitEvent::builder()
.all_headers(true)
.build();
if let Some(pad) = element.static_pad("src") {
if !pad.send_event(event) {
error!("Sending key unit request FAILED");
}
} else {
error!("failed to get depay src pad!");
}
}
}
}
}