mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-11-25 21:11:00 +00:00
uriplaylistbin: add properties reporting the current state of the playlist
This commit is contained in:
parent
9783d01a35
commit
b7c08933aa
2 changed files with 134 additions and 25 deletions
|
@ -7,7 +7,7 @@
|
|||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::sync::Mutex;
|
||||
use std::sync::{Mutex, MutexGuard};
|
||||
|
||||
use gst::glib;
|
||||
use gst::prelude::*;
|
||||
|
@ -123,6 +123,10 @@ struct State {
|
|||
streaming: Vec<Item>,
|
||||
// items which have been fully played, waiting to be cleaned up
|
||||
done: Vec<Item>,
|
||||
|
||||
// read-only properties
|
||||
current_iteration: u32,
|
||||
current_uri_index: u64,
|
||||
}
|
||||
|
||||
impl State {
|
||||
|
@ -141,6 +145,8 @@ impl State {
|
|||
blocked: None,
|
||||
streaming: vec![],
|
||||
done: vec![],
|
||||
current_iteration: 0,
|
||||
current_uri_index: 0,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -717,6 +723,24 @@ impl ObjectImpl for UriPlaylistBin {
|
|||
1,
|
||||
glib::ParamFlags::READWRITE | gst::PARAM_FLAG_MUTABLE_READY,
|
||||
),
|
||||
glib::ParamSpecUInt::new(
|
||||
"current-iteration",
|
||||
"Current iteration",
|
||||
"The index of the current playlist iteration, or 0 if the iterations property is 0 (unlimited playlist)",
|
||||
0,
|
||||
u32::MAX,
|
||||
0,
|
||||
glib::ParamFlags::READABLE,
|
||||
),
|
||||
glib::ParamSpecUInt64::new(
|
||||
"current-uri-index",
|
||||
"Current URI",
|
||||
"The index from the uris property of the current URI being played",
|
||||
0,
|
||||
u64::MAX,
|
||||
0,
|
||||
glib::ParamFlags::READABLE,
|
||||
),
|
||||
]
|
||||
});
|
||||
|
||||
|
@ -769,6 +793,22 @@ impl ObjectImpl for UriPlaylistBin {
|
|||
let settings = self.settings.lock().unwrap();
|
||||
settings.iterations.to_value()
|
||||
}
|
||||
"current-iteration" => {
|
||||
let state = self.state.lock().unwrap();
|
||||
state
|
||||
.as_ref()
|
||||
.map(|state| state.current_iteration)
|
||||
.unwrap_or(0)
|
||||
.to_value()
|
||||
}
|
||||
"current-uri-index" => {
|
||||
let state = self.state.lock().unwrap();
|
||||
state
|
||||
.as_ref()
|
||||
.map(|state| state.current_uri_index)
|
||||
.unwrap_or(0)
|
||||
.to_value()
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
@ -980,6 +1020,8 @@ impl UriPlaylistBin {
|
|||
// unblock last item
|
||||
state.unblock_item(element);
|
||||
|
||||
self.update_current(state_guard);
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
|
@ -1115,6 +1157,8 @@ impl UriPlaylistBin {
|
|||
}
|
||||
|
||||
state.waiting_for_stream_collection = None;
|
||||
|
||||
self.update_current(state_guard);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
@ -1431,6 +1475,8 @@ impl UriPlaylistBin {
|
|||
item.set_blocked();
|
||||
state.blocked = Some(item);
|
||||
|
||||
self.update_current(state_guard);
|
||||
|
||||
true
|
||||
} else {
|
||||
false
|
||||
|
@ -1571,5 +1617,40 @@ impl UriPlaylistBin {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
self.update_current(self.state.lock().unwrap());
|
||||
}
|
||||
|
||||
fn update_current(&self, mut state_guard: MutexGuard<Option<State>>) {
|
||||
let (uris_len, infinite) = {
|
||||
let settings = self.settings.lock().unwrap();
|
||||
|
||||
(settings.uris.len(), settings.iterations == 0)
|
||||
};
|
||||
|
||||
if let Some(state) = state_guard.as_mut() {
|
||||
// first streaming item is the one actually being played
|
||||
if let Some(current) = state.streaming.get(0) {
|
||||
let (mut current_iteration, current_uri_index) = (
|
||||
(current.index() / uris_len) as u32,
|
||||
(current.index() % uris_len) as u64,
|
||||
);
|
||||
|
||||
if infinite {
|
||||
current_iteration = 0;
|
||||
}
|
||||
|
||||
let element = self.instance();
|
||||
|
||||
if current_iteration != state.current_iteration {
|
||||
state.current_iteration = current_iteration;
|
||||
element.notify("current-iteration");
|
||||
}
|
||||
if current_uri_index != state.current_uri_index {
|
||||
state.current_uri_index = current_uri_index;
|
||||
element.notify("current-uri-index");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ fn test(
|
|||
n_streams: u32,
|
||||
iterations: u32,
|
||||
check_streams: bool,
|
||||
) -> Vec<gst::Message> {
|
||||
) -> (Vec<gst::Message>, u32, u64) {
|
||||
init();
|
||||
|
||||
let playlist_len = medias.len() * (iterations as usize);
|
||||
|
@ -99,6 +99,9 @@ fn test(
|
|||
playlist.set_property("uris", &uris);
|
||||
playlist.set_property("iterations", &iterations);
|
||||
|
||||
assert_eq!(playlist.property::<u32>("current-iteration"), 0);
|
||||
assert_eq!(playlist.property::<u64>("current-uri-index"), 0);
|
||||
|
||||
let mq_clone = mq.clone();
|
||||
playlist.connect_pad_added(move |_playlist, src_pad| {
|
||||
let mq_sink = mq_clone.request_pad_simple("sink_%u").unwrap();
|
||||
|
@ -185,9 +188,12 @@ fn test(
|
|||
}
|
||||
}
|
||||
|
||||
let current_iteration = playlist.property::<u32>("current-iteration");
|
||||
let current_uri_index = playlist.property::<u64>("current-uri-index");
|
||||
|
||||
pipeline.set_state(gst::State::Null).unwrap();
|
||||
|
||||
events
|
||||
(events, current_iteration, current_uri_index)
|
||||
}
|
||||
|
||||
fn assert_eos(msg: gst::Message) {
|
||||
|
@ -234,66 +240,88 @@ fn assert_stream_selected(msg: gst::Message, n_streams: usize) -> gst::Object {
|
|||
|
||||
#[test]
|
||||
fn single_audio() {
|
||||
let events = test(vec![TestMedia::ogg()], 1, 1, true).into_iter();
|
||||
assert_eos(events.last().unwrap());
|
||||
let (events, current_iteration, current_uri_index) = test(vec![TestMedia::ogg()], 1, 1, true);
|
||||
assert_eos(events.into_iter().last().unwrap());
|
||||
assert_eq!(current_iteration, 0);
|
||||
assert_eq!(current_uri_index, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn single_video() {
|
||||
let events = test(vec![TestMedia::mkv()], 2, 1, true).into_iter();
|
||||
assert_eos(events.last().unwrap());
|
||||
let (events, current_iteration, current_uri_index) = test(vec![TestMedia::mkv()], 2, 1, true);
|
||||
assert_eos(events.into_iter().last().unwrap());
|
||||
assert_eq!(current_iteration, 0);
|
||||
assert_eq!(current_uri_index, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multi_audio() {
|
||||
let events = test(
|
||||
let (events, current_iteration, current_uri_index) = test(
|
||||
vec![TestMedia::ogg(), TestMedia::ogg(), TestMedia::ogg()],
|
||||
1,
|
||||
1,
|
||||
true,
|
||||
)
|
||||
.into_iter();
|
||||
assert_eos(events.last().unwrap());
|
||||
);
|
||||
assert_eos(events.into_iter().last().unwrap());
|
||||
assert_eq!(current_iteration, 0);
|
||||
assert_eq!(current_uri_index, 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multi_audio_video() {
|
||||
let events = test(vec![TestMedia::mkv(), TestMedia::mkv()], 2, 1, true).into_iter();
|
||||
assert_eos(events.last().unwrap());
|
||||
let (events, current_iteration, current_uri_index) =
|
||||
test(vec![TestMedia::mkv(), TestMedia::mkv()], 2, 1, true);
|
||||
assert_eos(events.into_iter().last().unwrap());
|
||||
assert_eq!(current_iteration, 0);
|
||||
assert_eq!(current_uri_index, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn iterations() {
|
||||
let events = test(vec![TestMedia::mkv(), TestMedia::mkv()], 2, 2, true).into_iter();
|
||||
assert_eos(events.last().unwrap());
|
||||
let (events, current_iteration, current_uri_index) =
|
||||
test(vec![TestMedia::mkv(), TestMedia::mkv()], 2, 2, true);
|
||||
assert_eos(events.into_iter().last().unwrap());
|
||||
assert_eq!(current_iteration, 1);
|
||||
assert_eq!(current_uri_index, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nb_streams_increasing() {
|
||||
let events = test(vec![TestMedia::ogg(), TestMedia::mkv()], 2, 1, false).into_iter();
|
||||
assert_eos(events.last().unwrap());
|
||||
let (events, current_iteration, current_uri_index) =
|
||||
test(vec![TestMedia::ogg(), TestMedia::mkv()], 2, 1, false);
|
||||
assert_eos(events.into_iter().last().unwrap());
|
||||
assert_eq!(current_iteration, 0);
|
||||
assert_eq!(current_uri_index, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn missing_file() {
|
||||
let events = test(
|
||||
let (events, current_iteration, current_uri_index) = test(
|
||||
vec![TestMedia::ogg(), TestMedia::missing_file()],
|
||||
1,
|
||||
1,
|
||||
false,
|
||||
)
|
||||
.into_iter();
|
||||
assert_error(events.last().unwrap(), TestMedia::missing_file());
|
||||
);
|
||||
assert_error(
|
||||
events.into_iter().last().unwrap(),
|
||||
TestMedia::missing_file(),
|
||||
);
|
||||
assert_eq!(current_iteration, 0);
|
||||
assert_eq!(current_uri_index, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn missing_http() {
|
||||
let events = test(
|
||||
let (events, current_iteration, current_uri_index) = test(
|
||||
vec![TestMedia::ogg(), TestMedia::missing_http()],
|
||||
1,
|
||||
1,
|
||||
false,
|
||||
)
|
||||
.into_iter();
|
||||
assert_error(events.last().unwrap(), TestMedia::missing_http());
|
||||
);
|
||||
assert_error(
|
||||
events.into_iter().last().unwrap(),
|
||||
TestMedia::missing_http(),
|
||||
);
|
||||
assert_eq!(current_iteration, 0);
|
||||
assert_eq!(current_uri_index, 0);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue