mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-11-25 13:01:07 +00:00
webrtcsink: Support av1 via nvav1enc, av1enc, and rav1enc
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1572>
This commit is contained in:
parent
b12da2c543
commit
f5a7de9dc3
3 changed files with 67 additions and 18 deletions
|
@ -8800,7 +8800,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"
|
||||
|
@ -8833,7 +8833,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"
|
||||
|
@ -8880,7 +8880,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"
|
||||
|
@ -8912,7 +8912,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"
|
||||
|
@ -8945,7 +8945,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"
|
||||
|
@ -8979,7 +8979,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"
|
||||
|
@ -9012,7 +9012,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"
|
||||
|
@ -9044,7 +9044,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"
|
||||
|
@ -9260,7 +9260,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",
|
||||
|
@ -9467,7 +9467,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,
|
||||
|
|
|
@ -680,6 +680,7 @@ impl Codec {
|
|||
match self.name.as_str() {
|
||||
"H264" => make_element("h264parse", None),
|
||||
"H265" => make_element("h265parse", None),
|
||||
"AV1" => make_element("av1parse", None),
|
||||
_ => return Ok(None),
|
||||
}
|
||||
.map(Some)
|
||||
|
@ -723,6 +724,7 @@ pub static VP8_CAPS: Lazy<gst::Caps> = Lazy::new(|| gst::Caps::new_empty_simple(
|
|||
pub static VP9_CAPS: Lazy<gst::Caps> = Lazy::new(|| gst::Caps::new_empty_simple("video/x-vp9"));
|
||||
pub static H264_CAPS: Lazy<gst::Caps> = Lazy::new(|| gst::Caps::new_empty_simple("video/x-h264"));
|
||||
pub static H265_CAPS: Lazy<gst::Caps> = Lazy::new(|| gst::Caps::new_empty_simple("video/x-h265"));
|
||||
pub static AV1_CAPS: Lazy<gst::Caps> = Lazy::new(|| gst::Caps::new_empty_simple("video/x-av1"));
|
||||
|
||||
pub static RTP_CAPS: Lazy<gst::Caps> =
|
||||
Lazy::new(|| gst::Caps::new_empty_simple("application/x-rtp"));
|
||||
|
@ -814,6 +816,14 @@ static CODECS: Lazy<Codecs> = Lazy::new(|| {
|
|||
&encoders,
|
||||
&payloaders,
|
||||
),
|
||||
Codec::new(
|
||||
"AV1",
|
||||
gst::StreamType::VIDEO,
|
||||
&AV1_CAPS,
|
||||
&decoders,
|
||||
&encoders,
|
||||
&payloaders,
|
||||
),
|
||||
])
|
||||
});
|
||||
|
||||
|
|
|
@ -760,13 +760,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);
|
||||
|
||||
|
@ -964,16 +982,19 @@ impl VideoEncoder {
|
|||
| "nvv4l2h264enc"
|
||||
| "nvv4l2vp8enc"
|
||||
| "nvv4l2vp9enc"
|
||||
| "nvav1enc"
|
||||
| "av1enc"
|
||||
| "rav1enc"
|
||||
)
|
||||
}
|
||||
|
||||
fn bitrate(&self) -> Result<i32, WebRTCSinkError> {
|
||||
let bitrate = match self.factory_name.as_str() {
|
||||
"vp8enc" | "vp9enc" => self.element.property::<i32>("target-bitrate"),
|
||||
"x264enc" | "nvh264enc" | "vaapih264enc" | "vaapivp8enc" | "qsvh264enc" => {
|
||||
(self.element.property::<u32>("bitrate") * 1000) as i32
|
||||
}
|
||||
"nvv4l2h264enc" | "nvv4l2vp8enc" | "nvv4l2vp9enc" => {
|
||||
"av1enc" => (self.element.property::<u32>("target-bitrate") * 1000) as i32,
|
||||
"x264enc" | "nvh264enc" | "vaapih264enc" | "vaapivp8enc" | "qsvh264enc"
|
||||
| "nvav1enc" => (self.element.property::<u32>("bitrate") * 1000) as i32,
|
||||
"nvv4l2h264enc" | "nvv4l2vp8enc" | "nvv4l2vp9enc" | "rav1enc" => {
|
||||
(self.element.property::<u32>("bitrate")) as i32
|
||||
}
|
||||
_ => return Err(WebRTCSinkError::BitrateNotSupported),
|
||||
|
@ -1003,11 +1024,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),
|
||||
|
@ -1658,7 +1683,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");
|
||||
}
|
||||
}
|
||||
|
||||
if self.settings.lock().unwrap().do_clock_signalling {
|
||||
|
|
Loading…
Reference in a new issue