Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2023-07-11 19:47:44 +0300
committerSebastian Dröge <sebastian@centricular.com>2023-07-19 09:38:28 +0300
commit9854b299a23cf4c7eaf112b84b5611f6661a71e1 (patch)
tree6ffe97610020d37b06093b2e7d1dd12152939f49
parentbdcdbfeaaffb76e06d1bcfbef337ba5427bc8580 (diff)
webrtcsink: Translate force-keyunit events to force-IDR action signal for NVIDIA encoders
NVIDIA's v4l2 encoder elements don't handle the force-keyunit events but instead provide a custom action signal based API for requesting a keyframe. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1285>
-rw-r--r--net/webrtc/src/webrtcsink/imp.rs36
1 files changed, 36 insertions, 0 deletions
diff --git a/net/webrtc/src/webrtcsink/imp.rs b/net/webrtc/src/webrtcsink/imp.rs
index 4a7798e26..85b94b0fa 100644
--- a/net/webrtc/src/webrtcsink/imp.rs
+++ b/net/webrtc/src/webrtcsink/imp.rs
@@ -407,6 +407,40 @@ fn make_converter_for_video_caps(caps: &gst::Caps) -> Result<gst::Element, Error
Ok(ret.upcast())
}
+/// Add a pad probe to convert force-keyunit events to the custom action signal based NVIDIA
+/// encoder API.
+fn add_nv4l2enc_force_keyunit_workaround(enc: &gst::Element) {
+ use std::sync::atomic::{self, AtomicBool};
+
+ let srcpad = enc.static_pad("src").unwrap();
+ let saw_buffer = AtomicBool::new(false);
+ srcpad
+ .add_probe(
+ gst::PadProbeType::BUFFER
+ | gst::PadProbeType::BUFFER_LIST
+ | gst::PadProbeType::EVENT_UPSTREAM,
+ move |pad, info| {
+ match info.data {
+ Some(gst::PadProbeData::Buffer(..))
+ | Some(gst::PadProbeData::BufferList(..)) => {
+ saw_buffer.store(true, atomic::Ordering::SeqCst);
+ }
+ Some(gst::PadProbeData::Event(ref ev))
+ if gst_video::ForceKeyUnitEvent::is(ev)
+ && saw_buffer.load(atomic::Ordering::SeqCst) =>
+ {
+ let enc = pad.parent().unwrap();
+ enc.emit_by_name::<()>("force-IDR", &[]);
+ }
+ _ => {}
+ }
+
+ gst::PadProbeReturn::Ok
+ },
+ )
+ .unwrap();
+}
+
/// Default configuration for known encoders, can be disabled
/// by returning True from an encoder-setup handler.
fn configure_encoder(enc: &gst::Element, start_bitrate: u32) {
@@ -455,6 +489,7 @@ fn configure_encoder(enc: &gst::Element, start_bitrate: u32) {
enc.set_property("insert-sps-pps", true);
enc.set_property("insert-aud", true);
enc.set_property_from_str("control-rate", "constant_bitrate");
+ add_nv4l2enc_force_keyunit_workaround(enc);
}
"nvv4l2vp8enc" | "nvv4l2vp9enc" => {
enc.set_property("bitrate", start_bitrate);
@@ -462,6 +497,7 @@ fn configure_encoder(enc: &gst::Element, start_bitrate: u32) {
enc.set_property("maxperf-enable", true);
enc.set_property("idrinterval", 256u32);
enc.set_property_from_str("control-rate", "constant_bitrate");
+ add_nv4l2enc_force_keyunit_workaround(enc);
}
_ => (),
}