mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2025-02-16 21:05:15 +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",
|
"return-type": "GOutputStream",
|
||||||
"when": "last"
|
"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();
|
let mut state = self.state.lock().unwrap();
|
||||||
if let Some(mut context) = state.context.take() {
|
if let Some(mut context) = state.context.take() {
|
||||||
if context.playlist.is_rendering() {
|
if context.playlist.is_rendering() {
|
||||||
|
|
|
@ -27,6 +27,7 @@ const DEFAULT_SYNC: bool = true;
|
||||||
const DEFAULT_LATENCY: gst::ClockTime =
|
const DEFAULT_LATENCY: gst::ClockTime =
|
||||||
gst::ClockTime::from_mseconds((DEFAULT_TARGET_DURATION * 500) as u64);
|
gst::ClockTime::from_mseconds((DEFAULT_TARGET_DURATION * 500) as u64);
|
||||||
const SIGNAL_GET_INIT_STREAM: &str = "get-init-stream";
|
const SIGNAL_GET_INIT_STREAM: &str = "get-init-stream";
|
||||||
|
const SIGNAL_NEW_PLAYLIST: &str = "new-playlist";
|
||||||
|
|
||||||
static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
|
static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
|
||||||
gst::DebugCategory::new(
|
gst::DebugCategory::new(
|
||||||
|
@ -208,7 +209,8 @@ impl ObjectImpl for HlsCmafSink {
|
||||||
|
|
||||||
fn signals() -> &'static [glib::subclass::Signal] {
|
fn signals() -> &'static [glib::subclass::Signal] {
|
||||||
static SIGNALS: Lazy<Vec<glib::subclass::Signal>> = Lazy::new(|| {
|
static SIGNALS: Lazy<Vec<glib::subclass::Signal>> = Lazy::new(|| {
|
||||||
vec![glib::subclass::Signal::builder(SIGNAL_GET_INIT_STREAM)
|
vec![
|
||||||
|
glib::subclass::Signal::builder(SIGNAL_GET_INIT_STREAM)
|
||||||
.param_types([String::static_type()])
|
.param_types([String::static_type()])
|
||||||
.return_type::<Option<gio::OutputStream>>()
|
.return_type::<Option<gio::OutputStream>>()
|
||||||
.class_handler(|_, args| {
|
.class_handler(|_, args| {
|
||||||
|
@ -223,7 +225,44 @@ impl ObjectImpl for HlsCmafSink {
|
||||||
*ret = value.clone();
|
*ret = value.clone();
|
||||||
false
|
false
|
||||||
})
|
})
|
||||||
.build()]
|
.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()
|
SIGNALS.as_ref()
|
||||||
|
|
Loading…
Reference in a new issue