fallbacksrc: Don't configure conversion elements for normal stream

Internal conversion element can cause unexpected format/resolution
change depending negotiated result, which didn't happen before
the recent fallbacksrc update for fallback stream support.

Configure conversion objects only for fallback streams and also
fallback-{audio,video}-caps are specified, in order to keep
previous behavior.
This commit is contained in:
Seungha Yang 2022-10-20 22:19:28 +09:00 committed by Sebastian Dröge
parent 363de0c1c6
commit 92266cb82c

View file

@ -1571,6 +1571,153 @@ impl FallbackSrc {
state.flow_combiner.update_pad_flow(pad, res) state.flow_combiner.update_pad_flow(pad, res)
} }
fn create_image_converts(
&self,
filter_caps: &gst::Caps,
fallback_source: bool,
) -> gst::Element {
let imagefreeze = gst::ElementFactory::make("imagefreeze")
.property("is-live", true)
.build()
.expect("No imagefreeze found");
if !fallback_source || filter_caps.is_any() {
return imagefreeze;
}
let bin = gst::Bin::new(None);
let videoconvert = gst::ElementFactory::make("videoconvert")
.name("video_videoconvert")
.build()
.expect("No videoconvert found");
let videoscale = gst::ElementFactory::make("videoscale")
.name("video_videoscale")
.build()
.expect("No videoscale found");
let capsfilter = gst::ElementFactory::make("capsfilter")
.name("video_capsfilter")
.property("caps", filter_caps)
.build()
.expect("No capsfilter found");
bin.add_many(&[&videoconvert, &videoscale, &imagefreeze, &capsfilter])
.unwrap();
gst::Element::link_many(&[&videoconvert, &videoscale, &imagefreeze, &capsfilter]).unwrap();
let ghostpad =
gst::GhostPad::with_target(Some("sink"), &videoconvert.static_pad("sink").unwrap())
.unwrap();
ghostpad.set_active(true).unwrap();
bin.add_pad(&ghostpad).unwrap();
let ghostpad =
gst::GhostPad::with_target(Some("src"), &capsfilter.static_pad("src").unwrap())
.unwrap();
ghostpad.set_active(true).unwrap();
bin.add_pad(&ghostpad).unwrap();
bin.upcast()
}
fn create_video_converts(
&self,
filter_caps: &gst::Caps,
fallback_source: bool,
) -> gst::Element {
if !fallback_source || filter_caps.is_any() {
return gst::ElementFactory::make("identity")
.build()
.expect("No identity found");
}
let bin = gst::Bin::new(None);
let videoconvert = gst::ElementFactory::make("videoconvert")
.name("video_videoconvert")
.build()
.expect("No videoconvert found");
let videoscale = gst::ElementFactory::make("videoscale")
.name("video_videoscale")
.build()
.expect("No videoscale found");
let capsfilter = gst::ElementFactory::make("capsfilter")
.name("video_capsfilter")
.property("caps", filter_caps)
.build()
.expect("No capsfilter found");
bin.add_many(&[&videoconvert, &videoscale, &capsfilter])
.unwrap();
gst::Element::link_many(&[&videoconvert, &videoscale, &capsfilter]).unwrap();
let ghostpad =
gst::GhostPad::with_target(Some("sink"), &videoconvert.static_pad("sink").unwrap())
.unwrap();
ghostpad.set_active(true).unwrap();
bin.add_pad(&ghostpad).unwrap();
let ghostpad =
gst::GhostPad::with_target(Some("src"), &capsfilter.static_pad("src").unwrap())
.unwrap();
ghostpad.set_active(true).unwrap();
bin.add_pad(&ghostpad).unwrap();
bin.upcast()
}
fn create_audio_converts(
&self,
filter_caps: &gst::Caps,
fallback_source: bool,
) -> gst::Element {
if !fallback_source && filter_caps.is_any() {
return gst::ElementFactory::make("identity")
.build()
.expect("No identity found");
}
let bin = gst::Bin::new(None);
let audioconvert = gst::ElementFactory::make("audioconvert")
.name("audio_audioconvert")
.build()
.expect("No audioconvert found");
let audioresample = gst::ElementFactory::make("audioresample")
.name("audio_audioresample")
.build()
.expect("No audioresample found");
let capsfilter = gst::ElementFactory::make("capsfilter")
.name("audio_capsfilter")
.property("caps", filter_caps)
.build()
.expect("No capsfilter found");
bin.add_many(&[&audioconvert, &audioresample, &capsfilter])
.unwrap();
gst::Element::link_many(&[&audioconvert, &audioresample, &capsfilter]).unwrap();
let ghostpad =
gst::GhostPad::with_target(Some("sink"), &audioconvert.static_pad("sink").unwrap())
.unwrap();
ghostpad.set_active(true).unwrap();
bin.add_pad(&ghostpad).unwrap();
let ghostpad =
gst::GhostPad::with_target(Some("src"), &capsfilter.static_pad("src").unwrap())
.unwrap();
ghostpad.set_active(true).unwrap();
bin.add_pad(&ghostpad).unwrap();
bin.upcast()
}
fn handle_source_pad_added( fn handle_source_pad_added(
&self, &self,
pad: &gst::Pad, pad: &gst::Pad,
@ -1692,99 +1839,14 @@ impl FallbackSrc {
} }
}; };
let converters = if is_video { // Configure conversion elements only for fallback stream
let bin = gst::Bin::new(None); // (if fallback caps is not ANY) or image source.
let converters = if is_image {
let videoconvert = gst::ElementFactory::make("videoconvert") self.create_image_converts(filter_caps, fallback_source)
.name("video_videoconvert") } else if is_video {
.build() self.create_video_converts(filter_caps, fallback_source)
.expect("No videoconvert found");
let videoscale = gst::ElementFactory::make("videoscale")
.name("video_videoscale")
.build()
.expect("No videoscale found");
let capsfilter = gst::ElementFactory::make("capsfilter")
.name("video_capsfilter")
.build()
.expect("No capsfilter found");
let imagefreeze = if is_image {
gst::ElementFactory::make("imagefreeze")
.property("is-live", true)
.build()
.expect("no imagefreeze found")
} else {
gst::ElementFactory::make("identity")
.name("video_identity")
.build()
.expect("No identity found")
};
if fallback_source {
capsfilter.set_property("caps", filter_caps);
}
bin.add_many(&[&videoconvert, &videoscale, &imagefreeze, &capsfilter])
.unwrap();
gst::Element::link_many(&[&videoconvert, &videoscale, &imagefreeze, &capsfilter])
.unwrap();
let ghostpad =
gst::GhostPad::with_target(Some("sink"), &videoconvert.static_pad("sink").unwrap())
.unwrap();
ghostpad.set_active(true).unwrap();
bin.add_pad(&ghostpad).unwrap();
let ghostpad =
gst::GhostPad::with_target(Some("src"), &capsfilter.static_pad("src").unwrap())
.unwrap();
ghostpad.set_active(true).unwrap();
bin.add_pad(&ghostpad).unwrap();
bin.upcast()
} else { } else {
let bin = gst::Bin::new(None); self.create_audio_converts(filter_caps, fallback_source)
let audioconvert = gst::ElementFactory::make("audioconvert")
.name("audio_audioconvert")
.build()
.expect("No audioconvert found");
let audioresample = gst::ElementFactory::make("audioresample")
.name("audio_audioresample")
.build()
.expect("No audioresample found");
let capsfilter = gst::ElementFactory::make("capsfilter")
.name("audio_capsfilter")
.build()
.expect("No capsfilter found");
if fallback_source {
capsfilter.set_property("caps", filter_caps);
}
bin.add_many(&[&audioconvert, &audioresample, &capsfilter])
.unwrap();
gst::Element::link_many(&[&audioconvert, &audioresample, &capsfilter]).unwrap();
let ghostpad =
gst::GhostPad::with_target(Some("sink"), &audioconvert.static_pad("sink").unwrap())
.unwrap();
ghostpad.set_active(true).unwrap();
bin.add_pad(&ghostpad).unwrap();
let ghostpad =
gst::GhostPad::with_target(Some("src"), &capsfilter.static_pad("src").unwrap())
.unwrap();
ghostpad.set_active(true).unwrap();
bin.add_pad(&ghostpad).unwrap();
bin.upcast()
}; };
let queue = gst::ElementFactory::make("queue") let queue = gst::ElementFactory::make("queue")