mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2025-02-15 12:25:20 +00:00
webrtcsink: NVIDIA V4L2 encoders always require NVMM memory
And if the input is not like that then a corresponding converter must be inserted. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1327>
This commit is contained in:
parent
0205aa43d6
commit
17f7b04b82
1 changed files with 28 additions and 18 deletions
|
@ -90,6 +90,10 @@ impl Codec {
|
||||||
self.encoder
|
self.encoder
|
||||||
.has_type(gst::ElementFactoryType::VIDEO_ENCODER)
|
.has_type(gst::ElementFactoryType::VIDEO_ENCODER)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn encoder_factory(&self) -> &gst::ElementFactory {
|
||||||
|
&self.encoder
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wrapper around our sink pads
|
/// Wrapper around our sink pads
|
||||||
|
@ -307,7 +311,7 @@ impl Default for State {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_converter_for_video_caps(caps: &gst::Caps) -> Result<gst::Element, Error> {
|
fn make_converter_for_video_caps(caps: &gst::Caps, codec: &Codec) -> Result<gst::Element, Error> {
|
||||||
assert!(caps.is_fixed());
|
assert!(caps.is_fixed());
|
||||||
|
|
||||||
let video_info = gst_video::VideoInfo::from_caps(caps)?;
|
let video_info = gst_video::VideoInfo::from_caps(caps)?;
|
||||||
|
@ -316,7 +320,27 @@ fn make_converter_for_video_caps(caps: &gst::Caps) -> Result<gst::Element, Error
|
||||||
|
|
||||||
let (head, mut tail) = {
|
let (head, mut tail) = {
|
||||||
if let Some(feature) = caps.features(0) {
|
if let Some(feature) = caps.features(0) {
|
||||||
if feature.contains(CUDA_MEMORY_FEATURE) {
|
if feature.contains(NVMM_MEMORY_FEATURE)
|
||||||
|
// NVIDIA V4L2 encoders require NVMM memory as input and that requires using the
|
||||||
|
// corresponding converter
|
||||||
|
|| codec
|
||||||
|
.encoder_factory()
|
||||||
|
.name().starts_with("nvv4l2")
|
||||||
|
{
|
||||||
|
let queue = make_element("queue", None)?;
|
||||||
|
let nvconvert = if let Ok(nvconvert) = make_element("nvvideoconvert", None) {
|
||||||
|
nvconvert.set_property_from_str("compute-hw", "Default");
|
||||||
|
nvconvert.set_property_from_str("nvbuf-memory-type", "nvbuf-mem-default");
|
||||||
|
nvconvert
|
||||||
|
} else {
|
||||||
|
make_element("nvvidconv", None)?
|
||||||
|
};
|
||||||
|
|
||||||
|
ret.add_many(&[&queue, &nvconvert])?;
|
||||||
|
gst::Element::link_many(&[&queue, &nvconvert])?;
|
||||||
|
|
||||||
|
(queue, nvconvert)
|
||||||
|
} else if feature.contains(CUDA_MEMORY_FEATURE) {
|
||||||
if let Some(convert_factory) = gst::ElementFactory::find("cudaconvert") {
|
if let Some(convert_factory) = gst::ElementFactory::find("cudaconvert") {
|
||||||
let cudaupload = make_element("cudaupload", None)?;
|
let cudaupload = make_element("cudaupload", None)?;
|
||||||
let cudaconvert = convert_factory.create().build()?;
|
let cudaconvert = convert_factory.create().build()?;
|
||||||
|
@ -350,20 +374,6 @@ fn make_converter_for_video_caps(caps: &gst::Caps) -> Result<gst::Element, Error
|
||||||
gst::Element::link_many(&[&glupload, &glconvert, &glscale])?;
|
gst::Element::link_many(&[&glupload, &glconvert, &glscale])?;
|
||||||
|
|
||||||
(glupload, glscale)
|
(glupload, glscale)
|
||||||
} else if feature.contains(NVMM_MEMORY_FEATURE) {
|
|
||||||
let queue = make_element("queue", None)?;
|
|
||||||
let nvconvert = if let Ok(nvconvert) = make_element("nvvideoconvert", None) {
|
|
||||||
nvconvert.set_property_from_str("compute-hw", "Default");
|
|
||||||
nvconvert.set_property_from_str("nvbuf-memory-type", "nvbuf-mem-default");
|
|
||||||
nvconvert
|
|
||||||
} else {
|
|
||||||
make_element("nvvidconv", None)?
|
|
||||||
};
|
|
||||||
|
|
||||||
ret.add_many(&[&queue, &nvconvert])?;
|
|
||||||
gst::Element::link_many(&[&queue, &nvconvert])?;
|
|
||||||
|
|
||||||
(queue, nvconvert)
|
|
||||||
} else {
|
} else {
|
||||||
let convert = make_element("videoconvert", None)?;
|
let convert = make_element("videoconvert", None)?;
|
||||||
let scale = make_element("videoscale", None)?;
|
let scale = make_element("videoscale", None)?;
|
||||||
|
@ -516,7 +526,7 @@ fn setup_encoding(
|
||||||
twcc: bool,
|
twcc: bool,
|
||||||
) -> Result<(gst::Element, gst::Element, gst::Element), Error> {
|
) -> Result<(gst::Element, gst::Element, gst::Element), Error> {
|
||||||
let conv = match codec.is_video() {
|
let conv = match codec.is_video() {
|
||||||
true => make_converter_for_video_caps(input_caps)?.upcast(),
|
true => make_converter_for_video_caps(input_caps, codec)?.upcast(),
|
||||||
false => gst::parse_bin_from_description("audioresample ! audioconvert", true)?.upcast(),
|
false => gst::parse_bin_from_description("audioresample ! audioconvert", true)?.upcast(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2147,7 +2157,7 @@ impl WebRTCSink {
|
||||||
let mut elements = vec![src.clone()];
|
let mut elements = vec![src.clone()];
|
||||||
|
|
||||||
if codec.is_video() {
|
if codec.is_video() {
|
||||||
elements.push(make_converter_for_video_caps(caps)?);
|
elements.push(make_converter_for_video_caps(caps, &codec)?);
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
|
|
Loading…
Reference in a new issue