Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMathieu Duponchelle <mathieu@centricular.com>2021-06-04 02:29:09 +0300
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>2021-06-30 03:46:46 +0300
commitd38a84ab799117c3dae07e7451de32929b560af9 (patch)
tree6779b5912b81ea844c94f78fadf37805a56c8460
parentef41adf776830eeb54ad21505fafb8ad7fc931e7 (diff)
fallbacksrc: add support for still images as primary
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/515>
-rw-r--r--utils/fallbackswitch/src/fallbacksrc/imp.rs71
1 files changed, 69 insertions, 2 deletions
diff --git a/utils/fallbackswitch/src/fallbacksrc/imp.rs b/utils/fallbackswitch/src/fallbacksrc/imp.rs
index a6e6a9b77..1f2b87f5a 100644
--- a/utils/fallbackswitch/src/fallbacksrc/imp.rs
+++ b/utils/fallbackswitch/src/fallbacksrc/imp.rs
@@ -179,6 +179,8 @@ struct State {
// So that we don't schedule a restart when manually unblocking
// and our source hasn't reached the required state
schedule_restart_on_unblock: bool,
+
+ is_image: bool,
}
#[derive(Default)]
@@ -1089,6 +1091,7 @@ impl FallbackSrc {
stats: Stats::default(),
manually_blocked,
schedule_restart_on_unblock: false,
+ is_image: false,
});
drop(state_guard);
@@ -1261,6 +1264,39 @@ impl FallbackSrc {
Some(state) => state,
};
+ let mut is_image = false;
+
+ if let Some(stream_event) = pad.sticky_event(gst::EventType::StreamStart, 0) {
+ let stream = match stream_event.view() {
+ gst::EventView::StreamStart(ref ev) => ev.stream(),
+ _ => unreachable!(),
+ };
+
+ if let Some(stream) = stream {
+ if let Some(caps) = stream.caps() {
+ if let Some(s) = caps.structure(0) {
+ is_image = s.name().starts_with("image/");
+ }
+ }
+ }
+ }
+
+ if is_image {
+ if let Some(timeout) = state.source_pending_restart_timeout.take() {
+ timeout.unschedule();
+ }
+
+ if let Some(timeout) = state.source_retry_timeout.take() {
+ timeout.unschedule();
+ }
+
+ if let Some(timeout) = state.source_restart_timeout.take() {
+ timeout.unschedule();
+ }
+ }
+
+ state.is_image |= is_image;
+
let (is_video, stream) = match pad.name() {
x if x.starts_with("audio_") => (false, &mut state.audio_stream),
x if x.starts_with("video_") => (true, &mut state.video_stream),
@@ -1300,7 +1336,26 @@ impl FallbackSrc {
Some(ref mut stream) => stream,
};
- let sinkpad = stream.clocksync_queue.static_pad("sink").unwrap();
+ let sinkpad = if is_image {
+ let imagefreeze =
+ gst::ElementFactory::make("imagefreeze", None).expect("no imagefreeze found");
+
+ gst_debug!(CAT, "image stream, inserting imagefreeze");
+ element.add(&imagefreeze).unwrap();
+ imagefreeze.set_property("is-live", &true).unwrap();
+ if imagefreeze.sync_state_with_parent().is_err() {
+ gst_error!(CAT, obj: element, "imagefreeze failed to change state",);
+ return Err(gst::error_msg!(
+ gst::CoreError::StateChange,
+ ["Failed to change imagefreeze state"]
+ ));
+ }
+ imagefreeze.link(&stream.clocksync_queue).unwrap();
+ imagefreeze.static_pad("sink").unwrap()
+ } else {
+ stream.clocksync_queue.static_pad("sink").unwrap()
+ };
+
pad.link(&sinkpad).map_err(|err| {
gst_error!(
CAT,
@@ -1339,7 +1394,10 @@ impl FallbackSrc {
}
Some(state) => state,
};
- if state.settings.restart_on_eos {
+
+ if is_image {
+ gst::PadProbeReturn::Ok
+ } else if state.settings.restart_on_eos {
src.handle_source_error(&element, state, RetryReason::Eos);
drop(state_guard);
element.notify("statistics");
@@ -2226,6 +2284,15 @@ impl FallbackSrc {
return;
}
+ if state.is_image {
+ gst_debug!(
+ CAT,
+ obj: element,
+ "Not scheduling source restart timeout because we are playing back an image",
+ );
+ return;
+ }
+
if state.manually_blocked {
gst_debug!(
CAT,