mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-11-22 03:21:00 +00:00
hlscmafsink: Add new-playlist signal
Allows you to switch output between folders without having to state change to READY to close the current playlist. Closes the current playlist immediately and starts a new one at the currently set location. Should be used after changing the relevant location properties. Makes use of the send-headers signal in cmafmux. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1692>
This commit is contained in:
parent
798936afc9
commit
c4bcdea830
3 changed files with 61 additions and 16 deletions
|
@ -2867,6 +2867,12 @@
|
|||
],
|
||||
"return-type": "GOutputStream",
|
||||
"when": "last"
|
||||
},
|
||||
"new-playlist": {
|
||||
"action": true,
|
||||
"args": [],
|
||||
"return-type": "void",
|
||||
"when": "last"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -307,7 +307,7 @@ impl HlsBaseSink {
|
|||
});
|
||||
}
|
||||
|
||||
fn close_playlist(&self) {
|
||||
pub fn close_playlist(&self) {
|
||||
let mut state = self.state.lock().unwrap();
|
||||
if let Some(mut context) = state.context.take() {
|
||||
if context.playlist.is_rendering() {
|
||||
|
|
|
@ -27,6 +27,7 @@ const DEFAULT_SYNC: bool = true;
|
|||
const DEFAULT_LATENCY: gst::ClockTime =
|
||||
gst::ClockTime::from_mseconds((DEFAULT_TARGET_DURATION * 500) as u64);
|
||||
const SIGNAL_GET_INIT_STREAM: &str = "get-init-stream";
|
||||
const SIGNAL_NEW_PLAYLIST: &str = "new-playlist";
|
||||
|
||||
static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
|
||||
gst::DebugCategory::new(
|
||||
|
@ -208,22 +209,60 @@ impl ObjectImpl for HlsCmafSink {
|
|||
|
||||
fn signals() -> &'static [glib::subclass::Signal] {
|
||||
static SIGNALS: Lazy<Vec<glib::subclass::Signal>> = Lazy::new(|| {
|
||||
vec![glib::subclass::Signal::builder(SIGNAL_GET_INIT_STREAM)
|
||||
.param_types([String::static_type()])
|
||||
.return_type::<Option<gio::OutputStream>>()
|
||||
.class_handler(|_, args| {
|
||||
let elem = args[0].get::<HlsBaseSink>().expect("signal arg");
|
||||
let init_location = args[1].get::<String>().expect("signal arg");
|
||||
let imp = elem.imp();
|
||||
vec![
|
||||
glib::subclass::Signal::builder(SIGNAL_GET_INIT_STREAM)
|
||||
.param_types([String::static_type()])
|
||||
.return_type::<Option<gio::OutputStream>>()
|
||||
.class_handler(|_, args| {
|
||||
let elem = args[0].get::<HlsBaseSink>().expect("signal arg");
|
||||
let init_location = args[1].get::<String>().expect("signal arg");
|
||||
let imp = elem.imp();
|
||||
|
||||
Some(imp.new_file_stream(&init_location).ok().to_value())
|
||||
})
|
||||
.accumulator(|_hint, ret, value| {
|
||||
// First signal handler wins
|
||||
*ret = value.clone();
|
||||
false
|
||||
})
|
||||
.build()]
|
||||
Some(imp.new_file_stream(&init_location).ok().to_value())
|
||||
})
|
||||
.accumulator(|_hint, ret, value| {
|
||||
// First signal handler wins
|
||||
*ret = value.clone();
|
||||
false
|
||||
})
|
||||
.build(),
|
||||
glib::subclass::Signal::builder(SIGNAL_NEW_PLAYLIST)
|
||||
.action()
|
||||
.class_handler(|_token, args| {
|
||||
// Forces hlscmafsink to finish the current playlist and start a new one.
|
||||
// Meant to be used after changing output location at runtime, which would
|
||||
// otherwise require changing playback state to READY to make sure that the
|
||||
// old playlist is closed correctly and new init segment is written.
|
||||
let elem = args[0].get::<super::HlsCmafSink>().expect("signal arg");
|
||||
let imp = elem.imp();
|
||||
|
||||
gst::debug!(
|
||||
CAT,
|
||||
imp = imp,
|
||||
"Closing current playlist and starting a new one"
|
||||
);
|
||||
base_imp!(imp).close_playlist();
|
||||
|
||||
let (target_duration, playlist_type, segment_template, cmafmux) = {
|
||||
let settings = imp.settings.lock().unwrap();
|
||||
(
|
||||
settings.target_duration,
|
||||
settings.playlist_type.clone(),
|
||||
settings.location.clone(),
|
||||
settings.cmafmux.clone(),
|
||||
)
|
||||
};
|
||||
|
||||
let playlist = imp.start(target_duration, playlist_type);
|
||||
base_imp!(imp).open_playlist(playlist, segment_template);
|
||||
|
||||
// This forces cmafmux to send the init headers again.
|
||||
cmafmux.emit_by_name::<()>("send-headers", &[]);
|
||||
|
||||
None
|
||||
})
|
||||
.build(),
|
||||
]
|
||||
});
|
||||
|
||||
SIGNALS.as_ref()
|
||||
|
|
Loading…
Reference in a new issue