diff --git a/docs/plugins/gst_plugins_cache.json b/docs/plugins/gst_plugins_cache.json index 4384a2a0..87ae9c49 100644 --- a/docs/plugins/gst_plugins_cache.json +++ b/docs/plugins/gst_plugins_cache.json @@ -6759,7 +6759,7 @@ "type": "GstWebRTCSinkPad" }, "video_%%u": { - "caps": "video/x-raw:\n\nvideo/x-raw(memory:CUDAMemory):\n\nvideo/x-raw(memory:GLMemory):\n\nvideo/x-raw(memory:NVMM):\n\nvideo/x-raw(memory:D3D11Memory):\nvideo/x-vp8:\nvideo/x-h264:\nvideo/x-vp9:\nvideo/x-h265:\n", + "caps": "video/x-raw:\n\nvideo/x-raw(memory:CUDAMemory):\n\nvideo/x-raw(memory:GLMemory):\n\nvideo/x-raw(memory:NVMM):\n\nvideo/x-raw(memory:D3D11Memory):\nvideo/x-vp8:\nvideo/x-h264:\nvideo/x-vp9:\nvideo/x-h265:\nvideo/x-av1:\n", "direction": "sink", "presence": "request", "type": "GstWebRTCSinkPad" @@ -6792,7 +6792,7 @@ "type": "GstWebRTCSinkPad" }, "video_%%u": { - "caps": "video/x-raw:\n\nvideo/x-raw(memory:CUDAMemory):\n\nvideo/x-raw(memory:GLMemory):\n\nvideo/x-raw(memory:NVMM):\n\nvideo/x-raw(memory:D3D11Memory):\nvideo/x-vp8:\nvideo/x-h264:\nvideo/x-vp9:\nvideo/x-h265:\n", + "caps": "video/x-raw:\n\nvideo/x-raw(memory:CUDAMemory):\n\nvideo/x-raw(memory:GLMemory):\n\nvideo/x-raw(memory:NVMM):\n\nvideo/x-raw(memory:D3D11Memory):\nvideo/x-vp8:\nvideo/x-h264:\nvideo/x-vp9:\nvideo/x-h265:\nvideo/x-av1:\n", "direction": "sink", "presence": "request", "type": "GstWebRTCSinkPad" @@ -6825,7 +6825,7 @@ "type": "GstWebRTCSinkPad" }, "video_%%u": { - "caps": "video/x-raw:\n\nvideo/x-raw(memory:CUDAMemory):\n\nvideo/x-raw(memory:GLMemory):\n\nvideo/x-raw(memory:NVMM):\n\nvideo/x-raw(memory:D3D11Memory):\nvideo/x-vp8:\nvideo/x-h264:\nvideo/x-vp9:\nvideo/x-h265:\n", + "caps": "video/x-raw:\n\nvideo/x-raw(memory:CUDAMemory):\n\nvideo/x-raw(memory:GLMemory):\n\nvideo/x-raw(memory:NVMM):\n\nvideo/x-raw(memory:D3D11Memory):\nvideo/x-vp8:\nvideo/x-h264:\nvideo/x-vp9:\nvideo/x-h265:\nvideo/x-av1:\n", "direction": "sink", "presence": "request", "type": "GstWebRTCSinkPad" @@ -6857,7 +6857,7 @@ "type": "GstWebRTCSrcPad" }, "video_%%u": { - "caps": "video/x-raw(ANY):\napplication/x-rtp:\nvideo/x-vp8:\nvideo/x-h264:\nvideo/x-vp9:\nvideo/x-h265:\n", + "caps": "video/x-raw(ANY):\napplication/x-rtp:\nvideo/x-vp8:\nvideo/x-h264:\nvideo/x-vp9:\nvideo/x-h265:\nvideo/x-av1:\n", "direction": "src", "presence": "sometimes", "type": "GstWebRTCSrcPad" @@ -6890,7 +6890,7 @@ "type": "GstWebRTCSinkPad" }, "video_%%u": { - "caps": "video/x-raw:\n\nvideo/x-raw(memory:CUDAMemory):\n\nvideo/x-raw(memory:GLMemory):\n\nvideo/x-raw(memory:NVMM):\n\nvideo/x-raw(memory:D3D11Memory):\nvideo/x-vp8:\nvideo/x-h264:\nvideo/x-vp9:\nvideo/x-h265:\n", + "caps": "video/x-raw:\n\nvideo/x-raw(memory:CUDAMemory):\n\nvideo/x-raw(memory:GLMemory):\n\nvideo/x-raw(memory:NVMM):\n\nvideo/x-raw(memory:D3D11Memory):\nvideo/x-vp8:\nvideo/x-h264:\nvideo/x-vp9:\nvideo/x-h265:\nvideo/x-av1:\n", "direction": "sink", "presence": "request", "type": "GstWebRTCSinkPad" @@ -6924,7 +6924,7 @@ "type": "GstWebRTCSrcPad" }, "video_%%u": { - "caps": "video/x-raw(ANY):\napplication/x-rtp:\nvideo/x-vp8:\nvideo/x-h264:\nvideo/x-vp9:\nvideo/x-h265:\n", + "caps": "video/x-raw(ANY):\napplication/x-rtp:\nvideo/x-vp8:\nvideo/x-h264:\nvideo/x-vp9:\nvideo/x-h265:\nvideo/x-av1:\n", "direction": "src", "presence": "sometimes", "type": "GstWebRTCSrcPad" @@ -6957,7 +6957,7 @@ "type": "GstWebRTCSinkPad" }, "video_%%u": { - "caps": "video/x-raw:\n\nvideo/x-raw(memory:CUDAMemory):\n\nvideo/x-raw(memory:GLMemory):\n\nvideo/x-raw(memory:NVMM):\n\nvideo/x-raw(memory:D3D11Memory):\nvideo/x-vp8:\nvideo/x-h264:\nvideo/x-vp9:\nvideo/x-h265:\n", + "caps": "video/x-raw:\n\nvideo/x-raw(memory:CUDAMemory):\n\nvideo/x-raw(memory:GLMemory):\n\nvideo/x-raw(memory:NVMM):\n\nvideo/x-raw(memory:D3D11Memory):\nvideo/x-vp8:\nvideo/x-h264:\nvideo/x-vp9:\nvideo/x-h265:\nvideo/x-av1:\n", "direction": "sink", "presence": "request", "type": "GstWebRTCSinkPad" @@ -6989,7 +6989,7 @@ "type": "GstWebRTCSrcPad" }, "video_%%u": { - "caps": "video/x-raw(ANY):\napplication/x-rtp:\nvideo/x-vp8:\nvideo/x-h264:\nvideo/x-vp9:\nvideo/x-h265:\n", + "caps": "video/x-raw(ANY):\napplication/x-rtp:\nvideo/x-vp8:\nvideo/x-h264:\nvideo/x-vp9:\nvideo/x-h265:\nvideo/x-av1:\n", "direction": "src", "presence": "sometimes", "type": "GstWebRTCSrcPad" @@ -7193,7 +7193,7 @@ "construct": false, "construct-only": false, "controllable": false, - "default": "video/x-vp8; video/x-h264; video/x-vp9; video/x-h265", + "default": "video/x-vp8; video/x-h264; video/x-vp9; video/x-h265; video/x-av1", "mutable": "ready", "readable": true, "type": "GstCaps", @@ -7400,7 +7400,7 @@ "writable": true }, "video-codecs": { - "blurb": "Names of video codecs to be be used during the SDP negotiation. Valid values: [VP8, H264, VP9, H265]", + "blurb": "Names of video codecs to be be used during the SDP negotiation. Valid values: [VP8, H264, VP9, H265, AV1]", "conditionally-available": false, "construct": false, "construct-only": false, diff --git a/net/webrtc/src/utils.rs b/net/webrtc/src/utils.rs index b45c4a95..da93fd4a 100644 --- a/net/webrtc/src/utils.rs +++ b/net/webrtc/src/utils.rs @@ -676,6 +676,7 @@ impl Codec { "VP9" => make_element("vp9parse", None), "H264" => make_element("h264parse", None), "H265" => make_element("h265parse", None), + "AV1" => make_element("av1parse", None), _ => return Ok(None), } .map(Some) @@ -719,6 +720,7 @@ pub static VP8_CAPS: Lazy = Lazy::new(|| gst::Caps::new_empty_simple( pub static VP9_CAPS: Lazy = Lazy::new(|| gst::Caps::new_empty_simple("video/x-vp9")); pub static H264_CAPS: Lazy = Lazy::new(|| gst::Caps::new_empty_simple("video/x-h264")); pub static H265_CAPS: Lazy = Lazy::new(|| gst::Caps::new_empty_simple("video/x-h265")); +pub static AV1_CAPS: Lazy = Lazy::new(|| gst::Caps::new_empty_simple("video/x-av1")); pub static RTP_CAPS: Lazy = Lazy::new(|| gst::Caps::new_empty_simple("application/x-rtp")); @@ -810,6 +812,14 @@ static CODECS: Lazy = Lazy::new(|| { &encoders, &payloaders, ), + Codec::new( + "AV1", + gst::StreamType::VIDEO, + &AV1_CAPS, + &decoders, + &encoders, + &payloaders, + ), ]) }); diff --git a/net/webrtc/src/webrtcsink/imp.rs b/net/webrtc/src/webrtcsink/imp.rs index d05d0732..53e9e950 100644 --- a/net/webrtc/src/webrtcsink/imp.rs +++ b/net/webrtc/src/webrtcsink/imp.rs @@ -761,13 +761,31 @@ fn configure_encoder(enc: &gst::Element, start_bitrate: u32) { enc.set_property("disable-hrd-conformance", true); enc.set_property_from_str("rate-control", "cbr"); } + "nvav1enc" => { + enc.set_property("bitrate", start_bitrate / 1000); + enc.set_property("gop-size", -1i32); + enc.set_property_from_str("rc-mode", "cbr"); + enc.set_property("zerolatency", true); + } + "av1enc" => { + enc.set_property("target-bitrate", start_bitrate / 1000); + enc.set_property_from_str("end-usage", "cbr"); + enc.set_property("keyframe-max-dist", i32::MAX); + enc.set_property_from_str("usage-profile", "real-time"); + } + "rav1enc" => { + enc.set_property("bitrate", start_bitrate); + enc.set_property("low-latency", true); + enc.set_property("max-key-frame-interval", 715827882); + enc.set_property("speed-preset", 10); + } _ => (), } } } /// Default configuration for known payloaders, can be disabled -/// by returning True from an payloader-setup handler. +/// by returning True from a payloader-setup handler. fn configure_payloader(pay: &gst::Element) { pay.set_property("mtu", 1200_u32); @@ -965,16 +983,19 @@ impl VideoEncoder { | "nvv4l2h264enc" | "nvv4l2vp8enc" | "nvv4l2vp9enc" + | "nvav1enc" + | "av1enc" + | "rav1enc" ) } fn bitrate(&self) -> Result { let bitrate = match self.factory_name.as_str() { "vp8enc" | "vp9enc" => self.element.property::("target-bitrate"), - "x264enc" | "nvh264enc" | "vaapih264enc" | "vaapivp8enc" | "qsvh264enc" => { - (self.element.property::("bitrate") * 1000) as i32 - } - "nvv4l2h264enc" | "nvv4l2vp8enc" | "nvv4l2vp9enc" => { + "av1enc" => (self.element.property::("target-bitrate") * 1000) as i32, + "x264enc" | "nvh264enc" | "vaapih264enc" | "vaapivp8enc" | "qsvh264enc" + | "nvav1enc" => (self.element.property::("bitrate") * 1000) as i32, + "nvv4l2h264enc" | "nvv4l2vp8enc" | "nvv4l2vp9enc" | "rav1enc" => { (self.element.property::("bitrate")) as i32 } _ => return Err(WebRTCSinkError::BitrateNotSupported), @@ -1004,11 +1025,15 @@ impl VideoEncoder { ) -> Result<(), WebRTCSinkError> { match self.factory_name.as_str() { "vp8enc" | "vp9enc" => self.element.set_property("target-bitrate", bitrate), - "x264enc" | "nvh264enc" | "vaapih264enc" | "vaapivp8enc" | "qsvh264enc" => { + "av1enc" => self + .element + .set_property("target-bitrate", (bitrate / 1000) as u32), + "x264enc" | "nvh264enc" | "vaapih264enc" | "vaapivp8enc" | "qsvh264enc" + | "nvav1enc" => { self.element .set_property("bitrate", (bitrate / 1000) as u32); } - "nvv4l2h264enc" | "nvv4l2vp8enc" | "nvv4l2vp9enc" => { + "nvv4l2h264enc" | "nvv4l2vp8enc" | "nvv4l2vp9enc" | "rav1enc" => { self.element.set_property("bitrate", bitrate as u32) } _ => return Err(WebRTCSinkError::BitrateNotSupported), @@ -1655,7 +1680,21 @@ impl BaseWebRTCSink { ); if let Some(ssrc) = ssrc { - payloader.set_property("ssrc", ssrc); + if let Some(pspec) = payloader.find_property("ssrc") { + match pspec.value_type() { + glib::Type::I64 => { + payloader.set_property("ssrc", ssrc as i64); + } + glib::Type::U32 => { + payloader.set_property("ssrc", ssrc); + } + _ => { + gst::warning!(CAT, imp: self, "Unsupported ssrc type (expected i64 or u32)"); + } + } + } else { + gst::warning!(CAT, imp: self, "Failed to find 'ssrc' property on payloader"); + } } self.configure_congestion_control(payloader, codec, extension_configuration_type)