fallbacksrc: Add fallback-{audio,video}-caps properties

Add new properties so that user can specify output raw audio and/or
video format of fallback stream (output of testsrc or still image)
This commit is contained in:
Seungha Yang 2022-05-26 02:46:46 +09:00 committed by Sebastian Dröge
parent a5dd92f479
commit 4072f1df34

View file

@ -70,6 +70,8 @@ struct Settings {
buffer_duration: i64, buffer_duration: i64,
immediate_fallback: bool, immediate_fallback: bool,
manual_unblock: bool, manual_unblock: bool,
fallback_video_caps: gst::Caps,
fallback_audio_caps: gst::Caps,
} }
impl Default for Settings { impl Default for Settings {
@ -88,6 +90,8 @@ impl Default for Settings {
buffer_duration: -1, buffer_duration: -1,
immediate_fallback: false, immediate_fallback: false,
manual_unblock: false, manual_unblock: false,
fallback_video_caps: gst::Caps::new_any(),
fallback_audio_caps: gst::Caps::new_any(),
} }
} }
} }
@ -116,6 +120,8 @@ struct Stream {
// for audio: live audiotestsrc, converters // for audio: live audiotestsrc, converters
fallback_input: gst::Element, fallback_input: gst::Element,
fallback_capsfilter: gst::Element,
// source pad from source // source pad from source
source_srcpad: Option<gst::Pad>, source_srcpad: Option<gst::Pad>,
source_srcpad_block: Option<Block>, source_srcpad_block: Option<Block>,
@ -304,6 +310,20 @@ impl ObjectImpl for FallbackSrc {
false, false,
glib::ParamFlags::READWRITE | gst::PARAM_FLAG_MUTABLE_READY, glib::ParamFlags::READWRITE | gst::PARAM_FLAG_MUTABLE_READY,
), ),
glib::ParamSpecBoxed::new(
"fallback-video-caps",
"Fallback Video Caps",
"Raw video caps for fallback stream",
gst::Caps::static_type(),
glib::ParamFlags::READWRITE | gst::PARAM_FLAG_MUTABLE_READY,
),
glib::ParamSpecBoxed::new(
"fallback-audio-caps",
"Fallback Audio Caps",
"Raw audio caps for fallback stream",
gst::Caps::static_type(),
glib::ParamFlags::READWRITE | gst::PARAM_FLAG_MUTABLE_READY,
),
] ]
}); });
@ -474,6 +494,36 @@ impl ObjectImpl for FallbackSrc {
); );
settings.manual_unblock = new_value; settings.manual_unblock = new_value;
} }
"fallback-video-caps" => {
let mut settings = self.settings.lock();
let new_value = value
.get::<Option<gst::Caps>>()
.expect("type checked upstream")
.unwrap_or_else(gst::Caps::new_any);
gst::info!(
CAT,
obj: obj,
"Changing fallback video caps from {} to {}",
settings.fallback_video_caps,
new_value,
);
settings.fallback_video_caps = new_value;
}
"fallback-audio-caps" => {
let mut settings = self.settings.lock();
let new_value = value
.get::<Option<gst::Caps>>()
.expect("type checked upstream")
.unwrap_or_else(gst::Caps::new_any);
gst::info!(
CAT,
obj: obj,
"Changing fallback audio caps from {} to {}",
settings.fallback_audio_caps,
new_value,
);
settings.fallback_audio_caps = new_value;
}
_ => unimplemented!(), _ => unimplemented!(),
} }
} }
@ -588,6 +638,14 @@ impl ObjectImpl for FallbackSrc {
let settings = self.settings.lock(); let settings = self.settings.lock();
settings.manual_unblock.to_value() settings.manual_unblock.to_value()
} }
"fallback-video-caps" => {
let settings = self.settings.lock();
settings.fallback_video_caps.to_value()
}
"fallback-audio-caps" => {
let settings = self.settings.lock();
settings.fallback_audio_caps.to_value()
}
_ => unimplemented!(), _ => unimplemented!(),
} }
} }
@ -894,6 +952,7 @@ impl FallbackSrc {
input.upcast() input.upcast()
} }
#[allow(clippy::too_many_arguments)]
fn create_stream( fn create_stream(
&self, &self,
element: &super::FallbackSrc, element: &super::FallbackSrc,
@ -902,6 +961,7 @@ impl FallbackSrc {
is_audio: bool, is_audio: bool,
fallback_uri: Option<&str>, fallback_uri: Option<&str>,
immediate_fallback: bool, immediate_fallback: bool,
fallback_caps: &gst::Caps,
) -> Stream { ) -> Stream {
let fallback_input = if is_audio { let fallback_input = if is_audio {
self.create_fallback_audio_input(element) self.create_fallback_audio_input(element)
@ -909,6 +969,10 @@ impl FallbackSrc {
self.create_fallback_video_input(element, min_latency, fallback_uri) self.create_fallback_video_input(element, min_latency, fallback_uri)
}; };
let fallback_capsfilter =
gst::ElementFactory::make("capsfilter", None).expect("No capsfilter found");
fallback_capsfilter.set_property("caps", fallback_caps);
let switch = let switch =
gst::ElementFactory::make("fallbackswitch", None).expect("No fallbackswitch found"); gst::ElementFactory::make("fallbackswitch", None).expect("No fallbackswitch found");
let clocksync = gst::ElementFactory::make("clocksync", None) let clocksync = gst::ElementFactory::make("clocksync", None)
@ -928,8 +992,15 @@ impl FallbackSrc {
]); ]);
element element
.add_many(&[&fallback_input, &switch, &clocksync_queue, &clocksync]) .add_many(&[
&fallback_input,
&fallback_capsfilter,
&switch,
&clocksync_queue,
&clocksync,
])
.unwrap(); .unwrap();
fallback_input.link(&fallback_capsfilter).unwrap();
switch.set_property("timeout", timeout.nseconds()); switch.set_property("timeout", timeout.nseconds());
switch.set_property("min-upstream-latency", min_latency.nseconds()); switch.set_property("min-upstream-latency", min_latency.nseconds());
@ -943,7 +1014,7 @@ impl FallbackSrc {
switch_mainsink.set_property("priority", 0u32); switch_mainsink.set_property("priority", 0u32);
// clocksync_queue sink pad is not connected to anything yet at this point! // clocksync_queue sink pad is not connected to anything yet at this point!
let fallback_srcpad = fallback_input.static_pad("src").unwrap(); let fallback_srcpad = fallback_capsfilter.static_pad("src").unwrap();
let switch_fallbacksink = switch.request_pad_simple("sink_%u").unwrap(); let switch_fallbacksink = switch.request_pad_simple("sink_%u").unwrap();
fallback_srcpad.link(&switch_fallbacksink).unwrap(); fallback_srcpad.link(&switch_fallbacksink).unwrap();
switch_fallbacksink.set_property("priority", 1u32); switch_fallbacksink.set_property("priority", 1u32);
@ -983,6 +1054,7 @@ impl FallbackSrc {
Stream { Stream {
fallback_input, fallback_input,
fallback_capsfilter,
source_srcpad: None, source_srcpad: None,
source_srcpad_block: None, source_srcpad_block: None,
clocksync, clocksync,
@ -1037,6 +1109,7 @@ impl FallbackSrc {
false, false,
fallback_uri.as_deref(), fallback_uri.as_deref(),
settings.immediate_fallback, settings.immediate_fallback,
&settings.fallback_video_caps,
); );
flow_combiner.add_pad(&stream.srcpad); flow_combiner.add_pad(&stream.srcpad);
Some(stream) Some(stream)
@ -1053,6 +1126,7 @@ impl FallbackSrc {
true, true,
None, None,
settings.immediate_fallback, settings.immediate_fallback,
&settings.fallback_audio_caps,
); );
flow_combiner.add_pad(&stream.srcpad); flow_combiner.add_pad(&stream.srcpad);
Some(stream) Some(stream)
@ -1112,6 +1186,7 @@ impl FallbackSrc {
element.remove(&stream.switch).unwrap(); element.remove(&stream.switch).unwrap();
element.remove(&stream.clocksync_queue).unwrap(); element.remove(&stream.clocksync_queue).unwrap();
element.remove(&stream.clocksync).unwrap(); element.remove(&stream.clocksync).unwrap();
element.remove(&stream.fallback_capsfilter).unwrap();
element.remove(&stream.fallback_input).unwrap(); element.remove(&stream.fallback_input).unwrap();
let _ = stream.srcpad.set_target(None::<&gst::Pad>); let _ = stream.srcpad.set_target(None::<&gst::Pad>);
let _ = element.remove_pad(&stream.srcpad); let _ = element.remove_pad(&stream.srcpad);