2020-12-15 10:53:31 +00:00
|
|
|
// Take a look at the license at the top of the repository in the LICENSE file.
|
2017-08-08 20:37:48 +00:00
|
|
|
|
|
|
|
use std::ffi::CStr;
|
2018-02-20 16:57:51 +00:00
|
|
|
use std::fmt;
|
2017-08-08 20:37:48 +00:00
|
|
|
use std::mem;
|
|
|
|
|
2018-07-27 10:36:40 +00:00
|
|
|
use glib::translate::{
|
|
|
|
from_glib, from_glib_full, from_glib_none, FromGlibPtrContainer, ToGlib, ToGlibPtr,
|
|
|
|
};
|
2017-08-08 20:37:48 +00:00
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
use crate::TagList;
|
|
|
|
use crate::TagMergeMode;
|
|
|
|
use crate::TocEntryType;
|
|
|
|
use crate::TocLoopType;
|
|
|
|
use crate::TocScope;
|
2017-08-08 20:37:48 +00:00
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
gst_define_mini_object_wrapper!(Toc, TocRef, ffi::GstToc, || { ffi::gst_toc_get_type() });
|
2017-08-08 20:37:48 +00:00
|
|
|
|
2018-09-28 15:11:46 +00:00
|
|
|
impl Toc {
|
2017-08-08 20:37:48 +00:00
|
|
|
pub fn new(scope: TocScope) -> Self {
|
|
|
|
assert_initialized_main_thread!();
|
2020-11-21 13:46:48 +00:00
|
|
|
unsafe { from_glib_full(ffi::gst_toc_new(scope.to_glib())) }
|
2017-08-08 20:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl TocRef {
|
|
|
|
pub fn get_scope(&self) -> TocScope {
|
2020-11-21 13:46:48 +00:00
|
|
|
unsafe { from_glib(ffi::gst_toc_get_scope(self.as_ptr())) }
|
2017-08-08 20:37:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn find_entry(&self, uid: &str) -> Option<TocEntry> {
|
2020-11-21 13:46:48 +00:00
|
|
|
unsafe { from_glib_none(ffi::gst_toc_find_entry(self.as_ptr(), uid.to_glib_none().0)) }
|
2017-08-08 20:37:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_entries(&self) -> Vec<TocEntry> {
|
2020-11-21 13:46:48 +00:00
|
|
|
unsafe { FromGlibPtrContainer::from_glib_none(ffi::gst_toc_get_entries(self.as_ptr())) }
|
2017-08-08 20:37:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn append_entry(&mut self, entry: TocEntry) {
|
|
|
|
unsafe {
|
2020-11-21 13:46:48 +00:00
|
|
|
ffi::gst_toc_append_entry(self.as_mut_ptr(), entry.into_ptr());
|
2017-08-08 20:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_tags(&self) -> Option<TagList> {
|
2020-11-21 13:46:48 +00:00
|
|
|
unsafe { from_glib_none(ffi::gst_toc_get_tags(self.as_ptr())) }
|
2017-08-08 20:37:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn set_tags(&mut self, tag_list: TagList) {
|
|
|
|
unsafe {
|
2020-11-21 13:46:48 +00:00
|
|
|
ffi::gst_toc_set_tags(self.as_mut_ptr(), tag_list.into_ptr());
|
2017-08-08 20:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-26 21:58:02 +00:00
|
|
|
pub fn merge_tags(&mut self, tag_list: &TagList, mode: TagMergeMode) {
|
2017-08-08 20:37:48 +00:00
|
|
|
unsafe {
|
2020-11-21 13:46:48 +00:00
|
|
|
ffi::gst_toc_merge_tags(self.as_mut_ptr(), tag_list.as_mut_ptr(), mode.to_glib());
|
2017-08-08 20:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn dump(&self) {
|
|
|
|
unsafe {
|
2020-11-21 13:46:48 +00:00
|
|
|
ffi::gst_toc_dump(self.as_mut_ptr());
|
2017-08-08 20:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-29 21:12:46 +00:00
|
|
|
impl fmt::Debug for Toc {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
TocRef::fmt(self, f)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-20 16:57:51 +00:00
|
|
|
impl fmt::Debug for TocRef {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
f.debug_struct("Toc")
|
|
|
|
.field("scope", &self.get_scope())
|
|
|
|
.field("tags", &self.get_tags())
|
|
|
|
.field("entries", &self.get_entries())
|
|
|
|
.finish()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
gst_define_mini_object_wrapper!(TocEntry, TocEntryRef, ffi::GstTocEntry, || {
|
|
|
|
ffi::gst_toc_entry_get_type()
|
2020-06-29 21:12:46 +00:00
|
|
|
});
|
2017-08-08 20:37:48 +00:00
|
|
|
|
2018-09-28 15:11:46 +00:00
|
|
|
impl TocEntry {
|
2017-08-08 20:37:48 +00:00
|
|
|
pub fn new(type_: TocEntryType, uid: &str) -> Self {
|
|
|
|
assert_initialized_main_thread!();
|
|
|
|
unsafe {
|
2020-11-21 13:46:48 +00:00
|
|
|
from_glib_full(ffi::gst_toc_entry_new(
|
2017-08-08 20:37:48 +00:00
|
|
|
type_.to_glib(),
|
|
|
|
uid.to_glib_none().0,
|
|
|
|
))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl TocEntryRef {
|
|
|
|
pub fn get_entry_type(&self) -> TocEntryType {
|
2020-11-21 13:46:48 +00:00
|
|
|
unsafe { from_glib(ffi::gst_toc_entry_get_entry_type(self.as_ptr())) }
|
2017-08-08 20:37:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_uid(&self) -> &str {
|
|
|
|
unsafe {
|
2020-11-21 13:46:48 +00:00
|
|
|
CStr::from_ptr(ffi::gst_toc_entry_get_uid(self.as_ptr()))
|
2017-08-08 20:37:48 +00:00
|
|
|
.to_str()
|
|
|
|
.unwrap()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn append_sub_entry(&mut self, subentry: TocEntry) {
|
|
|
|
unsafe {
|
2020-11-21 13:46:48 +00:00
|
|
|
ffi::gst_toc_entry_append_sub_entry(self.as_mut_ptr(), subentry.into_ptr());
|
2017-08-08 20:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_sub_entries(&self) -> Vec<TocEntry> {
|
|
|
|
unsafe {
|
2020-11-21 13:46:48 +00:00
|
|
|
FromGlibPtrContainer::from_glib_none(ffi::gst_toc_entry_get_sub_entries(self.as_ptr()))
|
2017-08-08 20:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_parent(&self) -> Option<TocEntry> {
|
2020-11-21 13:46:48 +00:00
|
|
|
unsafe { from_glib_none(ffi::gst_toc_entry_get_parent(self.as_mut_ptr())) }
|
2017-08-08 20:37:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_start_stop_times(&self) -> Option<(i64, i64)> {
|
|
|
|
unsafe {
|
2019-07-11 12:34:28 +00:00
|
|
|
let mut start = mem::MaybeUninit::uninit();
|
|
|
|
let mut stop = mem::MaybeUninit::uninit();
|
2017-08-08 20:37:48 +00:00
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
if from_glib(ffi::gst_toc_entry_get_start_stop_times(
|
2017-08-08 20:37:48 +00:00
|
|
|
self.as_ptr(),
|
2019-07-11 12:34:28 +00:00
|
|
|
start.as_mut_ptr(),
|
|
|
|
stop.as_mut_ptr(),
|
2017-08-08 20:37:48 +00:00
|
|
|
)) {
|
2019-07-11 12:34:28 +00:00
|
|
|
Some((start.assume_init(), stop.assume_init()))
|
2017-08-08 20:37:48 +00:00
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn set_start_stop_times(&mut self, start: i64, stop: i64) {
|
|
|
|
unsafe {
|
2020-11-21 13:46:48 +00:00
|
|
|
ffi::gst_toc_entry_set_start_stop_times(self.as_mut_ptr(), start, stop);
|
2017-08-08 20:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_tags(&self) -> Option<TagList> {
|
2020-11-21 13:46:48 +00:00
|
|
|
unsafe { from_glib_none(ffi::gst_toc_entry_get_tags(self.as_ptr())) }
|
2017-08-08 20:37:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn set_tags(&mut self, tag_list: TagList) {
|
|
|
|
unsafe {
|
2020-11-21 13:46:48 +00:00
|
|
|
ffi::gst_toc_entry_set_tags(self.as_mut_ptr(), tag_list.into_ptr());
|
2017-08-08 20:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-26 21:58:02 +00:00
|
|
|
pub fn merge_tags(&mut self, tag_list: &TagList, mode: TagMergeMode) {
|
2017-08-08 20:37:48 +00:00
|
|
|
unsafe {
|
2020-11-21 13:46:48 +00:00
|
|
|
ffi::gst_toc_entry_merge_tags(self.as_mut_ptr(), tag_list.as_mut_ptr(), mode.to_glib());
|
2017-08-08 20:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_alternative(&self) -> bool {
|
2020-11-21 13:46:48 +00:00
|
|
|
unsafe { from_glib(ffi::gst_toc_entry_is_alternative(self.as_ptr())) }
|
2017-08-08 20:37:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_sequence(&self) -> bool {
|
2020-11-21 13:46:48 +00:00
|
|
|
unsafe { from_glib(ffi::gst_toc_entry_is_sequence(self.as_ptr())) }
|
2017-08-08 20:37:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_loop(&self) -> Option<(TocLoopType, i32)> {
|
|
|
|
unsafe {
|
2019-07-11 12:34:28 +00:00
|
|
|
let mut loop_type = mem::MaybeUninit::uninit();
|
|
|
|
let mut repeat_count = mem::MaybeUninit::uninit();
|
2020-11-21 13:46:48 +00:00
|
|
|
if from_glib(ffi::gst_toc_entry_get_loop(
|
2017-08-08 20:37:48 +00:00
|
|
|
self.as_ptr(),
|
2019-07-11 12:34:28 +00:00
|
|
|
loop_type.as_mut_ptr(),
|
|
|
|
repeat_count.as_mut_ptr(),
|
2017-08-08 20:37:48 +00:00
|
|
|
)) {
|
2019-07-11 12:34:28 +00:00
|
|
|
Some((
|
|
|
|
from_glib(loop_type.assume_init()),
|
|
|
|
repeat_count.assume_init(),
|
|
|
|
))
|
2017-08-08 20:37:48 +00:00
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn set_loop(&mut self, loop_type: TocLoopType, repeat_count: i32) {
|
|
|
|
unsafe {
|
2020-11-21 13:46:48 +00:00
|
|
|
ffi::gst_toc_entry_set_loop(self.as_mut_ptr(), loop_type.to_glib(), repeat_count);
|
2017-08-08 20:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-29 21:12:46 +00:00
|
|
|
impl fmt::Debug for TocEntry {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
TocEntryRef::fmt(self, f)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-20 16:57:51 +00:00
|
|
|
impl fmt::Debug for TocEntryRef {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
f.debug_struct("TocEntry")
|
|
|
|
.field("entry_type", &self.get_entry_type())
|
|
|
|
.field("uid", &self.get_uid())
|
|
|
|
.field("start_stop", &self.get_start_stop_times())
|
|
|
|
.field("tags", &self.get_tags())
|
|
|
|
.field("is_alternative", &self.is_alternative())
|
|
|
|
.field("is_sequence", &self.is_sequence())
|
|
|
|
.field("loop", &self.get_loop())
|
|
|
|
.field("sub_entries", &self.get_sub_entries())
|
|
|
|
.finish()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-08 20:37:48 +00:00
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_simple() {
|
2020-11-21 13:46:48 +00:00
|
|
|
crate::init().unwrap();
|
2017-08-08 20:37:48 +00:00
|
|
|
|
|
|
|
// Top level toc entry
|
|
|
|
let mut toc_entry = TocEntry::new(TocEntryType::Chapter, "chapter");
|
|
|
|
toc_entry.get_mut().unwrap().set_start_stop_times(1, 10);
|
|
|
|
|
|
|
|
// Toc sub entry
|
|
|
|
let toc_sub_entry = TocEntry::new(TocEntryType::Angle, "angle");
|
|
|
|
let parent = toc_sub_entry.get_parent();
|
|
|
|
assert!(parent.is_none());
|
|
|
|
|
|
|
|
// Append sub entry
|
|
|
|
toc_entry.get_mut().unwrap().append_sub_entry(toc_sub_entry);
|
|
|
|
|
|
|
|
// Toc
|
|
|
|
let mut toc = Toc::new(TocScope::Global);
|
|
|
|
assert_eq!(toc.get_scope(), TocScope::Global);
|
|
|
|
|
|
|
|
// Append toc entry
|
|
|
|
toc.get_mut().unwrap().append_entry(toc_entry);
|
|
|
|
assert_eq!(toc.get_scope(), TocScope::Global);
|
|
|
|
|
|
|
|
// Check toc entries
|
|
|
|
let toc_entries = toc.get_entries();
|
|
|
|
assert_eq!(toc_entries.len(), 1);
|
|
|
|
|
|
|
|
let toc_parent_entry = &toc_entries[0];
|
|
|
|
assert_eq!(toc_parent_entry.get_entry_type(), TocEntryType::Chapter);
|
|
|
|
assert_eq!(toc_parent_entry.get_uid(), "chapter");
|
|
|
|
let start_stop_times = toc_parent_entry.get_start_stop_times();
|
|
|
|
assert!(start_stop_times.is_some());
|
|
|
|
assert_eq!(start_stop_times.unwrap(), (1, 10));
|
|
|
|
|
|
|
|
// Check sub entry
|
|
|
|
let toc_sub_entries = toc_parent_entry.get_sub_entries();
|
|
|
|
assert_eq!(toc_sub_entries.len(), 1);
|
|
|
|
let toc_sub_entry = &toc_sub_entries[0];
|
|
|
|
assert_eq!(toc_sub_entry.get_entry_type(), TocEntryType::Angle);
|
|
|
|
let parent = toc_sub_entry.get_parent();
|
|
|
|
assert!(parent.is_some());
|
|
|
|
assert_eq!(parent.unwrap().get_entry_type(), TocEntryType::Chapter);
|
|
|
|
}
|
|
|
|
}
|