Rework ClockTime & FormattedValues

This commit is contained in:
François Laignel 2020-10-27 18:27:16 +01:00
parent 8dda8def6e
commit 90bb458e64
35 changed files with 1389 additions and 1224 deletions

View file

@ -56,7 +56,7 @@ fn print_discoverer_info(info: &DiscovererInfo) -> Result<(), Error> {
.uri()
.ok_or(DiscovererError("URI should not be null"))?;
println!("URI: {}", uri);
println!("Duration: {}", info.duration());
println!("Duration: {}", info.duration().display());
print_tags(info);
print_stream_info(
&info

View file

@ -89,9 +89,7 @@ fn create_ui(app: &gtk::Application) {
};
// Query the current playing position from the underlying pipeline.
let position = pipeline
.query_position::<gst::ClockTime>()
.unwrap_or_else(|| 0.into());
let position = pipeline.query_position::<gst::ClockTime>();
// Display the playing position in the gui.
label.set_text(&format!("Position: {:.0}", position));
// Tell the callback to continue calling this closure.

View file

@ -194,9 +194,7 @@ fn create_ui(app: &gtk::Application) {
};
// Query the current playing position from the underlying pipeline.
let position = pipeline
.query_position::<gst::ClockTime>()
.unwrap_or_else(|| 0.into());
let position = pipeline.query_position::<gst::ClockTime>();
// Display the playing position in the gui.
label.set_text(&format!("Position: {:.0}", position));
// Tell the timeout to continue calling this callback.

View file

@ -351,25 +351,25 @@ impl BufferRef {
}
#[doc(alias = "get_pts")]
pub fn pts(&self) -> ClockTime {
pub fn pts(&self) -> Option<ClockTime> {
unsafe { from_glib(self.0.pts) }
}
pub fn set_pts(&mut self, pts: ClockTime) {
self.0.pts = pts.into_glib();
pub fn set_pts(&mut self, pts: impl Into<Option<ClockTime>>) {
self.0.pts = pts.into().into_glib();
}
#[doc(alias = "get_dts")]
pub fn dts(&self) -> ClockTime {
pub fn dts(&self) -> Option<ClockTime> {
unsafe { from_glib(self.0.dts) }
}
pub fn set_dts(&mut self, dts: ClockTime) {
self.0.dts = dts.into_glib();
pub fn set_dts(&mut self, dts: impl Into<Option<ClockTime>>) {
self.0.dts = dts.into().into_glib();
}
#[doc(alias = "get_dts_or_pts")]
pub fn dts_or_pts(&self) -> ClockTime {
pub fn dts_or_pts(&self) -> Option<ClockTime> {
let val = self.dts();
if val.is_none() {
self.pts()
@ -379,12 +379,12 @@ impl BufferRef {
}
#[doc(alias = "get_duration")]
pub fn duration(&self) -> ClockTime {
pub fn duration(&self) -> Option<ClockTime> {
unsafe { from_glib(self.0.duration) }
}
pub fn set_duration(&mut self, duration: ClockTime) {
self.0.duration = duration.into_glib();
pub fn set_duration(&mut self, duration: impl Into<Option<ClockTime>>) {
self.0.duration = duration.into().into_glib();
}
#[doc(alias = "get_flags")]
@ -926,6 +926,7 @@ impl Eq for Buffer {}
impl fmt::Debug for BufferRef {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use crate::utils::Displayable;
use std::cell::RefCell;
struct DebugIter<I>(RefCell<I>);
@ -940,9 +941,9 @@ impl fmt::Debug for BufferRef {
f.debug_struct("Buffer")
.field("ptr", unsafe { &self.as_ptr() })
.field("pts", &self.pts().to_string())
.field("dts", &self.dts().to_string())
.field("duration", &self.duration().to_string())
.field("pts", &self.pts().display().to_string())
.field("dts", &self.dts().display().to_string())
.field("duration", &self.duration().display().to_string())
.field("size", &self.size())
.field("offset", &self.offset())
.field("offset_end", &self.offset_end())
@ -1149,17 +1150,17 @@ mod tests {
{
let buffer = buffer.get_mut().unwrap();
buffer.set_pts(1.into());
buffer.set_dts(2.into());
buffer.set_pts(ClockTime::NSECOND);
buffer.set_dts(2 * ClockTime::NSECOND);
buffer.set_offset(3);
buffer.set_offset_end(4);
buffer.set_duration(5.into());
buffer.set_duration(Some(5 * ClockTime::NSECOND));
}
assert_eq!(buffer.pts(), 1.into());
assert_eq!(buffer.dts(), 2.into());
assert_eq!(buffer.pts(), Some(ClockTime::NSECOND));
assert_eq!(buffer.dts(), Some(2 * ClockTime::NSECOND));
assert_eq!(buffer.offset(), 3);
assert_eq!(buffer.offset_end(), 4);
assert_eq!(buffer.duration(), 5.into());
assert_eq!(buffer.duration(), Some(5 * ClockTime::NSECOND));
}
#[test]
@ -1174,7 +1175,7 @@ mod tests {
assert_ne!(buffer.get_mut(), None);
{
let buffer = buffer.get_mut().unwrap();
buffer.set_pts(1.into());
buffer.set_pts(Some(ClockTime::NSECOND));
}
let mut buffer2 = buffer.clone();
@ -1190,15 +1191,15 @@ mod tests {
assert_ne!(buffer2.as_ptr(), buffer.as_ptr());
}
buffer2.set_pts(2.into());
buffer2.set_pts(Some(2 * ClockTime::NSECOND));
let mut data = buffer2.map_writable().unwrap();
assert_eq!(data.as_slice(), vec![1, 2, 3, 4].as_slice());
data.as_mut_slice()[0] = 0;
}
assert_eq!(buffer.pts(), 1.into());
assert_eq!(buffer2.pts(), 2.into());
assert_eq!(buffer.pts(), Some(ClockTime::NSECOND));
assert_eq!(buffer2.pts(), Some(2 * ClockTime::NSECOND));
{
let data = buffer.map_readable().unwrap();
@ -1331,14 +1332,14 @@ mod tests {
crate::ReferenceTimestampMeta::add(
buffer,
&crate::Caps::builder("foo/bar").build(),
crate::ClockTime::from(0),
crate::CLOCK_TIME_NONE,
ClockTime::ZERO,
ClockTime::NONE,
);
crate::ReferenceTimestampMeta::add(
buffer,
&crate::Caps::builder("foo/bar").build(),
crate::SECOND,
crate::CLOCK_TIME_NONE,
ClockTime::SECOND,
ClockTime::NONE,
);
}
@ -1351,7 +1352,10 @@ mod tests {
true
});
assert_eq!(&[crate::ClockTime::from(0), crate::SECOND][..], &res[..]);
assert_eq!(
&[Some(ClockTime::ZERO), Some(ClockTime::SECOND)][..],
&res[..]
);
}
#[cfg(any(feature = "v1_14", feature = "dox"))]
@ -1366,14 +1370,14 @@ mod tests {
crate::ReferenceTimestampMeta::add(
buffer,
&crate::Caps::builder("foo/bar").build(),
crate::ClockTime::from(0),
crate::CLOCK_TIME_NONE,
ClockTime::ZERO,
ClockTime::NONE,
);
crate::ReferenceTimestampMeta::add(
buffer,
&crate::Caps::builder("foo/bar").build(),
crate::SECOND,
crate::CLOCK_TIME_NONE,
ClockTime::SECOND,
ClockTime::NONE,
);
}
@ -1383,14 +1387,17 @@ mod tests {
.downcast_ref::<crate::ReferenceTimestampMeta>()
.unwrap();
res.push(meta.timestamp());
if meta.timestamp() == crate::SECOND {
if let Some(ClockTime::SECOND) = meta.timestamp() {
Ok(false)
} else {
Ok(true)
}
});
assert_eq!(&[crate::ClockTime::from(0), crate::SECOND][..], &res[..]);
assert_eq!(
&[Some(ClockTime::ZERO), Some(ClockTime::SECOND)][..],
&res[..]
);
let mut res = vec![];
buffer.foreach_meta(|meta| {
@ -1401,6 +1408,6 @@ mod tests {
true
});
assert_eq!(&[crate::ClockTime::from(0)][..], &res[..]);
assert_eq!(&[Some(ClockTime::ZERO)][..], &res[..]);
}
}

View file

@ -214,8 +214,8 @@ impl BufferPoolAcquireParams {
unsafe {
BufferPoolAcquireParams(ffi::GstBufferPoolAcquireParams {
format: start.format().into_glib(),
start: start.to_raw_value(),
stop: stop.to_raw_value(),
start: start.into_raw_value(),
stop: stop.into_raw_value(),
flags: flags.into_glib(),
_gst_reserved: [ptr::null_mut(); 4],
})

View file

@ -40,9 +40,9 @@ impl<'a> Serialize for Buffer {
#[derive(serde::Deserialize)]
struct BufferDe {
pts: ClockTime,
dts: ClockTime,
duration: ClockTime,
pts: Option<ClockTime>,
dts: Option<ClockTime>,
duration: Option<ClockTime>,
offset: u64,
offset_end: u64,
flags: BufferFlags,
@ -77,6 +77,7 @@ impl<'de> Deserialize<'de> for Buffer {
mod tests {
use crate::Buffer;
use crate::BufferFlags;
use crate::ClockTime;
#[test]
fn test_serialize() {
@ -85,10 +86,10 @@ mod tests {
let mut buffer = Buffer::from_slice(vec![1, 2, 3, 4]);
{
let buffer = buffer.get_mut().unwrap();
buffer.set_pts(1.into());
buffer.set_pts(Some(ClockTime::NSECOND));
buffer.set_offset(3);
buffer.set_offset_end(4);
buffer.set_duration(5.into());
buffer.set_duration(5 * ClockTime::NSECOND);
buffer.set_flags(BufferFlags::LIVE | BufferFlags::DISCONT);
}
@ -149,11 +150,11 @@ mod tests {
)
"#;
let buffer: Buffer = ron::de::from_str(buffer_ron).unwrap();
assert_eq!(buffer.pts(), 1.into());
assert_eq!(buffer.dts(), None.into());
assert_eq!(buffer.pts(), Some(ClockTime::NSECOND));
assert_eq!(buffer.dts(), crate::ClockTime::NONE);
assert_eq!(buffer.offset(), 3);
assert_eq!(buffer.offset_end(), 4);
assert_eq!(buffer.duration(), 5.into());
assert_eq!(buffer.duration(), Some(5 * ClockTime::NSECOND));
assert_eq!(buffer.flags(), BufferFlags::LIVE | BufferFlags::DISCONT);
{
let data = buffer.map_readable().unwrap();
@ -172,11 +173,11 @@ mod tests {
}
"#;
let buffer: Buffer = serde_json::from_str(buffer_json).unwrap();
assert_eq!(buffer.pts(), 1.into());
assert_eq!(buffer.dts(), None.into());
assert_eq!(buffer.pts(), Some(ClockTime::NSECOND));
assert_eq!(buffer.dts(), crate::ClockTime::NONE);
assert_eq!(buffer.offset(), 3);
assert_eq!(buffer.offset_end(), 4);
assert_eq!(buffer.duration(), 5.into());
assert_eq!(buffer.duration(), Some(5 * ClockTime::NSECOND));
assert_eq!(buffer.flags(), BufferFlags::LIVE | BufferFlags::DISCONT);
{
let data = buffer.map_readable().unwrap();
@ -191,10 +192,10 @@ mod tests {
let mut buffer = Buffer::from_slice(vec![1, 2, 3, 4]);
{
let buffer = buffer.get_mut().unwrap();
buffer.set_pts(1.into());
buffer.set_pts(Some(ClockTime::NSECOND));
buffer.set_offset(3);
buffer.set_offset_end(4);
buffer.set_duration(5.into());
buffer.set_duration(5 * ClockTime::NSECOND);
buffer.set_flags(BufferFlags::LIVE | BufferFlags::DISCONT);
}

View file

@ -185,17 +185,20 @@ impl fmt::Debug for BufferList {
impl fmt::Debug for BufferListRef {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use crate::clock_time::ClockTime;
use crate::utils::Displayable;
let size = self.iter().map(|b| b.size()).sum::<usize>();
let (pts, dts) = self
.get(0)
.map(|b| (b.pts(), b.dts()))
.unwrap_or((crate::ClockTime::none(), crate::ClockTime::none()));
.unwrap_or((ClockTime::NONE, ClockTime::NONE));
f.debug_struct("BufferList")
.field("ptr", unsafe { &self.as_ptr() })
.field("buffers", &self.len())
.field("pts", &pts.to_string())
.field("dts", &dts.to_string())
.field("pts", &pts.display().to_string())
.field("dts", &dts.display().to_string())
.field("size", &size)
.finish()
}
@ -272,6 +275,7 @@ define_iter!(IterOwned, Buffer, |list: &BufferListRef, idx| {
#[cfg(test)]
mod tests {
use super::*;
use crate::ClockTime;
#[test]
fn test_foreach() {
@ -281,11 +285,11 @@ mod tests {
{
let buffer_list = buffer_list.get_mut().unwrap();
let mut buffer = Buffer::new();
buffer.get_mut().unwrap().set_pts(crate::ClockTime::from(0));
buffer.get_mut().unwrap().set_pts(ClockTime::ZERO);
buffer_list.add(buffer);
let mut buffer = Buffer::new();
buffer.get_mut().unwrap().set_pts(crate::SECOND);
buffer.get_mut().unwrap().set_pts(ClockTime::SECOND);
buffer_list.add(buffer);
}
@ -296,7 +300,10 @@ mod tests {
true
});
assert_eq!(res, &[(crate::ClockTime::from(0), 0), (crate::SECOND, 1)]);
assert_eq!(
res,
&[(Some(ClockTime::ZERO), 0), (Some(ClockTime::SECOND), 1)]
);
}
#[test]
@ -307,15 +314,15 @@ mod tests {
{
let buffer_list = buffer_list.get_mut().unwrap();
let mut buffer = Buffer::new();
buffer.get_mut().unwrap().set_pts(crate::ClockTime::from(0));
buffer.get_mut().unwrap().set_pts(ClockTime::ZERO);
buffer_list.add(buffer);
let mut buffer = Buffer::new();
buffer.get_mut().unwrap().set_pts(crate::SECOND);
buffer.get_mut().unwrap().set_pts(ClockTime::SECOND);
buffer_list.add(buffer);
let mut buffer = Buffer::new();
buffer.get_mut().unwrap().set_pts(2 * crate::SECOND);
buffer.get_mut().unwrap().set_pts(2 * ClockTime::SECOND);
buffer_list.add(buffer);
}
@ -323,13 +330,13 @@ mod tests {
buffer_list.get_mut().unwrap().foreach_mut(|buffer, idx| {
res.push((buffer.pts(), idx));
if buffer.pts() == crate::ClockTime::from(0) {
if let Some(ClockTime::ZERO) = buffer.pts() {
Ok(Some(buffer))
} else if buffer.pts() == crate::SECOND {
} else if let Some(ClockTime::SECOND) = buffer.pts() {
Ok(None)
} else {
let mut new_buffer = Buffer::new();
new_buffer.get_mut().unwrap().set_pts(3 * crate::SECOND);
new_buffer.get_mut().unwrap().set_pts(3 * ClockTime::SECOND);
Ok(Some(new_buffer))
}
});
@ -337,9 +344,9 @@ mod tests {
assert_eq!(
res,
&[
(crate::ClockTime::from(0), 0),
(crate::SECOND, 1),
(2 * crate::SECOND, 1)
(Some(ClockTime::ZERO), 0),
(Some(ClockTime::SECOND), 1),
(Some(2 * ClockTime::SECOND), 1)
]
);
@ -352,7 +359,7 @@ mod tests {
assert_eq!(
res,
&[(crate::ClockTime::from(0), 0), (3 * crate::SECOND, 1)]
&[(Some(ClockTime::ZERO), 0), (Some(3 * ClockTime::SECOND), 1)]
);
}
}

View file

@ -62,6 +62,7 @@ impl<'de> Deserialize<'de> for BufferList {
#[cfg(test)]
mod tests {
use crate::BufferList;
use crate::ClockTime;
#[test]
fn test_serialize() {
@ -76,20 +77,20 @@ mod tests {
let mut buffer = Buffer::from_slice(vec![1, 2, 3, 4]);
{
let buffer = buffer.get_mut().unwrap();
buffer.set_pts(1.into());
buffer.set_pts(ClockTime::NSECOND);
buffer.set_offset(0);
buffer.set_offset_end(4);
buffer.set_duration(4.into());
buffer.set_duration(4 * ClockTime::NSECOND);
}
buffer_list.add(buffer);
let mut buffer = Buffer::from_slice(vec![5, 6]);
{
let buffer = buffer.get_mut().unwrap();
buffer.set_pts(5.into());
buffer.set_pts(5 * ClockTime::NSECOND);
buffer.set_offset(4);
buffer.set_offset_end(6);
buffer.set_duration(2.into());
buffer.set_duration(2 * ClockTime::NSECOND);
}
buffer_list.add(buffer);
}
@ -163,15 +164,15 @@ mod tests {
let buffer_list: BufferList = ron::de::from_str(buffer_list_ron).unwrap();
let mut iter = buffer_list.iter();
let buffer = iter.next().unwrap();
assert_eq!(buffer.pts(), 1.into());
assert_eq!(buffer.dts(), None.into());
assert_eq!(buffer.pts(), Some(ClockTime::NSECOND));
assert_eq!(buffer.dts(), None);
{
let data = buffer.map_readable().unwrap();
assert_eq!(data.as_slice(), vec![1, 2, 3, 4].as_slice());
}
let buffer = iter.next().unwrap();
assert_eq!(buffer.pts(), 5.into());
assert_eq!(buffer.pts(), Some(5 * ClockTime::NSECOND));
{
let data = buffer.map_readable().unwrap();
assert_eq!(data.as_slice(), vec![5, 6].as_slice());
@ -191,20 +192,20 @@ mod tests {
let mut buffer = Buffer::from_slice(vec![1, 2, 3, 4]);
{
let buffer = buffer.get_mut().unwrap();
buffer.set_pts(1.into());
buffer.set_pts(ClockTime::NSECOND);
buffer.set_offset(0);
buffer.set_offset_end(4);
buffer.set_duration(4.into());
buffer.set_duration(4 * ClockTime::NSECOND);
}
buffer_list.add(buffer);
let mut buffer = Buffer::from_slice(vec![5, 6]);
{
let buffer = buffer.get_mut().unwrap();
buffer.set_pts(5.into());
buffer.set_pts(5 * ClockTime::NSECOND);
buffer.set_offset(4);
buffer.set_offset_end(6);
buffer.set_duration(2.into());
buffer.set_duration(2 * ClockTime::NSECOND);
}
buffer_list.add(buffer);
}
@ -213,15 +214,15 @@ mod tests {
let buffer_list: BufferList = ron::de::from_str(buffer_list_ser.as_str()).unwrap();
let mut iter = buffer_list.iter();
let buffer = iter.next().unwrap();
assert_eq!(buffer.pts(), 1.into());
assert_eq!(buffer.dts(), None.into());
assert_eq!(buffer.pts(), Some(ClockTime::NSECOND));
assert_eq!(buffer.dts(), None);
{
let data = buffer.map_readable().unwrap();
assert_eq!(data.as_slice(), vec![1, 2, 3, 4].as_slice());
}
let buffer = iter.next().unwrap();
assert_eq!(buffer.pts(), 5.into());
assert_eq!(buffer.pts(), Some(5 * ClockTime::NSECOND));
{
let data = buffer.map_readable().unwrap();
assert_eq!(data.as_slice(), vec![5, 6].as_slice());

View file

@ -203,10 +203,10 @@ impl Bus {
}
pub fn iter(&self) -> Iter {
self.iter_timed(0.into())
self.iter_timed(Some(crate::ClockTime::ZERO))
}
pub fn iter_timed(&self, timeout: crate::ClockTime) -> Iter {
pub fn iter_timed(&self, timeout: Option<crate::ClockTime>) -> Iter {
Iter { bus: self, timeout }
}
@ -214,12 +214,12 @@ impl Bus {
&'a self,
msg_types: &'a [MessageType],
) -> impl Iterator<Item = Message> + 'a {
self.iter_timed_filtered(0.into(), msg_types)
self.iter_timed_filtered(Some(crate::ClockTime::ZERO), msg_types)
}
pub fn iter_timed_filtered<'a>(
&'a self,
timeout: crate::ClockTime,
timeout: Option<crate::ClockTime>,
msg_types: &'a [MessageType],
) -> impl Iterator<Item = Message> + 'a {
self.iter_timed(timeout)
@ -228,7 +228,7 @@ impl Bus {
pub fn timed_pop_filtered(
&self,
timeout: crate::ClockTime,
timeout: Option<crate::ClockTime>,
msg_types: &[MessageType],
) -> Option<Message> {
loop {
@ -267,7 +267,7 @@ impl Bus {
#[derive(Debug)]
pub struct Iter<'a> {
bus: &'a Bus,
timeout: crate::ClockTime,
timeout: Option<crate::ClockTime>,
}
impl<'a> Iterator for Iter<'a> {

View file

@ -35,7 +35,7 @@ glib::wrapper! {
impl ClockId {
#[doc(alias = "get_time")]
#[doc(alias = "gst_clock_id_get_time")]
pub fn time(&self) -> ClockTime {
pub fn time(&self) -> Option<ClockTime> {
unsafe { from_glib(ffi::gst_clock_id_get_time(self.to_glib_none().0)) }
}
@ -135,9 +135,11 @@ impl SingleShotClockId {
#[doc(alias = "gst_clock_id_wait_async")]
pub fn wait_async<F>(&self, func: F) -> Result<ClockSuccess, ClockError>
where
F: FnOnce(&Clock, ClockTime, &ClockId) + Send + 'static,
F: FnOnce(&Clock, Option<ClockTime>, &ClockId) + Send + 'static,
{
unsafe extern "C" fn trampoline<F: FnOnce(&Clock, ClockTime, &ClockId) + Send + 'static>(
unsafe extern "C" fn trampoline<
F: FnOnce(&Clock, Option<ClockTime>, &ClockId) + Send + 'static,
>(
clock: *mut ffi::GstClock,
time: ffi::GstClockTime,
id: gpointer,
@ -156,7 +158,7 @@ impl SingleShotClockId {
}
unsafe extern "C" fn destroy_notify<
F: FnOnce(&Clock, ClockTime, &ClockId) + Send + 'static,
F: FnOnce(&Clock, Option<ClockTime>, &ClockId) + Send + 'static,
>(
ptr: gpointer,
) {
@ -179,7 +181,13 @@ impl SingleShotClockId {
pub fn wait_async_future(
&self,
) -> Result<
Pin<Box<dyn Future<Output = Result<(ClockTime, ClockId), ClockError>> + Send + 'static>>,
Pin<
Box<
dyn Future<Output = Result<(Option<ClockTime>, ClockId), ClockError>>
+ Send
+ 'static,
>,
>,
ClockError,
> {
use futures_channel::oneshot;
@ -234,7 +242,7 @@ impl PeriodicClockId {
pub fn interval(&self) -> ClockTime {
unsafe {
let ptr: *mut ffi::GstClockEntry = self.to_glib_none().0 as *mut _;
from_glib((*ptr).interval)
Option::<_>::from_glib((*ptr).interval).expect("undefined interval")
}
}
@ -245,9 +253,11 @@ impl PeriodicClockId {
#[doc(alias = "gst_clock_id_wait_async")]
pub fn wait_async<F>(&self, func: F) -> Result<ClockSuccess, ClockError>
where
F: Fn(&Clock, ClockTime, &ClockId) + Send + 'static,
F: Fn(&Clock, Option<ClockTime>, &ClockId) + Send + 'static,
{
unsafe extern "C" fn trampoline<F: Fn(&Clock, ClockTime, &ClockId) + Send + 'static>(
unsafe extern "C" fn trampoline<
F: Fn(&Clock, Option<ClockTime>, &ClockId) + Send + 'static,
>(
clock: *mut ffi::GstClock,
time: ffi::GstClockTime,
id: gpointer,
@ -262,7 +272,9 @@ impl PeriodicClockId {
glib::ffi::GTRUE
}
unsafe extern "C" fn destroy_notify<F: Fn(&Clock, ClockTime, &ClockId) + Send + 'static>(
unsafe extern "C" fn destroy_notify<
F: Fn(&Clock, Option<ClockTime>, &ClockId) + Send + 'static,
>(
ptr: gpointer,
) {
Box::<F>::from_raw(ptr as *mut _);
@ -283,7 +295,7 @@ impl PeriodicClockId {
pub fn wait_async_stream(
&self,
) -> Result<
Pin<Box<dyn Stream<Item = (ClockTime, ClockId)> + Unpin + Send + 'static>>,
Pin<Box<dyn Stream<Item = (Option<ClockTime>, ClockId)> + Unpin + Send + 'static>>,
ClockError,
> {
use futures_channel::mpsc;
@ -348,7 +360,7 @@ impl Clock {
cexternal: ClockTime,
cnum: ClockTime,
cdenom: ClockTime,
) -> ClockTime {
) -> Option<ClockTime> {
skip_assert_initialized!();
unsafe {
from_glib(ffi::gst_clock_adjust_with_calibration(
@ -369,7 +381,7 @@ impl Clock {
cexternal: ClockTime,
cnum: ClockTime,
cdenom: ClockTime,
) -> ClockTime {
) -> Option<ClockTime> {
skip_assert_initialized!();
unsafe {
from_glib(ffi::gst_clock_unadjust_with_calibration(
@ -416,9 +428,7 @@ pub trait ClockExtManual: 'static {
impl<O: IsA<Clock>> ClockExtManual for O {
fn new_periodic_id(&self, start_time: ClockTime, interval: ClockTime) -> PeriodicClockId {
assert!(start_time.is_some());
assert!(interval.is_some());
assert_ne!(interval, crate::ClockTime::from(0));
assert_ne!(interval, ClockTime::ZERO);
unsafe {
PeriodicClockId(from_glib_full(ffi::gst_clock_new_periodic_id(
@ -452,8 +462,6 @@ impl<O: IsA<Clock>> ClockExtManual for O {
}
fn new_single_shot_id(&self, time: ClockTime) -> SingleShotClockId {
assert!(time.is_some());
unsafe {
SingleShotClockId(from_glib_full(ffi::gst_clock_new_single_shot_id(
self.as_ref().to_glib_none().0,
@ -518,8 +526,8 @@ mod tests {
crate::init().unwrap();
let clock = SystemClock::obtain();
let now = clock.time();
let id = clock.new_single_shot_id(now + 20 * crate::MSECOND);
let now = clock.time().unwrap();
let id = clock.new_single_shot_id(now + 20 * ClockTime::MSECOND);
let (res, _) = id.wait();
assert!(res == Ok(ClockSuccess::Ok) || res == Err(ClockError::Early));
@ -532,8 +540,8 @@ mod tests {
let (sender, receiver) = channel();
let clock = SystemClock::obtain();
let now = clock.time();
let id = clock.new_single_shot_id(now + 20 * crate::MSECOND);
let now = clock.time().unwrap();
let id = clock.new_single_shot_id(now + 20 * ClockTime::MSECOND);
let res = id.wait_async(move |_, _, _| {
sender.send(()).unwrap();
});
@ -548,8 +556,8 @@ mod tests {
crate::init().unwrap();
let clock = SystemClock::obtain();
let now = clock.time();
let id = clock.new_periodic_id(now + 20 * crate::MSECOND, 20 * crate::MSECOND);
let now = clock.time().unwrap();
let id = clock.new_periodic_id(now + 20 * ClockTime::MSECOND, 20 * ClockTime::MSECOND);
let (res, _) = id.wait();
assert!(res == Ok(ClockSuccess::Ok) || res == Err(ClockError::Early));
@ -565,8 +573,8 @@ mod tests {
let (sender, receiver) = channel();
let clock = SystemClock::obtain();
let now = clock.time();
let id = clock.new_periodic_id(now + 20 * crate::MSECOND, 20 * crate::MSECOND);
let now = clock.time().unwrap();
let id = clock.new_periodic_id(now + 20 * ClockTime::MSECOND, 20 * ClockTime::MSECOND);
let res = id.wait_async(move |_, _, _| {
let _ = sender.send(());
});

File diff suppressed because it is too large Load diff

View file

@ -1,46 +1,20 @@
// Take a look at the license at the top of the repository in the LICENSE file.
use serde::de;
use serde::de::{Deserialize, Deserializer, Visitor};
use serde::de::{Deserialize, Deserializer};
use serde::ser::{Serialize, Serializer};
use std::fmt;
use crate::ClockTime;
impl<'a> Serialize for ClockTime {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
match self.nanoseconds() {
Some(ref value) => serializer.serialize_some(value),
None => serializer.serialize_none(),
}
}
}
struct ClockTimeVisitor;
impl<'de> Visitor<'de> for ClockTimeVisitor {
type Value = ClockTime;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("an optional u64 ClockTime with ns precision")
}
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
u64::deserialize(deserializer).map(ClockTime::from_nseconds)
}
fn visit_none<E: de::Error>(self) -> Result<Self::Value, E> {
Ok(ClockTime(None))
self.0.serialize(serializer)
}
}
impl<'de> Deserialize<'de> for ClockTime {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
skip_assert_initialized!();
deserializer.deserialize_option(ClockTimeVisitor)
u64::deserialize(deserializer).map(ClockTime::from_nseconds)
}
}
@ -53,7 +27,7 @@ mod tests {
crate::init().unwrap();
// Some
let clocktime = ClockTime::from_nseconds(42_123_456_789);
let clocktime = Some(ClockTime::from_nseconds(42_123_456_789));
let pretty_config = ron::ser::PrettyConfig::new().with_new_line("".to_string());
@ -64,7 +38,7 @@ mod tests {
assert_eq!("42123456789".to_owned(), res);
// None
let clocktime = ClockTime(None);
let clocktime = ClockTime::NONE;
let res = ron::ser::to_string_pretty(&clocktime, pretty_config);
assert_eq!(Ok("None".to_owned()), res);
@ -79,46 +53,59 @@ mod tests {
// Some
let clocktime_ron = "Some(42123456789)";
let clocktime: ClockTime = ron::de::from_str(clocktime_ron).unwrap();
assert_eq!(clocktime.seconds(), Some(42));
assert_eq!(clocktime.mseconds(), Some(42_123));
assert_eq!(clocktime.useconds(), Some(42_123_456));
assert_eq!(clocktime.nseconds(), Some(42_123_456_789));
let clocktime: Option<ClockTime> = ron::de::from_str(clocktime_ron).unwrap();
let clocktime = clocktime.unwrap();
assert_eq!(clocktime.seconds(), 42);
assert_eq!(clocktime.mseconds(), 42_123);
assert_eq!(clocktime.useconds(), 42_123_456);
assert_eq!(clocktime.nseconds(), 42_123_456_789);
let clocktime_json = "42123456789";
let clocktime: ClockTime = serde_json::from_str(clocktime_json).unwrap();
assert_eq!(clocktime.seconds(), Some(42));
assert_eq!(clocktime.mseconds(), Some(42_123));
assert_eq!(clocktime.useconds(), Some(42_123_456));
assert_eq!(clocktime.nseconds(), Some(42_123_456_789));
let clocktime: Option<ClockTime> = serde_json::from_str(clocktime_json).unwrap();
let clocktime = clocktime.unwrap();
assert_eq!(clocktime.seconds(), 42);
assert_eq!(clocktime.mseconds(), 42_123);
assert_eq!(clocktime.useconds(), 42_123_456);
assert_eq!(clocktime.nseconds(), 42_123_456_789);
// None
let clocktime_ron = "None";
let clocktime: ClockTime = ron::de::from_str(clocktime_ron).unwrap();
assert_eq!(clocktime.nseconds(), None);
let clocktime: Option<ClockTime> = ron::de::from_str(clocktime_ron).unwrap();
assert!(clocktime.is_none());
let clocktime_json = "null";
let clocktime: ClockTime = serde_json::from_str(clocktime_json).unwrap();
assert_eq!(clocktime.nseconds(), None);
let clocktime: Option<ClockTime> = serde_json::from_str(clocktime_json).unwrap();
assert!(clocktime.is_none());
assert!(clocktime.is_none());
}
#[test]
fn test_serde_roundtrip() {
crate::init().unwrap();
// Some
// Direct
let clocktime = ClockTime::from_nseconds(42_123_456_789);
let clocktime_ser = ron::ser::to_string(&clocktime).unwrap();
let clocktime: ClockTime = ron::de::from_str(clocktime_ser.as_str()).unwrap();
assert_eq!(clocktime.seconds(), Some(42));
assert_eq!(clocktime.mseconds(), Some(42_123));
assert_eq!(clocktime.useconds(), Some(42_123_456));
assert_eq!(clocktime.nseconds(), Some(42_123_456_789));
assert_eq!(clocktime.seconds(), 42);
assert_eq!(clocktime.mseconds(), 42_123);
assert_eq!(clocktime.useconds(), 42_123_456);
assert_eq!(clocktime.nseconds(), 42_123_456_789);
// Some
let clocktime = Some(ClockTime::from_nseconds(42_123_456_789));
let clocktime_ser = ron::ser::to_string(&clocktime).unwrap();
let clocktime: Option<ClockTime> = ron::de::from_str(clocktime_ser.as_str()).unwrap();
let clocktime = clocktime.unwrap();
assert_eq!(clocktime.seconds(), 42);
assert_eq!(clocktime.mseconds(), 42_123);
assert_eq!(clocktime.useconds(), 42_123_456);
assert_eq!(clocktime.nseconds(), 42_123_456_789);
// None
let clocktime = ClockTime(None);
let clocktime = ClockTime::NONE;
let clocktime_ser = ron::ser::to_string(&clocktime).unwrap();
let clocktime: ClockTime = ron::de::from_str(clocktime_ser.as_str()).unwrap();
assert_eq!(clocktime.nseconds(), None);
let clocktime: Option<ClockTime> = ron::de::from_str(clocktime_ser.as_str()).unwrap();
assert!(clocktime.is_none());
}
}

View file

@ -226,11 +226,11 @@ pub trait ElementExtManual: 'static {
) -> Option<GenericFormattedValue>;
#[doc(alias = "gst_element_query_duration")]
fn query_duration<T: SpecificFormattedValue>(&self) -> Option<T>;
fn query_duration<T: SpecificFormattedValueIntrinsic>(&self) -> Option<T>;
fn query_duration_generic(&self, format: Format) -> Option<GenericFormattedValue>;
#[doc(alias = "gst_element_query_position")]
fn query_position<T: SpecificFormattedValue>(&self) -> Option<T>;
fn query_position<T: SpecificFormattedValueIntrinsic>(&self) -> Option<T>;
fn query_position_generic(&self, format: Format) -> Option<GenericFormattedValue>;
#[doc(alias = "gst_element_seek")]
@ -265,9 +265,10 @@ pub trait ElementExtManual: 'static {
T: Send + 'static;
#[doc(alias = "get_current_running_time")]
fn current_running_time(&self) -> crate::ClockTime;
fn current_running_time(&self) -> Option<crate::ClockTime>;
#[doc(alias = "get_current_clock_time")]
fn current_clock_time(&self) -> crate::ClockTime;
fn current_clock_time(&self) -> Option<crate::ClockTime>;
#[cfg(not(feature = "v1_20"))]
#[cfg_attr(feature = "dox", doc(cfg(not(feature = "v1_20"))))]
@ -286,11 +287,11 @@ impl<O: IsA<Element>> ElementExtManual for O {
}
fn current_state(&self) -> State {
self.state(ClockTime::zero()).1
self.state(Some(ClockTime::ZERO)).1
}
fn pending_state(&self) -> State {
self.state(ClockTime::zero()).2
self.state(Some(ClockTime::ZERO)).2
}
fn query(&self, query: &mut QueryRef) -> bool {
@ -575,7 +576,7 @@ impl<O: IsA<Element>> ElementExtManual for O {
let ret = from_glib(ffi::gst_element_query_convert(
self.as_ref().to_glib_none().0,
src_val.format().into_glib(),
src_val.to_raw_value(),
src_val.into_raw_value(),
U::default_format().into_glib(),
dest_val.as_mut_ptr(),
));
@ -613,16 +614,16 @@ impl<O: IsA<Element>> ElementExtManual for O {
}
}
fn query_duration<T: SpecificFormattedValue>(&self) -> Option<T> {
fn query_duration<T: SpecificFormattedValueIntrinsic>(&self) -> Option<T> {
unsafe {
let mut duration = mem::MaybeUninit::uninit();
let ret = from_glib(ffi::gst_element_query_duration(
self.as_ref().to_glib_none().0,
T::default_format().into_glib(),
T::FormattedValueType::default_format().into_glib(),
duration.as_mut_ptr(),
));
if ret {
Some(T::from_raw(T::default_format(), duration.assume_init()))
try_from_glib(duration.assume_init()).ok()
} else {
None
}
@ -645,16 +646,16 @@ impl<O: IsA<Element>> ElementExtManual for O {
}
}
fn query_position<T: SpecificFormattedValue>(&self) -> Option<T> {
fn query_position<T: SpecificFormattedValueIntrinsic>(&self) -> Option<T> {
unsafe {
let mut cur = mem::MaybeUninit::uninit();
let ret = from_glib(ffi::gst_element_query_position(
self.as_ref().to_glib_none().0,
T::default_format().into_glib(),
T::FormattedValueType::default_format().into_glib(),
cur.as_mut_ptr(),
));
if ret {
Some(T::from_raw(T::default_format(), cur.assume_init()))
try_from_glib(cur.assume_init()).ok()
} else {
None
}
@ -779,18 +780,18 @@ impl<O: IsA<Element>> ElementExtManual for O {
Box::pin(async move { receiver.await.expect("sender dropped") })
}
fn current_running_time(&self) -> crate::ClockTime {
fn current_running_time(&self) -> Option<crate::ClockTime> {
let base_time = self.base_time();
let clock_time = self.current_clock_time();
clock_time - base_time
clock_time.zip(base_time).map(|(ct, bt)| ct - bt)
}
fn current_clock_time(&self) -> crate::ClockTime {
fn current_clock_time(&self) -> Option<crate::ClockTime> {
if let Some(clock) = self.clock() {
clock.time()
} else {
crate::CLOCK_TIME_NONE
crate::ClockTime::NONE
}
}

View file

@ -447,12 +447,12 @@ impl<'a> Caps<'a> {
declare_concrete_event!(Segment);
impl<'a> Segment<'a> {
#[allow(clippy::new_ret_no_self)]
pub fn new<F: crate::FormattedValue>(segment: &crate::FormattedSegment<F>) -> Event {
pub fn new<F: crate::FormattedValueIntrinsic>(segment: &crate::FormattedSegment<F>) -> Event {
skip_assert_initialized!();
Self::builder(segment).build()
}
pub fn builder<F: crate::FormattedValue>(
pub fn builder<F: crate::FormattedValueIntrinsic>(
segment: &crate::FormattedSegment<F>,
) -> SegmentBuilder {
assert_initialized_main_thread!();
@ -776,7 +776,7 @@ impl<'a> Gap<'a> {
GapBuilder::new(timestamp, duration)
}
pub fn get(&self) -> (crate::ClockTime, crate::ClockTime) {
pub fn get(&self) -> (Option<crate::ClockTime>, Option<crate::ClockTime>) {
unsafe {
let mut timestamp = mem::MaybeUninit::uninit();
let mut duration = mem::MaybeUninit::uninit();
@ -818,7 +818,7 @@ impl<'a> Qos<'a> {
QosBuilder::new(type_, proportion, diff, timestamp)
}
pub fn get(&self) -> (crate::QOSType, f64, i64, crate::ClockTime) {
pub fn get(&self) -> (crate::QOSType, f64, i64, Option<crate::ClockTime>) {
unsafe {
let mut type_ = mem::MaybeUninit::uninit();
let mut proportion = mem::MaybeUninit::uninit();
@ -919,7 +919,7 @@ impl<'a> Seek<'a> {
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_16")))]
#[doc(alias = "get_trickmode_interval")]
#[doc(alias = "gst_event_parse_seek_trickmode_interval")]
pub fn trickmode_interval(&self) -> crate::ClockTime {
pub fn trickmode_interval(&self) -> Option<crate::ClockTime> {
unsafe {
let mut trickmode_interval = mem::MaybeUninit::uninit();
@ -962,7 +962,7 @@ impl<'a> Latency<'a> {
#[doc(alias = "get_latency")]
#[doc(alias = "gst_event_parse_latency")]
pub fn latency(&self) -> crate::ClockTime {
pub fn latency(&self) -> Option<crate::ClockTime> {
unsafe {
let mut latency = mem::MaybeUninit::uninit();

View file

@ -2,45 +2,65 @@
use crate::ClockTime;
use crate::Format;
use glib::translate::{FromGlib, GlibNoneError, IntoGlib, OptionIntoGlib, TryFromGlib};
use muldiv::MulDiv;
use std::borrow::Borrow;
use std::convert::TryFrom;
use std::fmt;
use std::ops;
use thiserror::Error;
use std::cmp;
#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)]
#[cfg_attr(feature = "ser_de", derive(serde::Serialize, serde::Deserialize))]
pub enum GenericFormattedValue {
Undefined(Undefined),
Default(Default),
Bytes(Bytes),
Time(ClockTime),
Buffers(Buffers),
Percent(Percent),
Default(Option<Default>),
Bytes(Option<Bytes>),
Time(Option<ClockTime>),
Buffers(Option<Buffers>),
Percent(Option<Percent>),
Other(Format, i64),
}
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)]
pub struct Undefined(pub i64);
#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug, Default)]
pub struct Default(pub Option<u64>);
impl_common_ops_for_opt_int!(Default);
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)]
pub struct Default(pub u64);
#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug, Default)]
pub struct Bytes(pub Option<u64>);
impl_common_ops_for_opt_int!(Bytes);
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)]
pub struct Bytes(pub u64);
pub type Time = ClockTime;
#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug, Default)]
pub struct Buffers(pub Option<u64>);
impl_common_ops_for_opt_int!(Buffers);
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)]
pub struct Buffers(pub u64);
impl Buffers {
pub const OFFSET_NONE: u64 = ffi::GST_BUFFER_OFFSET_NONE;
}
#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug, Default)]
pub struct Percent(pub Option<u32>);
impl_common_ops_for_opt_int!(Percent);
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)]
pub struct Percent(pub u32);
impl Percent {
pub const MAX: u32 = ffi::GST_FORMAT_PERCENT_MAX as u32;
pub const SCALE: u32 = ffi::GST_FORMAT_PERCENT_SCALE as u32;
}
impl fmt::Display for GenericFormattedValue {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use crate::utils::Displayable;
match self {
Self::Undefined(val) => val.fmt(f),
Self::Default(val) => val.display().fmt(f),
Self::Bytes(val) => val.display().fmt(f),
Self::Time(val) => val.display().fmt(f),
Self::Buffers(val) => val.display().fmt(f),
Self::Percent(val) => val.display().fmt(f),
Self::Other(format, val) => write!(f, "{} ({:?})", val, format),
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Error)]
#[error("invalid generic value format")]
@ -53,11 +73,32 @@ pub trait FormattedValue: Copy + Clone + Sized + Into<GenericFormattedValue> + '
fn format(&self) -> Format;
unsafe fn from_raw(format: Format, value: i64) -> Self;
unsafe fn to_raw_value(&self) -> i64;
unsafe fn into_raw_value(self) -> i64;
}
// rustdoc-stripper-ignore-next
/// A trait implemented on the intrinsic type of a `FormattedValue`.
///
/// # Examples
///
/// - `GenericFormattedValue` is the intrinsic type for `GenericFormattedValue`.
/// - `Undefined` is the intrinsic type for `Undefined`.
/// - `Bytes` is the intrinsic type for `Option<Bytes>`.
pub trait FormattedValueIntrinsic: Copy + Clone + Sized + 'static {
type FormattedValueType: FormattedValue;
}
pub trait SpecificFormattedValue: FormattedValue + TryFrom<GenericFormattedValue> {}
// rustdoc-stripper-ignore-next
/// A trait implemented on the intrinsic type of a `SpecificFormattedValue`.
///
/// # Examples
///
/// - `Undefined` is the intrinsic type for `Undefined`.
/// - `Bytes` is the intrinsic type for `Option<Bytes>`.
pub trait SpecificFormattedValueIntrinsic: TryFromGlib<i64> + FormattedValueIntrinsic {}
impl FormattedValue for GenericFormattedValue {
fn default_format() -> Format {
Format::Undefined
@ -71,7 +112,7 @@ impl FormattedValue for GenericFormattedValue {
GenericFormattedValue::new(format, value)
}
unsafe fn to_raw_value(&self) -> i64 {
unsafe fn into_raw_value(self) -> i64 {
self.value()
}
}
@ -81,27 +122,11 @@ impl GenericFormattedValue {
skip_assert_initialized!();
match format {
Format::Undefined => Self::Undefined(Undefined(value)),
Format::Default => Self::Default(if value == -1 {
Default(None)
} else {
Default(Some(value as u64))
}),
Format::Bytes => Self::Bytes(if value == -1 {
Bytes(None)
} else {
Bytes(Some(value as u64))
}),
Format::Time => Self::Time(if value == -1 {
ClockTime::none()
} else {
ClockTime::from_nseconds(value as u64)
}),
Format::Buffers => Self::Buffers(if value == -1 {
Buffers(None)
} else {
Buffers(Some(value as u64))
}),
Format::Percent => Self::Percent(unsafe { Percent::from_raw(format, value) }),
Format::Default => Self::Default(unsafe { FromGlib::from_glib(value as u64) }),
Format::Bytes => Self::Bytes(unsafe { FromGlib::from_glib(value as u64) }),
Format::Time => Self::Time(unsafe { FromGlib::from_glib(value as u64) }),
Format::Buffers => Self::Buffers(unsafe { FromGlib::from_glib(value as u64) }),
Format::Percent => Self::Percent(unsafe { FormattedValue::from_raw(format, value) }),
Format::__Unknown(_) => Self::Other(format, value),
}
}
@ -121,153 +146,87 @@ impl GenericFormattedValue {
#[doc(alias = "get_value")]
pub fn value(&self) -> i64 {
unsafe {
match *self {
Self::Undefined(v) => v.0,
Self::Default(v) => v.map(|v| v as i64).unwrap_or(-1),
Self::Bytes(v) => v.map(|v| v as i64).unwrap_or(-1),
Self::Time(v) => v.map(|v| v as i64).unwrap_or(-1),
Self::Buffers(v) => v.map(|v| v as i64).unwrap_or(-1),
Self::Percent(v) => v.map(i64::from).unwrap_or(-1),
Self::Default(v) => v.into_raw_value(),
Self::Bytes(v) => v.into_raw_value(),
Self::Time(v) => v.into_raw_value(),
Self::Buffers(v) => v.into_raw_value(),
Self::Percent(v) => v.into_raw_value(),
Self::Other(_, v) => v,
}
}
}
}
impl FormattedValueIntrinsic for GenericFormattedValue {
type FormattedValueType = GenericFormattedValue;
}
macro_rules! impl_op_same(
($name:ident, $op:ident, $op_name:ident, $op_assign:ident, $op_assign_name:ident, $e:expr) => {
impl ops::$op<$name> for $name {
($name:ident, $op:ident, $op_name:ident, $op_assign:ident, $op_assign_name:ident) => {
impl<RHS: Borrow<$name>> ops::$op<RHS> for $name {
type Output = Self;
fn $op_name(self, rhs: RHS) -> Self::Output {
Self(self.0.$op_name(rhs.borrow().0))
}
}
impl<RHS: Borrow<$name>> ops::$op<RHS> for &$name {
type Output = $name;
fn $op_name(self, other: $name) -> Self::Output {
match (self.0, other.0) {
(Some(a), Some(b)) => $name($e(a, b)),
_ => $name(None),
}
}
}
impl<'a> ops::$op<&'a $name> for $name {
type Output = $name;
fn $op_name(self, other: &'a $name) -> Self::Output {
self.$op_name(*other)
fn $op_name(self, rhs: RHS) -> Self::Output {
(*self).$op_name(rhs)
}
}
impl<'a> ops::$op<$name> for &'a $name {
type Output = $name;
fn $op_name(self, other: $name) -> Self::Output {
(*self).$op_name(other)
}
}
impl<'a, 'b> ops::$op<&'a $name> for &'b $name {
type Output = $name;
fn $op_name(self, other: &'a $name) -> Self::Output {
(*self).$op_name(*other)
}
}
impl ops::$op_assign<$name> for $name {
fn $op_assign_name(&mut self, other: $name) {
match (self.0, other.0) {
(Some(a), Some(b)) => self.0 = $e(a, b),
_ => self.0 = None,
}
}
}
impl<'a> ops::$op_assign<&'a $name> for $name {
fn $op_assign_name(&mut self, other: &'a $name) {
self.$op_assign_name(*other)
impl<RHS: Borrow<$name>> ops::$op_assign<RHS> for $name {
fn $op_assign_name(&mut self, rhs: RHS) {
self.0.$op_assign_name(rhs.borrow().0)
}
}
};
);
macro_rules! impl_op_u64(
($name:ident, $op:ident, $op_name:ident, $op_assign:ident, $op_assign_name:ident, $e:expr) => {
($name:ident, $op:ident, $op_name:ident, $op_assign:ident, $op_assign_name:ident) => {
impl ops::$op<u64> for $name {
type Output = $name;
fn $op_name(self, other: u64) -> Self::Output {
match self.0 {
Some(a) => $name($e(a, other)),
_ => $name(None),
}
fn $op_name(self, rhs: u64) -> Self::Output {
$name(self.0.$op_name(rhs))
}
}
impl<'a> ops::$op<&'a u64> for $name {
impl ops::$op<u64> for &$name {
type Output = $name;
fn $op_name(self, other: &'a u64) -> Self::Output {
self.$op_name(*other)
}
}
impl<'a> ops::$op<u64> for &'a $name {
type Output = $name;
fn $op_name(self, other: u64) -> Self::Output {
(*self).$op_name(other)
}
}
impl<'a, 'b> ops::$op<&'a u64> for &'b $name {
type Output = $name;
fn $op_name(self, other: &'a u64) -> Self::Output {
self.$op_name(*other)
fn $op_name(self, rhs: u64) -> Self::Output {
(*self).$op_name(rhs)
}
}
impl ops::$op<$name> for u64 {
type Output = $name;
fn $op_name(self, other: $name) -> $name {
other.$op_name(self)
fn $op_name(self, rhs: $name) -> $name {
$name(self.$op_name(rhs.0))
}
}
impl<'a> ops::$op<&'a $name> for u64 {
impl ops::$op<&$name> for u64 {
type Output = $name;
fn $op_name(self, other: &'a $name) -> $name {
(*other).$op_name(self)
}
}
impl<'a> ops::$op<$name> for &'a u64 {
type Output = $name;
fn $op_name(self, other: $name) -> $name {
other.$op_name(*self)
}
}
impl<'a, 'b> ops::$op<&'a $name> for &'b u64 {
type Output = $name;
fn $op_name(self, other: &'a $name) -> $name {
(*other).$op_name(*self)
fn $op_name(self, rhs: &$name) -> $name {
self.$op_name(*rhs)
}
}
impl ops::$op_assign<u64> for $name {
fn $op_assign_name(&mut self, other: u64) {
match self.0 {
Some(a) => self.0 = $e(a, other),
_ => self.0 = None,
}
}
}
impl<'a> ops::$op_assign<&'a u64> for $name {
fn $op_assign_name(&mut self, other: &'a u64) {
self.$op_assign_name(*other)
fn $op_assign_name(&mut self, rhs: u64) {
self.0.$op_assign_name(rhs)
}
}
};
@ -275,7 +234,7 @@ macro_rules! impl_op_u64(
macro_rules! impl_format_value_traits(
($name:ident, $format:ident, $format_value:ident) => {
impl FormattedValue for $name {
impl FormattedValue for Option<$name> {
fn default_format() -> Format {
Format::$format
}
@ -284,31 +243,38 @@ macro_rules! impl_format_value_traits(
Format::$format
}
unsafe fn from_raw(format: Format, value: i64) -> Self {
unsafe fn from_raw(format: Format, value: i64) -> Option<$name> {
debug_assert_eq!(format, Format::$format);
if value == -1 {
$name(None)
} else {
$name(Some(value as u64))
FromGlib::from_glib(value as u64)
}
unsafe fn into_raw_value(self) -> i64 {
IntoGlib::into_glib(self) as i64
}
}
unsafe fn to_raw_value(&self) -> i64 {
self.0.map(|v| v as i64).unwrap_or(-1)
impl From<Option<$name>> for GenericFormattedValue {
fn from(v: Option<$name>) -> Self {
skip_assert_initialized!();
Self::$format_value(v)
}
}
impl From<$name> for GenericFormattedValue {
fn from(v: $name) -> Self {
skip_assert_initialized!();
GenericFormattedValue::$format_value(v)
Self::$format_value(Some(v))
}
}
impl TryFrom<GenericFormattedValue> for $name {
impl FormattedValueIntrinsic for $name {
type FormattedValueType = Option<$name>;
}
impl TryFrom<GenericFormattedValue> for Option<$name> {
type Error = TryFromGenericFormattedValueError;
fn try_from(v: GenericFormattedValue) -> Result<$name, Self::Error> {
fn try_from(v: GenericFormattedValue) -> Result<Option<$name>, Self::Error> {
skip_assert_initialized!();
if let GenericFormattedValue::$format_value(v) = v {
Ok(v)
@ -318,208 +284,127 @@ macro_rules! impl_format_value_traits(
}
}
impl SpecificFormattedValue for $name { }
impl TryFrom<u64> for $name {
type Error = GlibNoneError;
impl From<u64> for $name {
fn from(v: u64) -> Self {
fn try_from(v: u64) -> Result<$name, GlibNoneError> {
skip_assert_initialized!();
$name(Some(v))
unsafe { Self::try_from_glib(v) }
}
}
impl From<Option<u64>> for $name {
fn from(v: Option<u64>) -> Self {
impl TryFromGlib<i64> for $name {
type Error = GlibNoneError;
#[inline]
unsafe fn try_from_glib(val: i64) -> Result<Self, GlibNoneError> {
skip_assert_initialized!();
$name(v)
<$name as TryFromGlib<u64>>::try_from_glib(val as u64)
}
}
impl From<$name> for Option<u64> {
fn from(v: $name) -> Self {
skip_assert_initialized!();
v.0
}
}
impl SpecificFormattedValue for Option<$name> {}
impl SpecificFormattedValueIntrinsic for $name {}
impl ops::Deref for $name {
type Target = Option<u64>;
type Target = u64;
fn deref(&self) -> &Option<u64> {
fn deref(&self) -> &u64 {
&self.0
}
}
impl ops::DerefMut for $name {
fn deref_mut(&mut self) -> &mut Option<u64> {
fn deref_mut(&mut self) -> &mut u64 {
&mut self.0
}
}
impl AsRef<Option<u64>> for $name {
fn as_ref(&self) -> &Option<u64> {
impl AsRef<u64> for $name {
fn as_ref(&self) -> &u64 {
&self.0
}
}
impl AsMut<Option<u64>> for $name {
fn as_mut(&mut self) -> &mut Option<u64> {
impl AsMut<u64> for $name {
fn as_mut(&mut self) -> &mut u64 {
&mut self.0
}
}
impl_op_same!($name, Add, add, AddAssign, add_assign, |a: u64, b: u64| a.checked_add(b));
impl_op_same!($name, Sub, sub, SubAssign, sub_assign, |a: u64, b: u64| a.checked_sub(b));
impl_op_same!($name, Mul, mul, MulAssign, mul_assign, |a: u64, b: u64| a.checked_mul(b));
impl_op_same!($name, Div, div, DivAssign, div_assign, |a: u64, b: u64| a.checked_div(b));
impl_op_same!($name, Rem, rem, RemAssign, rem_assign, |a: u64, b: u64| a.checked_rem(b));
impl_op_same!($name, Add, add, AddAssign, add_assign);
impl_op_same!($name, Sub, sub, SubAssign, sub_assign);
impl_op_same!($name, Mul, mul, MulAssign, mul_assign);
impl_op_same!($name, Div, div, DivAssign, div_assign);
impl_op_same!($name, Rem, rem, RemAssign, rem_assign);
impl_op_u64!($name, Mul, mul, MulAssign, mul_assign, |a: u64, b: u64| a.checked_mul(b));
impl_op_u64!($name, Div, div, DivAssign, div_assign, |a: u64, b: u64| a.checked_div(b));
impl_op_u64!($name, Rem, rem, RemAssign, rem_assign, |a: u64, b: u64| a.checked_rem(b));
impl_op_u64!($name, Mul, mul, MulAssign, mul_assign);
impl_op_u64!($name, Div, div, DivAssign, div_assign);
impl_op_u64!($name, Rem, rem, RemAssign, rem_assign);
impl MulDiv<$name> for $name {
impl<ND: Borrow<u64>> MulDiv<ND> for $name {
type Output = $name;
fn mul_div_floor(self, num: $name, denom: $name) -> Option<Self::Output> {
match (self.0, num.0, denom.0) {
(Some(s), Some(n), Some(d)) => s.mul_div_floor(n, d).map(|v| $name(Some(v))),
_ => Some($name(None)),
}
fn mul_div_floor(self, num: ND, denom: ND) -> Option<Self::Output> {
self.0
.mul_div_floor(*num.borrow(), *denom.borrow())
.map($name)
}
fn mul_div_round(self, num: $name, denom: $name) -> Option<Self::Output> {
match (self.0, num.0, denom.0) {
(Some(s), Some(n), Some(d)) => s.mul_div_round(n, d).map(|v| $name(Some(v))),
_ => Some($name(None)),
}
fn mul_div_round(self, num: ND, denom: ND) -> Option<Self::Output> {
self.0
.mul_div_round(*num.borrow(), *denom.borrow())
.map($name)
}
fn mul_div_ceil(self, num: $name, denom: $name) -> Option<Self::Output> {
match (self.0, num.0, denom.0) {
(Some(s), Some(n), Some(d)) => s.mul_div_ceil(n, d).map(|v| $name(Some(v))),
_ => Some($name(None)),
}
}
}
impl<'a> MulDiv<&'a $name> for $name {
type Output = $name;
fn mul_div_floor(self, num: &$name, denom: &$name) -> Option<Self::Output> {
self.mul_div_floor(*num, *denom)
}
fn mul_div_round(self, num: &$name, denom: &$name) -> Option<Self::Output> {
self.mul_div_round(*num, *denom)
}
fn mul_div_ceil(self, num: &$name, denom: &$name) -> Option<Self::Output> {
self.mul_div_ceil(*num, *denom)
}
}
impl<'a> MulDiv<$name> for &'a $name {
type Output = $name;
fn mul_div_floor(self, num: $name, denom: $name) -> Option<Self::Output> {
(*self).mul_div_floor(num, denom)
}
fn mul_div_round(self, num: $name, denom: $name) -> Option<Self::Output> {
(*self).mul_div_round(num, denom)
}
fn mul_div_ceil(self, num: $name, denom: $name) -> Option<Self::Output> {
(*self).mul_div_ceil(num, denom)
}
}
impl<'a, 'b> MulDiv<&'b $name> for &'a $name {
type Output = $name;
fn mul_div_floor(self, num: &$name, denom: &$name) -> Option<Self::Output> {
(*self).mul_div_floor(*num, *denom)
}
fn mul_div_round(self, num: &$name, denom: &$name) -> Option<Self::Output> {
(*self).mul_div_round(*num, *denom)
}
fn mul_div_ceil(self, num: &$name, denom: &$name) -> Option<Self::Output> {
(*self).mul_div_ceil(*num, *denom)
}
}
impl<'a> MulDiv<u64> for $name {
type Output = $name;
fn mul_div_floor(self, num: u64, denom: u64) -> Option<Self::Output> {
self.mul_div_floor($name(Some(num)), $name(Some(denom)))
}
fn mul_div_round(self, num: u64, denom: u64) -> Option<Self::Output> {
self.mul_div_round($name(Some(num)), $name(Some(denom)))
}
fn mul_div_ceil(self, num: u64, denom: u64) -> Option<Self::Output> {
self.mul_div_ceil($name(Some(num)), $name(Some(denom)))
}
}
impl<'a> MulDiv<&'a u64> for $name {
type Output = $name;
fn mul_div_floor(self, num: &u64, denom: &u64) -> Option<Self::Output> {
self.mul_div_floor(*num, *denom)
}
fn mul_div_round(self, num: &u64, denom: &u64) -> Option<Self::Output> {
self.mul_div_round(*num, *denom)
}
fn mul_div_ceil(self, num: &u64, denom: &u64) -> Option<Self::Output> {
self.mul_div_ceil(*num, *denom)
}
}
impl<'a> MulDiv<u64> for &'a $name {
type Output = $name;
fn mul_div_floor(self, num: u64, denom: u64) -> Option<Self::Output> {
(*self).mul_div_floor(num, denom)
}
fn mul_div_round(self, num: u64, denom: u64) -> Option<Self::Output> {
(*self).mul_div_round(num, denom)
}
fn mul_div_ceil(self, num: u64, denom: u64) -> Option<Self::Output> {
(*self).mul_div_ceil(num, denom)
}
}
impl<'a, 'b> MulDiv<&'a u64> for &'b $name {
type Output = $name;
fn mul_div_floor(self, num: &u64, denom: &u64) -> Option<Self::Output> {
(*self).mul_div_floor(*num, *denom)
}
fn mul_div_round(self, num: &u64, denom: &u64) -> Option<Self::Output> {
(*self).mul_div_round(*num, *denom)
}
fn mul_div_ceil(self, num: &u64, denom: &u64) -> Option<Self::Output> {
(*self).mul_div_ceil(*num, *denom)
fn mul_div_ceil(self, num: ND, denom: ND) -> Option<Self::Output> {
self.0
.mul_div_ceil(*num.borrow(), *denom.borrow())
.map($name)
}
}
};
);
macro_rules! option_glib_newtype_display {
($name:ident, $unit:expr) => {
impl crate::utils::Displayable for Option<$name> {
type DisplayImpl = String;
fn display(self) -> String {
if let Some(val) = self {
val.display()
} else {
format!("undef. {}", $unit)
}
}
}
impl crate::utils::Displayable for $name {
type DisplayImpl = String;
fn display(self) -> String {
format!("{} {}", self.0, $unit)
}
}
};
}
impl_common_ops_for_newtype_u64!(Default);
impl_format_value_traits!(Default, Default, Default);
option_glib_newtype_from_to!(Default, u64::MAX);
option_glib_newtype_display!(Default, "(Default)");
impl_common_ops_for_newtype_u64!(Bytes);
impl_format_value_traits!(Bytes, Bytes, Bytes);
option_glib_newtype_from_to!(Bytes, u64::MAX);
option_glib_newtype_display!(Bytes, "bytes");
impl_format_value_traits!(ClockTime, Time, Time);
impl_common_ops_for_newtype_u64!(Buffers);
impl_format_value_traits!(Buffers, Buffers, Buffers);
option_glib_newtype_from_to!(Buffers, Buffers::OFFSET_NONE);
option_glib_newtype_display!(Buffers, "buffers");
impl FormattedValue for Undefined {
fn default_format() -> Format {
@ -535,7 +420,7 @@ impl FormattedValue for Undefined {
Undefined(value)
}
unsafe fn to_raw_value(&self) -> i64 {
unsafe fn into_raw_value(self) -> i64 {
self.0
}
}
@ -560,8 +445,23 @@ impl TryFrom<GenericFormattedValue> for Undefined {
}
}
impl FormattedValueIntrinsic for Undefined {
type FormattedValueType = Undefined;
}
impl SpecificFormattedValue for Undefined {}
impl SpecificFormattedValueIntrinsic for Undefined {}
impl TryFromGlib<i64> for Undefined {
type Error = std::convert::Infallible;
#[inline]
unsafe fn try_from_glib(v: i64) -> Result<Self, Self::Error> {
skip_assert_initialized!();
Ok(Undefined(v))
}
}
impl From<i64> for Undefined {
fn from(v: i64) -> Self {
skip_assert_initialized!();
@ -569,13 +469,6 @@ impl From<i64> for Undefined {
}
}
impl From<Undefined> for i64 {
fn from(u: Undefined) -> Self {
skip_assert_initialized!();
u.0
}
}
impl ops::Deref for Undefined {
type Target = i64;
@ -602,7 +495,24 @@ impl AsMut<i64> for Undefined {
}
}
impl FormattedValue for Percent {
impl fmt::Display for Undefined {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} (Undefined)", self.0)
}
}
impl crate::utils::Displayable for Undefined {
type DisplayImpl = Undefined;
fn display(self) -> Undefined {
self
}
}
impl_common_ops_for_newtype_u64!(Percent);
option_glib_newtype_display!(Percent, "%");
impl FormattedValue for Option<Percent> {
fn default_format() -> Format {
Format::Percent
}
@ -613,29 +523,47 @@ impl FormattedValue for Percent {
unsafe fn from_raw(format: Format, value: i64) -> Self {
debug_assert_eq!(format, Format::Percent);
if value < 0 || value > ffi::GST_FORMAT_PERCENT_MAX {
Percent(None)
} else {
Percent(Some(value as u32))
Percent::try_from_glib(value as i64).ok()
}
unsafe fn into_raw_value(self) -> i64 {
self.map_or(-1, |v| v.0 as i64)
}
}
unsafe fn to_raw_value(&self) -> i64 {
self.0.map(|v| v as i64).unwrap_or(-1)
impl From<Option<Percent>> for GenericFormattedValue {
fn from(v: Option<Percent>) -> Self {
skip_assert_initialized!();
GenericFormattedValue::Percent(v)
}
}
impl From<Percent> for GenericFormattedValue {
fn from(v: Percent) -> Self {
skip_assert_initialized!();
GenericFormattedValue::Percent(v)
GenericFormattedValue::Percent(Some(v))
}
}
impl TryFrom<GenericFormattedValue> for Percent {
impl TryFromGlib<i64> for Percent {
type Error = GlibNoneError;
#[inline]
unsafe fn try_from_glib(value: i64) -> Result<Self, Self::Error> {
skip_assert_initialized!();
if value < 0 || value > ffi::GST_FORMAT_PERCENT_MAX {
Err(GlibNoneError)
} else {
Ok(Percent(value as u32))
}
}
}
impl TryFrom<GenericFormattedValue> for Option<Percent> {
type Error = TryFromGenericFormattedValueError;
fn try_from(v: GenericFormattedValue) -> Result<Percent, TryFromGenericFormattedValueError> {
fn try_from(
v: GenericFormattedValue,
) -> Result<Option<Percent>, TryFromGenericFormattedValueError> {
skip_assert_initialized!();
if let GenericFormattedValue::Percent(v) = v {
Ok(v)
@ -645,30 +573,36 @@ impl TryFrom<GenericFormattedValue> for Percent {
}
}
impl SpecificFormattedValue for Percent {}
impl FormattedValueIntrinsic for Percent {
type FormattedValueType = Option<Percent>;
}
impl SpecificFormattedValue for Option<Percent> {}
impl SpecificFormattedValueIntrinsic for Percent {}
impl ops::Deref for Percent {
type Target = Option<u32>;
type Target = u32;
fn deref(&self) -> &Option<u32> {
fn deref(&self) -> &u32 {
&self.0
}
}
impl ops::DerefMut for Percent {
fn deref_mut(&mut self) -> &mut Option<u32> {
fn deref_mut(&mut self) -> &mut u32 {
&mut self.0
}
}
impl AsRef<Option<u32>> for Percent {
fn as_ref(&self) -> &Option<u32> {
impl AsRef<u32> for Percent {
fn as_ref(&self) -> &u32 {
&self.0
}
}
impl AsMut<Option<u32>> for Percent {
fn as_mut(&mut self) -> &mut Option<u32> {
impl AsMut<u32> for Percent {
fn as_mut(&mut self) -> &mut u32 {
&mut self.0
}
}
@ -685,9 +619,9 @@ impl TryFrom<f64> for Percent {
if v < 0.0 || v > 1.0 {
Err(TryPercentFromFloatError(()))
} else {
Ok(Percent(Some(
(v * ffi::GST_FORMAT_PERCENT_SCALE as f64).round() as u32,
)))
Ok(Percent(
(v * ffi::GST_FORMAT_PERCENT_SCALE as f64).round() as u32
))
}
}
}
@ -700,28 +634,9 @@ impl TryFrom<f32> for Percent {
if v < 0.0 || v > 1.0 {
Err(TryPercentFromFloatError(()))
} else {
Ok(Percent(Some(
(v * ffi::GST_FORMAT_PERCENT_SCALE as f32).round() as u32,
)))
Ok(Percent(
(v * ffi::GST_FORMAT_PERCENT_SCALE as f32).round() as u32
))
}
}
}
#[cfg(test)]
mod tests {
#[test]
fn test_clock_time() {
crate::init().unwrap();
let t1 = crate::SECOND;
let t2 = 2 * t1;
let t3 = &t1 * 2;
let mut t4 = t2 + t3;
t4 += &t1;
assert_eq!(t4.nanoseconds(), Some(5_000_000_000));
let t5 = t4 - 6 * crate::SECOND;
assert!(t5.is_none());
}
}

View file

@ -19,7 +19,7 @@ macro_rules! impl_ser_de(
impl<'de> Deserialize<'de> for $t {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
skip_assert_initialized!();
Option::<u64>::deserialize(deserializer).map($t)
u64::deserialize(deserializer).map($t)
}
}
}
@ -51,7 +51,7 @@ impl Serialize for Percent {
impl<'de> Deserialize<'de> for Percent {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
skip_assert_initialized!();
Option::<u32>::deserialize(deserializer).map(Percent)
u32::deserialize(deserializer).map(Percent)
}
}
@ -69,43 +69,43 @@ mod tests {
let pretty_config = ron::ser::PrettyConfig::new().with_new_line("".to_string());
let value = GenericFormattedValue::Undefined(Undefined::from(42));
let value = GenericFormattedValue::from(Undefined(42));
let res = ron::ser::to_string_pretty(&value, pretty_config.clone());
assert_eq!(Ok("Undefined(42)".to_owned()), res);
let res = serde_json::to_string(&value).unwrap();
assert_eq!("{\"Undefined\":42}".to_owned(), res);
let value = GenericFormattedValue::Default(Default::from(42));
let value = GenericFormattedValue::from(Default(42));
let res = ron::ser::to_string_pretty(&value, pretty_config.clone());
assert_eq!(Ok("Default(Some(42))".to_owned()), res);
let res = serde_json::to_string(&value).unwrap();
assert_eq!("{\"Default\":42}".to_owned(), res);
let value = GenericFormattedValue::Default(Default::from(None));
let value = GenericFormattedValue::from(Option::<Default>::None);
let res = ron::ser::to_string_pretty(&value, pretty_config.clone());
assert_eq!(Ok("Default(None)".to_owned()), res);
let res = serde_json::to_string(&value).unwrap();
assert_eq!("{\"Default\":null}".to_owned(), res);
let value = GenericFormattedValue::Bytes(Bytes::from(42));
let value = GenericFormattedValue::from(Bytes(42));
let res = ron::ser::to_string_pretty(&value, pretty_config.clone());
assert_eq!(Ok("Bytes(Some(42))".to_owned()), res);
let res = serde_json::to_string(&value).unwrap();
assert_eq!("{\"Bytes\":42}".to_owned(), res);
let value = GenericFormattedValue::Time(ClockTime::from_nseconds(42_123_456_789));
let value = GenericFormattedValue::from(ClockTime::from_nseconds(42_123_456_789));
let res = ron::ser::to_string_pretty(&value, pretty_config.clone());
assert_eq!(Ok("Time(Some(42123456789))".to_owned()), res);
let res = serde_json::to_string(&value).unwrap();
assert_eq!("{\"Time\":42123456789}".to_owned(), res);
let value = GenericFormattedValue::Buffers(Buffers::from(42));
let value = GenericFormattedValue::from(Buffers(42));
let res = ron::ser::to_string_pretty(&value, pretty_config.clone());
assert_eq!(Ok("Buffers(Some(42))".to_owned()), res);
let res = serde_json::to_string(&value).unwrap();
assert_eq!("{\"Buffers\":42}".to_owned(), res);
let value = GenericFormattedValue::Percent(Percent::try_from(0.42).unwrap());
let value = GenericFormattedValue::from(Percent::try_from(0.42).unwrap());
let res = ron::ser::to_string_pretty(&value, pretty_config.clone());
assert_eq!(Ok("Percent(Some(4200))".to_owned()), res);
let res = serde_json::to_string(&value).unwrap();
@ -130,11 +130,11 @@ mod tests {
let value_ron = "Default(Some(42))";
let value_de: GenericFormattedValue = ron::de::from_str(value_ron).unwrap();
assert_eq!(value_de, GenericFormattedValue::Default(Default::from(42)));
assert_eq!(value_de, GenericFormattedValue::from(Default(42)));
let value_json = "{\"Default\":42}";
let value_de: GenericFormattedValue = serde_json::from_str(value_json).unwrap();
assert_eq!(value_de, GenericFormattedValue::Default(Default::from(42)));
assert_eq!(value_de, GenericFormattedValue::from(Default(42)));
let value_ron = "Other(Percent, 42)";
let value_de: GenericFormattedValue = ron::de::from_str(value_ron).unwrap();
@ -158,13 +158,13 @@ mod tests {
);
test_roundrip!(GenericFormattedValue::Undefined(Undefined::from(42)));
test_roundrip!(GenericFormattedValue::Default(Default::from(42)));
test_roundrip!(GenericFormattedValue::Bytes(Bytes(Some(42))));
test_roundrip!(GenericFormattedValue::Time(ClockTime::from_nseconds(
test_roundrip!(GenericFormattedValue::from(Default(42)));
test_roundrip!(GenericFormattedValue::from(Bytes(42)));
test_roundrip!(GenericFormattedValue::from(ClockTime::from_nseconds(
42_123_456_789
)));
test_roundrip!(GenericFormattedValue::Buffers(Buffers::from(42)));
test_roundrip!(GenericFormattedValue::Percent(
test_roundrip!(GenericFormattedValue::from(Buffers(42)));
test_roundrip!(GenericFormattedValue::from(
Percent::try_from(0.42).unwrap()
));
test_roundrip!(GenericFormattedValue::Other(Format::Percent, 42));

View file

@ -202,7 +202,10 @@ mod typefind;
pub use crate::typefind::*;
pub mod format;
pub use crate::format::{FormattedValue, GenericFormattedValue, SpecificFormattedValue};
pub use crate::format::{
FormattedValue, FormattedValueIntrinsic, GenericFormattedValue, SpecificFormattedValue,
SpecificFormattedValueIntrinsic,
};
#[cfg(feature = "ser_de")]
mod format_serde;
@ -230,6 +233,8 @@ pub use crate::param_spec::*;
pub mod functions;
pub use crate::functions::*;
mod utils;
use std::ptr;
#[doc(alias = "gst_init_check")]
@ -259,22 +264,6 @@ pub unsafe fn deinit() {
ffi::gst_deinit();
}
pub const BUFFER_OFFSET_NONE: u64 = ffi::GST_BUFFER_OFFSET_NONE;
pub const CLOCK_TIME_NONE: ClockTime = ClockTime(None);
pub const SECOND: ClockTime = ClockTime(Some(1_000_000_000));
pub const MSECOND: ClockTime = ClockTime(Some(1_000_000));
pub const USECOND: ClockTime = ClockTime(Some(1_000));
pub const NSECOND: ClockTime = ClockTime(Some(1));
pub const SECOND_VAL: u64 = 1_000_000_000;
pub const MSECOND_VAL: u64 = 1_000_000;
pub const USECOND_VAL: u64 = 1_000;
pub const NSECOND_VAL: u64 = 1;
pub const FORMAT_PERCENT_MAX: u32 = ffi::GST_FORMAT_PERCENT_MAX as u32;
pub const FORMAT_PERCENT_SCALE: u32 = ffi::GST_FORMAT_PERCENT_SCALE as u32;
pub const PARAM_FLAG_CONTROLLABLE: glib::ParamFlags = glib::ParamFlags::USER_1;
pub const PARAM_FLAG_MUTABLE_READY: glib::ParamFlags = glib::ParamFlags::USER_2;
pub const PARAM_FLAG_MUTABLE_PAUSED: glib::ParamFlags = glib::ParamFlags::USER_3;
@ -333,10 +322,12 @@ pub mod prelude {
pub use muldiv::MulDiv;
pub use crate::format::{FormattedValue, SpecificFormattedValue};
pub use crate::format::{
FormattedValue, FormattedValueIntrinsic, SpecificFormattedValue,
SpecificFormattedValueIntrinsic,
};
pub use crate::utils::Displayable;
}
mod utils;
#[macro_use]
pub mod subclass;

View file

@ -956,7 +956,7 @@ impl<'a> AsyncDone<'a> {
}
#[doc(alias = "get_running_time")]
pub fn running_time(&self) -> crate::ClockTime {
pub fn running_time(&self) -> Option<crate::ClockTime> {
unsafe {
let mut running_time = mem::MaybeUninit::uninit();
@ -1079,10 +1079,10 @@ impl<'a> Qos<'a> {
&self,
) -> (
bool,
crate::ClockTime,
crate::ClockTime,
crate::ClockTime,
crate::ClockTime,
Option<crate::ClockTime>,
Option<crate::ClockTime>,
Option<crate::ClockTime>,
Option<crate::ClockTime>,
) {
unsafe {
let mut live = mem::MaybeUninit::uninit();
@ -1241,7 +1241,7 @@ impl<'a> ResetTime<'a> {
}
#[doc(alias = "get_running_time")]
pub fn running_time(&self) -> crate::ClockTime {
pub fn running_time(&self) -> Option<crate::ClockTime> {
unsafe {
let mut running_time = mem::MaybeUninit::uninit();

View file

@ -377,7 +377,7 @@ impl ReferenceTimestampMeta {
buffer: &'a mut BufferRef,
reference: &Caps,
timestamp: ClockTime,
duration: ClockTime,
duration: impl Into<Option<ClockTime>>,
) -> MetaRefMut<'a, Self, Standalone> {
skip_assert_initialized!();
unsafe {
@ -385,7 +385,7 @@ impl ReferenceTimestampMeta {
buffer.as_mut_ptr(),
reference.to_glib_none().0,
timestamp.into_glib(),
duration.into_glib(),
duration.into().into_glib(),
);
Self::from_mut_ptr(buffer, meta)
@ -403,12 +403,12 @@ impl ReferenceTimestampMeta {
}
#[doc(alias = "get_timestamp")]
pub fn timestamp(&self) -> ClockTime {
pub fn timestamp(&self) -> Option<ClockTime> {
unsafe { from_glib(self.0.timestamp) }
}
#[doc(alias = "get_duration")]
pub fn duration(&self) -> ClockTime {
pub fn duration(&self) -> Option<ClockTime> {
unsafe { from_glib(self.0.duration) }
}
}
@ -428,10 +428,12 @@ unsafe impl MetaAPI for ReferenceTimestampMeta {
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))]
impl fmt::Debug for ReferenceTimestampMeta {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use crate::utils::Displayable;
f.debug_struct("ReferenceTimestampMeta")
.field("reference", &self.reference())
.field("timestamp", &self.timestamp())
.field("duration", &self.duration())
.field("timestamp", &self.timestamp().display().to_string())
.field("duration", &self.duration().display().to_string())
.finish()
}
}

View file

@ -16,8 +16,8 @@ use crate::PadProbeReturn;
use crate::PadProbeType;
use crate::Query;
use crate::QueryRef;
use crate::SpecificFormattedValue;
use crate::StaticPadTemplate;
use crate::{SpecificFormattedValue, SpecificFormattedValueIntrinsic};
use std::cell::RefCell;
use std::mem;
@ -243,11 +243,11 @@ pub trait PadExtManual: 'static {
) -> Option<GenericFormattedValue>;
#[doc(alias = "gst_pad_peer_query_duration")]
fn peer_query_duration<T: SpecificFormattedValue>(&self) -> Option<T>;
fn peer_query_duration<T: SpecificFormattedValueIntrinsic>(&self) -> Option<T>;
fn peer_query_duration_generic(&self, format: Format) -> Option<GenericFormattedValue>;
#[doc(alias = "gst_pad_peer_query_position")]
fn peer_query_position<T: SpecificFormattedValue>(&self) -> Option<T>;
fn peer_query_position<T: SpecificFormattedValueIntrinsic>(&self) -> Option<T>;
fn peer_query_position_generic(&self, format: Format) -> Option<GenericFormattedValue>;
#[doc(alias = "gst_pad_query_convert")]
@ -262,11 +262,11 @@ pub trait PadExtManual: 'static {
) -> Option<GenericFormattedValue>;
#[doc(alias = "gst_pad_query_duration")]
fn query_duration<T: SpecificFormattedValue>(&self) -> Option<T>;
fn query_duration<T: SpecificFormattedValueIntrinsic>(&self) -> Option<T>;
fn query_duration_generic(&self, format: Format) -> Option<GenericFormattedValue>;
#[doc(alias = "gst_pad_query_position")]
fn query_position<T: SpecificFormattedValue>(&self) -> Option<T>;
fn query_position<T: SpecificFormattedValueIntrinsic>(&self) -> Option<T>;
fn query_position_generic(&self, format: Format) -> Option<GenericFormattedValue>;
#[doc(alias = "get_mode")]
@ -734,7 +734,7 @@ impl<O: IsA<Pad>> PadExtManual for O {
let ret = from_glib(ffi::gst_pad_peer_query_convert(
self.as_ref().to_glib_none().0,
src_val.format().into_glib(),
src_val.to_raw_value(),
src_val.into_raw_value(),
U::default_format().into_glib(),
dest_val.as_mut_ptr(),
));
@ -757,7 +757,7 @@ impl<O: IsA<Pad>> PadExtManual for O {
let ret = from_glib(ffi::gst_pad_peer_query_convert(
self.as_ref().to_glib_none().0,
src_val.format().into_glib(),
src_val.to_raw_value(),
src_val.into_raw_value(),
dest_format.into_glib(),
dest_val.as_mut_ptr(),
));
@ -772,16 +772,16 @@ impl<O: IsA<Pad>> PadExtManual for O {
}
}
fn peer_query_duration<T: SpecificFormattedValue>(&self) -> Option<T> {
fn peer_query_duration<T: SpecificFormattedValueIntrinsic>(&self) -> Option<T> {
unsafe {
let mut duration = mem::MaybeUninit::uninit();
let ret = from_glib(ffi::gst_pad_peer_query_duration(
self.as_ref().to_glib_none().0,
T::default_format().into_glib(),
T::FormattedValueType::default_format().into_glib(),
duration.as_mut_ptr(),
));
if ret {
Some(T::from_raw(T::default_format(), duration.assume_init()))
try_from_glib(duration.assume_init()).ok()
} else {
None
}
@ -804,16 +804,16 @@ impl<O: IsA<Pad>> PadExtManual for O {
}
}
fn peer_query_position<T: SpecificFormattedValue>(&self) -> Option<T> {
fn peer_query_position<T: SpecificFormattedValueIntrinsic>(&self) -> Option<T> {
unsafe {
let mut cur = mem::MaybeUninit::uninit();
let ret = from_glib(ffi::gst_pad_peer_query_position(
self.as_ref().to_glib_none().0,
T::default_format().into_glib(),
T::FormattedValueType::default_format().into_glib(),
cur.as_mut_ptr(),
));
if ret {
Some(T::from_raw(T::default_format(), cur.assume_init()))
try_from_glib(cur.assume_init()).ok()
} else {
None
}
@ -847,7 +847,7 @@ impl<O: IsA<Pad>> PadExtManual for O {
let ret = from_glib(ffi::gst_pad_query_convert(
self.as_ref().to_glib_none().0,
src_val.format().into_glib(),
src_val.to_raw_value(),
src_val.into_raw_value(),
U::default_format().into_glib(),
dest_val.as_mut_ptr(),
));
@ -886,16 +886,16 @@ impl<O: IsA<Pad>> PadExtManual for O {
}
}
fn query_duration<T: SpecificFormattedValue>(&self) -> Option<T> {
fn query_duration<T: SpecificFormattedValueIntrinsic>(&self) -> Option<T> {
unsafe {
let mut duration = mem::MaybeUninit::uninit();
let ret = from_glib(ffi::gst_pad_query_duration(
self.as_ref().to_glib_none().0,
T::default_format().into_glib(),
T::FormattedValueType::default_format().into_glib(),
duration.as_mut_ptr(),
));
if ret {
Some(T::from_raw(T::default_format(), duration.assume_init()))
try_from_glib(duration.assume_init()).ok()
} else {
None
}
@ -918,16 +918,16 @@ impl<O: IsA<Pad>> PadExtManual for O {
}
}
fn query_position<T: SpecificFormattedValue>(&self) -> Option<T> {
fn query_position<T: SpecificFormattedValueIntrinsic>(&self) -> Option<T> {
unsafe {
let mut cur = mem::MaybeUninit::uninit();
let ret = from_glib(ffi::gst_pad_query_position(
self.as_ref().to_glib_none().0,
T::default_format().into_glib(),
T::FormattedValueType::default_format().into_glib(),
cur.as_mut_ptr(),
));
if ret {
Some(T::from_raw(T::default_format(), cur.assume_init()))
try_from_glib(cur.assume_init()).ok()
} else {
None
}

View file

@ -324,7 +324,7 @@ impl Default for Latency<Query> {
impl<T: AsPtr> Latency<T> {
#[doc(alias = "get_result")]
pub fn result(&self) -> (bool, crate::ClockTime, crate::ClockTime) {
pub fn result(&self) -> (bool, Option<crate::ClockTime>, Option<crate::ClockTime>) {
unsafe {
let mut live = mem::MaybeUninit::uninit();
let mut min = mem::MaybeUninit::uninit();
@ -1428,6 +1428,7 @@ declare_concrete_query!(Other, T);
#[cfg(test)]
mod tests {
use super::*;
use crate::ClockTime;
use std::convert::TryInto;
#[test]
@ -1439,10 +1440,10 @@ mod tests {
match query.view_mut() {
QueryView::Position(ref mut p) => {
let pos = p.result();
assert_eq!(pos.try_into(), Ok(crate::CLOCK_TIME_NONE));
p.set(3 * crate::SECOND);
assert_eq!(pos.try_into(), Ok(ClockTime::NONE));
p.set(Some(3 * ClockTime::SECOND));
let pos = p.result();
assert_eq!(pos.try_into(), Ok(3 * crate::SECOND));
assert_eq!(pos.try_into(), Ok(Some(3 * ClockTime::SECOND)));
}
_ => panic!("Wrong concrete Query in Query"),
}
@ -1453,7 +1454,7 @@ mod tests {
match query.view() {
QueryView::Position(ref p) => {
let pos = p.result();
assert_eq!(pos.try_into(), Ok(3 * crate::SECOND));
assert_eq!(pos.try_into(), Ok(Some(3 * ClockTime::SECOND)));
unsafe {
assert!(!p.as_mut_ptr().is_null());
}
@ -1464,7 +1465,7 @@ mod tests {
let mut p = Position::new(crate::Format::Time);
let pos = p.result();
assert_eq!(pos.try_into(), Ok(crate::CLOCK_TIME_NONE));
assert_eq!(pos.try_into(), Ok(ClockTime::NONE));
p.structure_mut().set("check_mut", &true);
@ -1494,12 +1495,12 @@ mod tests {
let query = query.make_mut();
if let QueryView::Duration(d) = &mut query.view_mut() {
d.set(2 * crate::SECOND);
d.set(Some(2 * ClockTime::SECOND));
}
if let QueryView::Duration(d) = &query.view() {
let duration = d.result();
assert_eq!(duration.try_into(), Ok(2 * crate::SECOND));
assert_eq!(duration.try_into(), Ok(Some(2 * ClockTime::SECOND)));
}
}

View file

@ -12,7 +12,7 @@ use crate::BufferRef;
use crate::Caps;
use crate::CapsRef;
use crate::FormattedSegment;
use crate::FormattedValue;
use crate::FormattedValueIntrinsic;
use crate::Segment;
use crate::Structure;
use crate::StructureRef;
@ -54,7 +54,7 @@ impl<'a> SampleBuilder<'a> {
}
}
pub fn segment<F: FormattedValue>(self, segment: &'a FormattedSegment<F>) -> Self {
pub fn segment<F: FormattedValueIntrinsic>(self, segment: &'a FormattedSegment<F>) -> Self {
Self {
segment: Some(segment.upcast_ref()),
..self

View file

@ -96,10 +96,10 @@ mod tests {
let mut buffer = Buffer::from_slice(vec![1, 2, 3, 4]);
{
let buffer = buffer.get_mut().unwrap();
buffer.set_pts(1.into());
buffer.set_pts(Some(ClockTime::NSECOND));
buffer.set_offset(0);
buffer.set_offset_end(4);
buffer.set_duration(4.into());
buffer.set_duration(Some(4 * ClockTime::NSECOND));
}
let caps = Caps::builder("sample/caps")
@ -112,13 +112,13 @@ mod tests {
segment.set_rate(1f64);
segment.set_applied_rate(0.9f64);
segment.set_format(Format::Time);
segment.set_base(GenericFormattedValue::Time(ClockTime::from_nseconds(123)));
segment.set_offset(GenericFormattedValue::Time(ClockTime::from_nseconds(42)));
segment.set_start(GenericFormattedValue::Time(ClockTime::from_nseconds(1024)));
segment.set_stop(GenericFormattedValue::Time(ClockTime::from_nseconds(2048)));
segment.set_time(GenericFormattedValue::Time(ClockTime::from_nseconds(1042)));
segment.set_position(GenericFormattedValue::Time(ClockTime::from_nseconds(256)));
segment.set_duration(GenericFormattedValue::Time(ClockTime::none()));
segment.set_base(GenericFormattedValue::from(ClockTime::from_nseconds(123)));
segment.set_offset(GenericFormattedValue::from(ClockTime::from_nseconds(42)));
segment.set_start(GenericFormattedValue::from(ClockTime::from_nseconds(1024)));
segment.set_stop(GenericFormattedValue::from(ClockTime::from_nseconds(2048)));
segment.set_time(GenericFormattedValue::from(ClockTime::from_nseconds(1042)));
segment.set_position(GenericFormattedValue::from(ClockTime::from_nseconds(256)));
segment.set_duration(GenericFormattedValue::from(ClockTime::NONE));
let info = Structure::builder("sample.info")
.field("f3", &123i32)
@ -182,10 +182,10 @@ mod tests {
let mut buffer = Buffer::from_slice(vec![1, 2, 3, 4]);
{
let buffer = buffer.get_mut().unwrap();
buffer.set_pts(1.into());
buffer.set_pts(Some(ClockTime::NSECOND));
buffer.set_offset(0);
buffer.set_offset_end(4);
buffer.set_duration(4.into());
buffer.set_duration(Some(4 * ClockTime::NSECOND));
}
Sample::builder().buffer(&buffer).build()
};
@ -277,7 +277,7 @@ mod tests {
)"#;
let sample: Sample = ron::de::from_str(buffer_ron).unwrap();
let buffer = sample.buffer().unwrap();
assert_eq!(buffer.pts(), 1.into());
assert_eq!(buffer.pts(), Some(ClockTime::NSECOND));
assert_eq!(buffer.offset_end(), 4);
{
let data = buffer.map_readable().unwrap();
@ -326,10 +326,10 @@ mod tests {
let mut buffer = Buffer::from_slice(vec![1, 2, 3, 4]);
{
let buffer = buffer.get_mut().unwrap();
buffer.set_pts(1.into());
buffer.set_pts(Some(ClockTime::NSECOND));
buffer.set_offset(0);
buffer.set_offset_end(4);
buffer.set_duration(4.into());
buffer.set_duration(Some(4 * ClockTime::NSECOND));
}
let caps = Caps::builder("sample/caps")
@ -342,13 +342,13 @@ mod tests {
segment.set_rate(1f64);
segment.set_applied_rate(0.9f64);
segment.set_format(Format::Time);
segment.set_base(GenericFormattedValue::Time(ClockTime::from_nseconds(123)));
segment.set_offset(GenericFormattedValue::Time(ClockTime::from_nseconds(42)));
segment.set_start(GenericFormattedValue::Time(ClockTime::from_nseconds(1024)));
segment.set_stop(GenericFormattedValue::Time(ClockTime::from_nseconds(2048)));
segment.set_time(GenericFormattedValue::Time(ClockTime::from_nseconds(1042)));
segment.set_position(GenericFormattedValue::Time(ClockTime::from_nseconds(256)));
segment.set_duration(GenericFormattedValue::Time(ClockTime::none()));
segment.set_base(GenericFormattedValue::from(ClockTime::from_nseconds(123)));
segment.set_offset(GenericFormattedValue::from(ClockTime::from_nseconds(42)));
segment.set_start(GenericFormattedValue::from(ClockTime::from_nseconds(1024)));
segment.set_stop(GenericFormattedValue::from(ClockTime::from_nseconds(2048)));
segment.set_time(GenericFormattedValue::from(ClockTime::from_nseconds(1042)));
segment.set_position(GenericFormattedValue::from(ClockTime::from_nseconds(256)));
segment.set_duration(GenericFormattedValue::from(ClockTime::NONE));
let info = Structure::builder("sample.info")
.field("f3", &123i32)
@ -364,7 +364,7 @@ mod tests {
let sample_ser = ron::ser::to_string(&sample).unwrap();
let sample_de: Sample = ron::de::from_str(sample_ser.as_str()).unwrap();
let buffer_de = sample_de.buffer().unwrap();
assert_eq!(buffer_de.pts(), 1.into());
assert_eq!(buffer_de.pts(), Some(ClockTime::NSECOND));
assert_eq!(buffer_de.offset_end(), 4);
{
let data = buffer_de.map_readable().unwrap();

View file

@ -1,10 +1,10 @@
// Take a look at the license at the top of the repository in the LICENSE file.
use crate::Format;
use crate::FormattedValue;
use crate::GenericFormattedValue;
use crate::SeekFlags;
use crate::SeekType;
use crate::{FormattedValue, FormattedValueIntrinsic};
use glib::translate::*;
use glib::StaticType;
use std::fmt;
@ -15,7 +15,7 @@ use std::ptr;
pub type Segment = FormattedSegment<GenericFormattedValue>;
#[repr(transparent)]
#[doc(alias = "GstSegment")]
pub struct FormattedSegment<T: FormattedValue>(ffi::GstSegment, PhantomData<T>);
pub struct FormattedSegment<T: FormattedValueIntrinsic>(ffi::GstSegment, PhantomData<T>);
impl Segment {
pub fn reset_with_format(&mut self, format: Format) {
@ -28,16 +28,20 @@ impl Segment {
self.0.format = format.into_glib();
}
pub fn downcast<T: FormattedValue>(self) -> Result<FormattedSegment<T>, Self> {
if T::default_format() == Format::Undefined || T::default_format() == self.format() {
pub fn downcast<T: FormattedValueIntrinsic>(self) -> Result<FormattedSegment<T>, Self> {
if T::FormattedValueType::default_format() == Format::Undefined
|| T::FormattedValueType::default_format() == self.format()
{
Ok(FormattedSegment(self.0, PhantomData))
} else {
Err(self)
}
}
pub fn downcast_ref<T: FormattedValue>(&self) -> Option<&FormattedSegment<T>> {
if T::default_format() == Format::Undefined || T::default_format() == self.format() {
pub fn downcast_ref<T: FormattedValueIntrinsic>(&self) -> Option<&FormattedSegment<T>> {
if T::FormattedValueType::default_format() == Format::Undefined
|| T::FormattedValueType::default_format() == self.format()
{
Some(unsafe {
&*(self as *const FormattedSegment<GenericFormattedValue>
as *const FormattedSegment<T>)
@ -47,8 +51,10 @@ impl Segment {
}
}
pub fn downcast_mut<T: FormattedValue>(&mut self) -> Option<&mut FormattedSegment<T>> {
if T::default_format() == Format::Undefined || T::default_format() == self.format() {
pub fn downcast_mut<T: FormattedValueIntrinsic>(&mut self) -> Option<&mut FormattedSegment<T>> {
if T::FormattedValueType::default_format() == Format::Undefined
|| T::FormattedValueType::default_format() == self.format()
{
Some(unsafe {
&mut *(self as *mut FormattedSegment<GenericFormattedValue>
as *mut FormattedSegment<T>)
@ -59,12 +65,15 @@ impl Segment {
}
}
impl<T: FormattedValue> FormattedSegment<T> {
impl<T: FormattedValueIntrinsic> FormattedSegment<T> {
pub fn new() -> Self {
assert_initialized_main_thread!();
let segment = unsafe {
let mut segment = mem::MaybeUninit::zeroed();
ffi::gst_segment_init(segment.as_mut_ptr(), T::default_format().into_glib());
ffi::gst_segment_init(
segment.as_mut_ptr(),
T::FormattedValueType::default_format().into_glib(),
);
segment.assume_init()
};
FormattedSegment(segment, PhantomData)
@ -82,16 +91,23 @@ impl<T: FormattedValue> FormattedSegment<T> {
pub fn reset(&mut self) {
unsafe {
ffi::gst_segment_init(&mut self.0, T::default_format().into_glib());
ffi::gst_segment_init(
&mut self.0,
T::FormattedValueType::default_format().into_glib(),
);
}
}
#[doc(alias = "gst_segment_clip")]
pub fn clip<V: Into<T>>(&self, start: V, stop: V) -> Option<(T, T)> {
pub fn clip<V: Into<T::FormattedValueType>>(
&self,
start: V,
stop: V,
) -> Option<(T::FormattedValueType, T::FormattedValueType)> {
let start = start.into();
let stop = stop.into();
if T::default_format() == Format::Undefined {
if T::FormattedValueType::default_format() == Format::Undefined {
assert_eq!(self.format(), start.format());
assert_eq!(self.format(), stop.format());
}
@ -102,15 +118,15 @@ impl<T: FormattedValue> FormattedSegment<T> {
let ret = from_glib(ffi::gst_segment_clip(
&self.0,
start.format().into_glib(),
start.to_raw_value() as u64,
stop.to_raw_value() as u64,
start.into_raw_value() as u64,
stop.into_raw_value() as u64,
clip_start.as_mut_ptr(),
clip_stop.as_mut_ptr(),
));
if ret {
Some((
T::from_raw(self.format(), clip_start.assume_init() as i64),
T::from_raw(self.format(), clip_stop.assume_init() as i64),
T::FormattedValueType::from_raw(self.format(), clip_start.assume_init() as i64),
T::FormattedValueType::from_raw(self.format(), clip_stop.assume_init() as i64),
))
} else {
None
@ -120,7 +136,7 @@ impl<T: FormattedValue> FormattedSegment<T> {
#[allow(clippy::too_many_arguments)]
#[doc(alias = "gst_segment_do_seek")]
pub fn do_seek<V: Into<T>>(
pub fn do_seek<V: Into<T::FormattedValueType>>(
&mut self,
rate: f64,
flags: SeekFlags,
@ -133,7 +149,7 @@ impl<T: FormattedValue> FormattedSegment<T> {
let start = start.into();
let stop = stop.into();
if T::default_format() == Format::Undefined {
if T::FormattedValueType::default_format() == Format::Undefined {
assert_eq!(self.format(), start.format());
assert_eq!(self.format(), stop.format());
}
@ -146,9 +162,9 @@ impl<T: FormattedValue> FormattedSegment<T> {
self.format().into_glib(),
flags.into_glib(),
start_type.into_glib(),
start.to_raw_value() as u64,
start.into_raw_value() as u64,
stop_type.into_glib(),
stop.to_raw_value() as u64,
stop.into_raw_value() as u64,
update.as_mut_ptr(),
));
if ret {
@ -174,30 +190,36 @@ impl<T: FormattedValue> FormattedSegment<T> {
}
#[doc(alias = "gst_segment_position_from_running_time")]
pub fn position_from_running_time<V: Into<T>>(&self, running_time: V) -> T {
pub fn position_from_running_time<V: Into<T::FormattedValueType>>(
&self,
running_time: V,
) -> T::FormattedValueType {
let running_time = running_time.into();
if T::default_format() == Format::Undefined {
if T::FormattedValueType::default_format() == Format::Undefined {
assert_eq!(self.format(), running_time.format());
}
unsafe {
T::from_raw(
T::FormattedValueType::from_raw(
self.format(),
ffi::gst_segment_position_from_running_time(
&self.0,
self.format().into_glib(),
running_time.to_raw_value() as u64,
running_time.into_raw_value() as u64,
) as i64,
)
}
}
#[doc(alias = "gst_segment_position_from_running_time_full")]
pub fn position_from_running_time_full<V: Into<T>>(&self, running_time: V) -> (i32, T) {
pub fn position_from_running_time_full<V: Into<T::FormattedValueType>>(
&self,
running_time: V,
) -> (i32, T::FormattedValueType) {
let running_time = running_time.into();
if T::default_format() == Format::Undefined {
if T::FormattedValueType::default_format() == Format::Undefined {
assert_eq!(self.format(), running_time.format());
}
@ -206,41 +228,47 @@ impl<T: FormattedValue> FormattedSegment<T> {
let ret = ffi::gst_segment_position_from_running_time_full(
&self.0,
self.format().into_glib(),
running_time.to_raw_value() as u64,
running_time.into_raw_value() as u64,
position.as_mut_ptr(),
);
(
ret,
T::from_raw(self.format(), position.assume_init() as i64),
T::FormattedValueType::from_raw(self.format(), position.assume_init() as i64),
)
}
}
#[doc(alias = "gst_segment_position_from_stream_time")]
pub fn position_from_stream_time<V: Into<T>>(&self, stream_time: V) -> T {
pub fn position_from_stream_time<V: Into<T::FormattedValueType>>(
&self,
stream_time: V,
) -> T::FormattedValueType {
let stream_time = stream_time.into();
if T::default_format() == Format::Undefined {
if T::FormattedValueType::default_format() == Format::Undefined {
assert_eq!(self.format(), stream_time.format());
}
unsafe {
T::from_raw(
T::FormattedValueType::from_raw(
self.format(),
ffi::gst_segment_position_from_stream_time(
&self.0,
self.format().into_glib(),
stream_time.to_raw_value() as u64,
stream_time.into_raw_value() as u64,
) as i64,
)
}
}
#[doc(alias = "gst_segment_position_from_stream_time_full")]
pub fn position_from_stream_time_full<V: Into<T>>(&self, stream_time: V) -> (i32, T) {
pub fn position_from_stream_time_full<V: Into<T::FormattedValueType>>(
&self,
stream_time: V,
) -> (i32, T::FormattedValueType) {
let stream_time = stream_time.into();
if T::default_format() == Format::Undefined {
if T::FormattedValueType::default_format() == Format::Undefined {
assert_eq!(self.format(), stream_time.format());
}
@ -249,21 +277,24 @@ impl<T: FormattedValue> FormattedSegment<T> {
let ret = ffi::gst_segment_position_from_stream_time_full(
&self.0,
self.format().into_glib(),
stream_time.to_raw_value() as u64,
stream_time.into_raw_value() as u64,
position.as_mut_ptr(),
);
(
ret,
T::from_raw(self.format(), position.assume_init() as i64),
T::FormattedValueType::from_raw(self.format(), position.assume_init() as i64),
)
}
}
#[doc(alias = "gst_segment_set_running_time")]
pub fn set_running_time<V: Into<T>>(&mut self, running_time: V) -> Result<(), glib::BoolError> {
pub fn set_running_time<V: Into<T::FormattedValueType>>(
&mut self,
running_time: V,
) -> Result<(), glib::BoolError> {
let running_time = running_time.into();
if T::default_format() == Format::Undefined {
if T::FormattedValueType::default_format() == Format::Undefined {
assert_eq!(self.format(), running_time.format());
}
@ -272,7 +303,7 @@ impl<T: FormattedValue> FormattedSegment<T> {
ffi::gst_segment_set_running_time(
&mut self.0,
self.format().into_glib(),
running_time.to_raw_value() as u64,
running_time.into_raw_value() as u64,
),
"Running time is not in the segment"
)
@ -280,30 +311,36 @@ impl<T: FormattedValue> FormattedSegment<T> {
}
#[doc(alias = "gst_segment_to_running_time")]
pub fn to_running_time<V: Into<T>>(&self, position: V) -> T {
pub fn to_running_time<V: Into<T::FormattedValueType>>(
&self,
position: V,
) -> T::FormattedValueType {
let position = position.into();
if T::default_format() == Format::Undefined {
if T::FormattedValueType::default_format() == Format::Undefined {
assert_eq!(self.format(), position.format());
}
unsafe {
T::from_raw(
T::FormattedValueType::from_raw(
self.format(),
ffi::gst_segment_to_running_time(
&self.0,
self.format().into_glib(),
position.to_raw_value() as u64,
position.into_raw_value() as u64,
) as i64,
)
}
}
#[doc(alias = "gst_segment_to_running_time_full")]
pub fn to_running_time_full<V: Into<T>>(&self, position: V) -> (i32, T) {
pub fn to_running_time_full<V: Into<T::FormattedValueType>>(
&self,
position: V,
) -> (i32, T::FormattedValueType) {
let position = position.into();
if T::default_format() == Format::Undefined {
if T::FormattedValueType::default_format() == Format::Undefined {
assert_eq!(self.format(), position.format());
}
@ -312,41 +349,47 @@ impl<T: FormattedValue> FormattedSegment<T> {
let ret = ffi::gst_segment_to_running_time_full(
&self.0,
self.format().into_glib(),
position.to_raw_value() as u64,
position.into_raw_value() as u64,
running_time.as_mut_ptr(),
);
(
ret,
T::from_raw(self.format(), running_time.assume_init() as i64),
T::FormattedValueType::from_raw(self.format(), running_time.assume_init() as i64),
)
}
}
#[doc(alias = "gst_segment_to_stream_time")]
pub fn to_stream_time<V: Into<T>>(&self, position: V) -> T {
pub fn to_stream_time<V: Into<T::FormattedValueType>>(
&self,
position: V,
) -> T::FormattedValueType {
let position = position.into();
if T::default_format() == Format::Undefined {
if T::FormattedValueType::default_format() == Format::Undefined {
assert_eq!(self.format(), position.format());
}
unsafe {
T::from_raw(
T::FormattedValueType::from_raw(
self.format(),
ffi::gst_segment_to_stream_time(
&self.0,
self.format().into_glib(),
position.to_raw_value() as u64,
position.into_raw_value() as u64,
) as i64,
)
}
}
#[doc(alias = "gst_segment_to_stream_time_full")]
pub fn to_stream_time_full<V: Into<T>>(&self, position: V) -> (i32, T) {
pub fn to_stream_time_full<V: Into<T::FormattedValueType>>(
&self,
position: V,
) -> (i32, T::FormattedValueType) {
let position = position.into();
if T::default_format() == Format::Undefined {
if T::FormattedValueType::default_format() == Format::Undefined {
assert_eq!(self.format(), position.format());
}
@ -355,12 +398,12 @@ impl<T: FormattedValue> FormattedSegment<T> {
let ret = ffi::gst_segment_to_stream_time_full(
&self.0,
self.format().into_glib(),
position.to_raw_value() as u64,
position.into_raw_value() as u64,
stream_time.as_mut_ptr(),
);
(
ret,
T::from_raw(self.format(), stream_time.assume_init() as i64),
T::FormattedValueType::from_raw(self.format(), stream_time.assume_init() as i64),
)
}
}
@ -402,112 +445,112 @@ impl<T: FormattedValue> FormattedSegment<T> {
}
#[doc(alias = "get_base")]
pub fn base(&self) -> T {
unsafe { T::from_raw(self.format(), self.0.base as i64) }
pub fn base(&self) -> T::FormattedValueType {
unsafe { T::FormattedValueType::from_raw(self.format(), self.0.base as i64) }
}
pub fn set_base<V: Into<T>>(&mut self, base: V) {
pub fn set_base<V: Into<T::FormattedValueType>>(&mut self, base: V) {
let base = base.into();
if T::default_format() == Format::Undefined {
if T::FormattedValueType::default_format() == Format::Undefined {
assert_eq!(self.format(), base.format());
}
self.0.base = unsafe { base.to_raw_value() } as u64;
self.0.base = unsafe { base.into_raw_value() } as u64;
}
#[doc(alias = "get_offset")]
pub fn offset(&self) -> T {
unsafe { T::from_raw(self.format(), self.0.offset as i64) }
pub fn offset(&self) -> T::FormattedValueType {
unsafe { T::FormattedValueType::from_raw(self.format(), self.0.offset as i64) }
}
pub fn set_offset<V: Into<T>>(&mut self, offset: V) {
pub fn set_offset<V: Into<T::FormattedValueType>>(&mut self, offset: V) {
let offset = offset.into();
if T::default_format() == Format::Undefined {
if T::FormattedValueType::default_format() == Format::Undefined {
assert_eq!(self.format(), offset.format());
}
self.0.offset = unsafe { offset.to_raw_value() } as u64;
self.0.offset = unsafe { offset.into_raw_value() } as u64;
}
#[doc(alias = "get_start")]
pub fn start(&self) -> T {
unsafe { T::from_raw(self.format(), self.0.start as i64) }
pub fn start(&self) -> T::FormattedValueType {
unsafe { T::FormattedValueType::from_raw(self.format(), self.0.start as i64) }
}
pub fn set_start<V: Into<T>>(&mut self, start: V) {
pub fn set_start<V: Into<T::FormattedValueType>>(&mut self, start: V) {
let start = start.into();
if T::default_format() == Format::Undefined {
if T::FormattedValueType::default_format() == Format::Undefined {
assert_eq!(self.format(), start.format());
}
self.0.start = unsafe { start.to_raw_value() } as u64;
self.0.start = unsafe { start.into_raw_value() } as u64;
}
#[doc(alias = "get_stop")]
pub fn stop(&self) -> T {
unsafe { T::from_raw(self.format(), self.0.stop as i64) }
pub fn stop(&self) -> T::FormattedValueType {
unsafe { T::FormattedValueType::from_raw(self.format(), self.0.stop as i64) }
}
pub fn set_stop<V: Into<T>>(&mut self, stop: V) {
pub fn set_stop<V: Into<T::FormattedValueType>>(&mut self, stop: V) {
let stop = stop.into();
if T::default_format() == Format::Undefined {
if T::FormattedValueType::default_format() == Format::Undefined {
assert_eq!(self.format(), stop.format());
}
self.0.stop = unsafe { stop.to_raw_value() } as u64;
self.0.stop = unsafe { stop.into_raw_value() } as u64;
}
#[doc(alias = "get_time")]
pub fn time(&self) -> T {
unsafe { T::from_raw(self.format(), self.0.time as i64) }
pub fn time(&self) -> T::FormattedValueType {
unsafe { T::FormattedValueType::from_raw(self.format(), self.0.time as i64) }
}
pub fn set_time<V: Into<T>>(&mut self, time: V) {
pub fn set_time<V: Into<T::FormattedValueType>>(&mut self, time: V) {
let time = time.into();
if T::default_format() == Format::Undefined {
if T::FormattedValueType::default_format() == Format::Undefined {
assert_eq!(self.format(), time.format());
}
self.0.time = unsafe { time.to_raw_value() } as u64;
self.0.time = unsafe { time.into_raw_value() } as u64;
}
#[doc(alias = "get_position")]
pub fn position(&self) -> T {
unsafe { T::from_raw(self.format(), self.0.position as i64) }
pub fn position(&self) -> T::FormattedValueType {
unsafe { T::FormattedValueType::from_raw(self.format(), self.0.position as i64) }
}
pub fn set_position<V: Into<T>>(&mut self, position: V) {
pub fn set_position<V: Into<T::FormattedValueType>>(&mut self, position: V) {
let position = position.into();
if T::default_format() == Format::Undefined {
if T::FormattedValueType::default_format() == Format::Undefined {
assert_eq!(self.format(), position.format());
}
self.0.position = unsafe { position.to_raw_value() } as u64;
self.0.position = unsafe { position.into_raw_value() } as u64;
}
#[doc(alias = "get_duration")]
pub fn duration(&self) -> T {
unsafe { T::from_raw(self.format(), self.0.duration as i64) }
pub fn duration(&self) -> T::FormattedValueType {
unsafe { T::FormattedValueType::from_raw(self.format(), self.0.duration as i64) }
}
pub fn set_duration<V: Into<T>>(&mut self, duration: V) {
pub fn set_duration<V: Into<T::FormattedValueType>>(&mut self, duration: V) {
let duration = duration.into();
if T::default_format() == Format::Undefined {
if T::FormattedValueType::default_format() == Format::Undefined {
assert_eq!(self.format(), duration.format());
}
self.0.duration = unsafe { duration.to_raw_value() } as u64;
self.0.duration = unsafe { duration.into_raw_value() } as u64;
}
}
impl<T: FormattedValue> PartialEq for FormattedSegment<T> {
impl<T: FormattedValueIntrinsic> PartialEq for FormattedSegment<T> {
#[inline]
#[doc(alias = "gst_segment_is_equal")]
fn eq(&self, other: &Self) -> bool {
@ -515,18 +558,18 @@ impl<T: FormattedValue> PartialEq for FormattedSegment<T> {
}
}
impl<T: FormattedValue> Eq for FormattedSegment<T> {}
impl<T: FormattedValueIntrinsic> Eq for FormattedSegment<T> {}
unsafe impl<T: FormattedValue> Send for FormattedSegment<T> {}
unsafe impl<T: FormattedValue> Sync for FormattedSegment<T> {}
unsafe impl<T: FormattedValueIntrinsic> Send for FormattedSegment<T> {}
unsafe impl<T: FormattedValueIntrinsic> Sync for FormattedSegment<T> {}
impl<T: FormattedValue> Clone for FormattedSegment<T> {
impl<T: FormattedValueIntrinsic> Clone for FormattedSegment<T> {
fn clone(&self) -> Self {
unsafe { FormattedSegment(ptr::read(&self.0), PhantomData) }
}
}
impl<T: FormattedValue> AsRef<Segment> for FormattedSegment<T> {
impl<T: FormattedValueIntrinsic> AsRef<Segment> for FormattedSegment<T> {
fn as_ref(&self) -> &Segment {
unsafe {
&*(self as *const FormattedSegment<T> as *const FormattedSegment<GenericFormattedValue>)
@ -534,8 +577,10 @@ impl<T: FormattedValue> AsRef<Segment> for FormattedSegment<T> {
}
}
impl<T: FormattedValue> fmt::Debug for FormattedSegment<T> {
impl<T: FormattedValueIntrinsic> fmt::Debug for FormattedSegment<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use crate::utils::Displayable;
let segment = self.as_ref();
match segment.format() {
Format::Undefined => f
@ -546,16 +591,16 @@ impl<T: FormattedValue> fmt::Debug for FormattedSegment<T> {
let segment = segment.downcast_ref::<crate::ClockTime>().unwrap();
f.debug_struct("Segment")
.field("format", &Format::Time)
.field("start", &segment.start().to_string())
.field("offset", &segment.offset().to_string())
.field("stop", &segment.stop().to_string())
.field("start", &segment.start().display().to_string())
.field("offset", &segment.offset().display().to_string())
.field("stop", &segment.stop().display().to_string())
.field("rate", &segment.rate())
.field("applied_rate", &segment.applied_rate())
.field("flags", &segment.flags())
.field("time", &segment.time().to_string())
.field("base", &segment.base().to_string())
.field("position", &segment.position().to_string())
.field("duration", &segment.duration().to_string())
.field("time", &segment.time().display().to_string())
.field("base", &segment.base().display().to_string())
.field("position", &segment.position().display().to_string())
.field("duration", &segment.duration().display().to_string())
.finish()
}
_ => f
@ -576,13 +621,13 @@ impl<T: FormattedValue> fmt::Debug for FormattedSegment<T> {
}
}
impl<T: FormattedValue> Default for FormattedSegment<T> {
impl<T: FormattedValueIntrinsic> Default for FormattedSegment<T> {
fn default() -> Self {
Self::new()
}
}
impl<T: FormattedValue> glib::types::StaticType for FormattedSegment<T> {
impl<T: FormattedValueIntrinsic> glib::types::StaticType for FormattedSegment<T> {
fn static_type() -> glib::types::Type {
unsafe { glib::translate::from_glib(ffi::gst_segment_get_type()) }
}
@ -605,7 +650,7 @@ unsafe impl<'a> glib::value::FromValue<'a> for Segment {
}
#[doc(hidden)]
impl<T: FormattedValue> glib::value::ToValue for FormattedSegment<T> {
impl<T: FormattedValueIntrinsic> glib::value::ToValue for FormattedSegment<T> {
fn to_value(&self) -> glib::Value {
let mut value = glib::Value::for_value_type::<Segment>();
unsafe {
@ -623,7 +668,7 @@ impl<T: FormattedValue> glib::value::ToValue for FormattedSegment<T> {
}
#[doc(hidden)]
impl<T: FormattedValue> glib::value::ToValueOptional for FormattedSegment<T> {
impl<T: FormattedValueIntrinsic> glib::value::ToValueOptional for FormattedSegment<T> {
fn to_value_optional(s: Option<&Self>) -> glib::Value {
skip_assert_initialized!();
let mut value = glib::Value::for_value_type::<Segment>();
@ -638,12 +683,12 @@ impl<T: FormattedValue> glib::value::ToValueOptional for FormattedSegment<T> {
}
#[doc(hidden)]
#[doc(hidden)]
impl<T: FormattedValue> glib::translate::GlibPtrDefault for FormattedSegment<T> {
impl<T: FormattedValueIntrinsic> glib::translate::GlibPtrDefault for FormattedSegment<T> {
type GlibType = *mut ffi::GstSegment;
}
#[doc(hidden)]
impl<'a, T: FormattedValue> glib::translate::ToGlibPtr<'a, *const ffi::GstSegment>
impl<'a, T: FormattedValueIntrinsic> glib::translate::ToGlibPtr<'a, *const ffi::GstSegment>
for FormattedSegment<T>
{
type Storage = &'a FormattedSegment<T>;
@ -658,7 +703,7 @@ impl<'a, T: FormattedValue> glib::translate::ToGlibPtr<'a, *const ffi::GstSegmen
}
#[doc(hidden)]
impl<'a, T: FormattedValue> glib::translate::ToGlibPtrMut<'a, *mut ffi::GstSegment>
impl<'a, T: FormattedValueIntrinsic> glib::translate::ToGlibPtrMut<'a, *mut ffi::GstSegment>
for FormattedSegment<T>
{
type Storage = &'a mut FormattedSegment<T>;

View file

@ -7,10 +7,11 @@ use serde::ser::{Serialize, Serializer};
use crate::Format;
use crate::FormattedSegment;
use crate::FormattedValue;
use crate::FormattedValueIntrinsic;
use crate::GenericFormattedValue;
use crate::Segment;
use crate::SegmentFlags;
use crate::SpecificFormattedValue;
use crate::SpecificFormattedValueIntrinsic;
#[derive(serde::Serialize, serde::Deserialize)]
struct FormattedSegmentSerde {
@ -27,7 +28,7 @@ struct FormattedSegmentSerde {
duration: i64,
}
impl<T: FormattedValue> Serialize for FormattedSegment<T> {
impl<T: FormattedValueIntrinsic> Serialize for FormattedSegment<T> {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let fmt_seg = unsafe {
FormattedSegmentSerde {
@ -35,13 +36,13 @@ impl<T: FormattedValue> Serialize for FormattedSegment<T> {
rate: self.rate(),
applied_rate: self.applied_rate(),
format: self.format(),
base: self.base().to_raw_value(),
offset: self.offset().to_raw_value(),
start: self.start().to_raw_value(),
stop: self.stop().to_raw_value(),
time: self.time().to_raw_value(),
position: self.position().to_raw_value(),
duration: self.duration().to_raw_value(),
base: self.base().into_raw_value(),
offset: self.offset().into_raw_value(),
start: self.start().into_raw_value(),
stop: self.stop().into_raw_value(),
time: self.time().into_raw_value(),
position: self.position().into_raw_value(),
duration: self.duration().into_raw_value(),
}
};
fmt_seg.serialize(serializer)
@ -91,7 +92,7 @@ impl<'de> Deserialize<'de> for Segment {
}
}
impl<'de, T: FormattedValue + SpecificFormattedValue> Deserialize<'de> for FormattedSegment<T> {
impl<'de, T: SpecificFormattedValueIntrinsic> Deserialize<'de> for FormattedSegment<T> {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
skip_assert_initialized!();
Segment::deserialize(deserializer).and_then(|segment| {
@ -99,7 +100,7 @@ impl<'de, T: FormattedValue + SpecificFormattedValue> Deserialize<'de> for Forma
de::Error::custom(format!(
"failed to convert segment with format {:?} to {:?}",
segment.format(),
T::default_format(),
T::FormattedValueType::default_format(),
))
})
})
@ -123,13 +124,13 @@ mod tests {
segment.set_rate(1f64);
segment.set_applied_rate(0.9f64);
segment.set_format(Format::Time);
segment.set_base(GenericFormattedValue::Time(ClockTime::from_nseconds(123)));
segment.set_offset(GenericFormattedValue::Time(ClockTime::from_nseconds(42)));
segment.set_start(GenericFormattedValue::Time(ClockTime::from_nseconds(1024)));
segment.set_stop(GenericFormattedValue::Time(ClockTime::from_nseconds(2048)));
segment.set_time(GenericFormattedValue::Time(ClockTime::from_nseconds(1042)));
segment.set_position(GenericFormattedValue::Time(ClockTime::from_nseconds(256)));
segment.set_duration(GenericFormattedValue::Time(ClockTime::none()));
segment.set_base(GenericFormattedValue::from(ClockTime::from_nseconds(123)));
segment.set_offset(GenericFormattedValue::from(ClockTime::from_nseconds(42)));
segment.set_start(GenericFormattedValue::from(ClockTime::from_nseconds(1024)));
segment.set_stop(GenericFormattedValue::from(ClockTime::from_nseconds(2048)));
segment.set_time(GenericFormattedValue::from(ClockTime::from_nseconds(1042)));
segment.set_position(GenericFormattedValue::from(ClockTime::from_nseconds(256)));
segment.set_duration(GenericFormattedValue::from(ClockTime::NONE));
let pretty_config = ron::ser::PrettyConfig::new().with_new_line("".to_string());
@ -184,33 +185,37 @@ mod tests {
assert!((segment.rate() - 1f64).abs() < std::f64::EPSILON);
assert!((segment.applied_rate() - 0.9f64).abs() < std::f64::EPSILON);
assert_eq!(segment.format(), Format::Time);
assert_eq!(segment.flags(), SegmentFlags::RESET | SegmentFlags::SEGMENT);
assert!((segment.rate() - 1f64).abs() < std::f64::EPSILON);
assert!((segment.applied_rate() - 0.9f64).abs() < std::f64::EPSILON);
assert_eq!(segment.format(), Format::Time);
assert_eq!(
segment.base(),
GenericFormattedValue::Time(ClockTime::from_nseconds(123))
GenericFormattedValue::from(ClockTime::from_nseconds(123)),
);
assert_eq!(
segment.offset(),
GenericFormattedValue::Time(ClockTime::from_nseconds(42))
GenericFormattedValue::from(ClockTime::from_nseconds(42)),
);
assert_eq!(
segment.start(),
GenericFormattedValue::Time(ClockTime::from_nseconds(1024))
GenericFormattedValue::from(ClockTime::from_nseconds(1024)),
);
assert_eq!(
segment.stop(),
GenericFormattedValue::Time(ClockTime::from_nseconds(2048))
GenericFormattedValue::from(ClockTime::from_nseconds(2048)),
);
assert_eq!(
segment.time(),
GenericFormattedValue::Time(ClockTime::from_nseconds(1042))
GenericFormattedValue::from(ClockTime::from_nseconds(1042)),
);
assert_eq!(
segment.position(),
GenericFormattedValue::Time(ClockTime::from_nseconds(256))
GenericFormattedValue::from(ClockTime::from_nseconds(256)),
);
assert_eq!(
segment.duration(),
GenericFormattedValue::Time(ClockTime::none())
GenericFormattedValue::from(ClockTime::NONE),
);
}
@ -244,13 +249,13 @@ mod tests {
assert!((fmt_seg.rate() - 1f64).abs() < std::f64::EPSILON);
assert!((fmt_seg.applied_rate() - 0.9f64).abs() < std::f64::EPSILON);
assert_eq!(fmt_seg.format(), Format::Time);
assert_eq!(fmt_seg.base(), ClockTime::from_nseconds(123));
assert_eq!(fmt_seg.offset(), ClockTime::from_nseconds(42));
assert_eq!(fmt_seg.start(), ClockTime::from_nseconds(1024));
assert_eq!(fmt_seg.stop(), ClockTime::from_nseconds(2048));
assert_eq!(fmt_seg.time(), ClockTime::from_nseconds(1042));
assert_eq!(fmt_seg.position(), ClockTime::from_nseconds(256));
assert_eq!(fmt_seg.duration(), ClockTime::none());
assert_eq!(fmt_seg.base(), Some(ClockTime::from_nseconds(123)));
assert_eq!(fmt_seg.offset(), Some(ClockTime::from_nseconds(42)));
assert_eq!(fmt_seg.start(), Some(ClockTime::from_nseconds(1024)));
assert_eq!(fmt_seg.stop(), Some(ClockTime::from_nseconds(2048)));
assert_eq!(fmt_seg.time(), Some(ClockTime::from_nseconds(1042)));
assert_eq!(fmt_seg.position(), Some(ClockTime::from_nseconds(256)));
assert_eq!(fmt_seg.duration(), ClockTime::NONE);
}
#[test]
@ -262,13 +267,13 @@ mod tests {
segment.set_rate(1f64);
segment.set_applied_rate(0.9f64);
segment.set_format(Format::Time);
segment.set_base(GenericFormattedValue::Time(ClockTime::from_nseconds(123)));
segment.set_offset(GenericFormattedValue::Time(ClockTime::from_nseconds(42)));
segment.set_start(GenericFormattedValue::Time(ClockTime::from_nseconds(1024)));
segment.set_stop(GenericFormattedValue::Time(ClockTime::from_nseconds(2048)));
segment.set_time(GenericFormattedValue::Time(ClockTime::from_nseconds(1042)));
segment.set_position(GenericFormattedValue::Time(ClockTime::from_nseconds(256)));
segment.set_duration(GenericFormattedValue::Time(ClockTime::none()));
segment.set_base(GenericFormattedValue::from(ClockTime::from_nseconds(123)));
segment.set_offset(GenericFormattedValue::from(ClockTime::from_nseconds(42)));
segment.set_start(GenericFormattedValue::from(ClockTime::from_nseconds(1024)));
segment.set_stop(GenericFormattedValue::from(ClockTime::from_nseconds(2048)));
segment.set_time(GenericFormattedValue::from(ClockTime::from_nseconds(1042)));
segment.set_position(GenericFormattedValue::from(ClockTime::from_nseconds(256)));
segment.set_duration(GenericFormattedValue::from(ClockTime::NONE));
let segment_se = ron::ser::to_string(&segment).unwrap();
let segment_de: Segment = ron::de::from_str(segment_se.as_str()).unwrap();

View file

@ -18,15 +18,15 @@ pub trait ClockImpl: ClockImplExt + ObjectImpl + Send + Sync {
clock: &Self::Type,
old_resolution: ClockTime,
new_resolution: ClockTime,
) -> ClockTime {
) -> Option<ClockTime> {
self.parent_change_resolution(clock, old_resolution, new_resolution)
}
fn resolution(&self, clock: &Self::Type) -> ClockTime {
fn resolution(&self, clock: &Self::Type) -> Option<ClockTime> {
self.parent_resolution(clock)
}
fn internal_time(&self, clock: &Self::Type) -> ClockTime {
fn internal_time(&self, clock: &Self::Type) -> Option<ClockTime> {
self.parent_internal_time(clock)
}
@ -53,11 +53,11 @@ pub trait ClockImplExt: ObjectSubclass {
clock: &Self::Type,
old_resolution: ClockTime,
new_resolution: ClockTime,
) -> ClockTime;
) -> Option<ClockTime>;
fn parent_resolution(&self, clock: &Self::Type) -> ClockTime;
fn parent_resolution(&self, clock: &Self::Type) -> Option<ClockTime>;
fn parent_internal_time(&self, clock: &Self::Type) -> ClockTime;
fn parent_internal_time(&self, clock: &Self::Type) -> Option<ClockTime>;
fn parent_wait(
&self,
@ -85,7 +85,7 @@ impl<T: ClockImpl> ClockImplExt for T {
clock: &Self::Type,
old_resolution: ClockTime,
new_resolution: ClockTime,
) -> ClockTime {
) -> Option<ClockTime> {
unsafe {
let data = Self::type_data();
let parent_class = data.as_ref().parent_class() as *mut ffi::GstClockClass;
@ -102,7 +102,7 @@ impl<T: ClockImpl> ClockImplExt for T {
}
}
fn parent_resolution(&self, clock: &Self::Type) -> ClockTime {
fn parent_resolution(&self, clock: &Self::Type) -> Option<ClockTime> {
unsafe {
let data = Self::type_data();
let parent_class = data.as_ref().parent_class() as *mut ffi::GstClockClass;
@ -116,7 +116,7 @@ impl<T: ClockImpl> ClockImplExt for T {
}
}
fn parent_internal_time(&self, clock: &Self::Type) -> ClockTime {
fn parent_internal_time(&self, clock: &Self::Type) -> Option<ClockTime> {
unsafe {
let data = Self::type_data();
let parent_class = data.as_ref().parent_class() as *mut ffi::GstClockClass;
@ -254,11 +254,16 @@ unsafe extern "C" fn clock_change_resolution<T: ClockImpl>(
let imp = instance.impl_();
let wrap: Borrowed<Clock> = from_glib_borrow(ptr);
imp.change_resolution(
wrap.unsafe_cast_ref(),
from_glib(old_resolution),
from_glib(new_resolution),
)
let old_resolution = match from_glib(old_resolution) {
Some(old_resolution) => old_resolution,
None => return ffi::GST_CLOCK_TIME_NONE,
};
let new_resolution = match from_glib(new_resolution) {
Some(new_resolution) => new_resolution,
None => return ffi::GST_CLOCK_TIME_NONE,
};
imp.change_resolution(wrap.unsafe_cast_ref(), old_resolution, new_resolution)
.into_glib()
}

View file

@ -797,7 +797,7 @@ mod tests {
pipeline.set_state(crate::State::Playing).unwrap();
let bus = pipeline.bus().unwrap();
let eos = bus.timed_pop_filtered(crate::CLOCK_TIME_NONE, &[crate::MessageType::Eos]);
let eos = bus.timed_pop_filtered(crate::ClockTime::NONE, &[crate::MessageType::Eos]);
assert!(eos.is_some());
pipeline.set_state(crate::State::Null).unwrap();

View file

@ -951,6 +951,7 @@ pub fn merge_strings_with_comma(src: &Value) -> Value {
#[cfg(test)]
mod tests {
use super::*;
use crate::ClockTime;
#[test]
fn test_add() {
@ -961,7 +962,7 @@ mod tests {
{
let tags = tags.get_mut().unwrap();
tags.add::<Title>(&"some title", TagMergeMode::Append);
tags.add::<Duration>(&(crate::SECOND * 120), TagMergeMode::Append);
tags.add::<Duration>(&(ClockTime::SECOND * 120), TagMergeMode::Append);
}
assert_eq!(
tags.to_string(),
@ -978,15 +979,19 @@ mod tests {
{
let tags = tags.get_mut().unwrap();
tags.add::<Title>(&"some title", TagMergeMode::Append);
tags.add::<Duration>(&(crate::SECOND * 120), TagMergeMode::Append);
tags.add::<Duration>(&(ClockTime::SECOND * 120), TagMergeMode::Append);
}
assert_eq!(tags.get::<Title>().unwrap().get(), "some title");
assert_eq!(tags.get::<Duration>().unwrap().get(), crate::SECOND * 120);
assert_eq!(
tags.get::<Duration>().unwrap().get(),
ClockTime::SECOND * 120,
);
assert_eq!(tags.index::<Title>(0).unwrap().get(), "some title");
assert_eq!(tags.index::<Title>(0).unwrap().get(), "some title");
assert_eq!(
tags.index::<Duration>(0).unwrap().get(),
crate::SECOND * 120
ClockTime::SECOND * 120,
);
}
@ -1018,7 +1023,11 @@ mod tests {
.add_generic(&TAG_TITLE, "second title", TagMergeMode::Append)
.is_ok());
assert!(tags
.add_generic(&TAG_DURATION, crate::SECOND * 120, TagMergeMode::Append)
.add_generic(
&TAG_DURATION,
&(ClockTime::SECOND * 120),
TagMergeMode::Append
)
.is_ok());
assert!(tags
.add_generic(&TAG_TITLE, "third title", TagMergeMode::Append)
@ -1044,7 +1053,7 @@ mod tests {
);
assert_eq!(
tags.index_generic(&TAG_DURATION, 0).unwrap().get(),
Ok(crate::SECOND * 120)
Ok(Some(ClockTime::SECOND * 120))
);
assert_eq!(
tags.index_generic(&TAG_TITLE, 2).unwrap().get(),
@ -1090,7 +1099,7 @@ mod tests {
let (tag_name, mut tag_iter) = tag_list_iter.next().unwrap();
assert_eq!(tag_name, *TAG_DURATION);
let first_duration = tag_iter.next().unwrap();
assert_eq!(first_duration.get(), Ok(crate::SECOND * 120));
assert_eq!(first_duration.get(), Ok(Some(ClockTime::SECOND * 120)));
assert!(tag_iter.next().is_none());
// Iter
@ -1106,7 +1115,7 @@ mod tests {
let (tag_name, tag_value) = tag_list_iter.next().unwrap();
assert_eq!(tag_name, *TAG_DURATION);
assert_eq!(tag_value.get(), Ok(crate::SECOND * 120));
assert_eq!(tag_value.get(), Ok(Some(ClockTime::SECOND * 120)));
assert!(tag_iter.next().is_none());
}

View file

@ -311,6 +311,7 @@ impl<'de> Deserialize<'de> for TagList {
mod tests {
use crate::tags::*;
use crate::Buffer;
use crate::ClockTime;
use crate::Sample;
use crate::TagMergeMode;
use crate::TagScope;
@ -325,7 +326,7 @@ mod tests {
let tags = tags.get_mut().unwrap();
tags.add::<Title>(&"a title", TagMergeMode::Append); // String
tags.add::<Title>(&"another title", TagMergeMode::Append); // String
tags.add::<Duration>(&(crate::SECOND * 120), TagMergeMode::Append); // u64
tags.add::<Duration>(&(ClockTime::SECOND * 120), TagMergeMode::Append); // u64
tags.add::<Bitrate>(&96_000, TagMergeMode::Append); // u32
tags.add::<TrackGain>(&1f64, TagMergeMode::Append); // f64
tags.add::<Date>(
@ -465,9 +466,10 @@ mod tests {
assert_eq!(tags.index::<Title>(0).unwrap().get(), "a title");
assert_eq!(tags.index::<Title>(1).unwrap().get(), "another title");
assert_eq!(tags.index::<Title>(1).unwrap().get(), "another title");
assert_eq!(
tags.index::<Duration>(0).unwrap().get(),
crate::SECOND * 120
120 * ClockTime::SECOND,
);
assert_eq!(tags.index::<Bitrate>(0).unwrap().get(), 96_000);
assert!((tags.index::<TrackGain>(0).unwrap().get() - 1f64).abs() < std::f64::EPSILON);
@ -534,7 +536,7 @@ mod tests {
tags.set_scope(TagScope::Global);
tags.add::<Title>(&"a title", TagMergeMode::Append); // String
tags.add::<Title>(&"another title", TagMergeMode::Append); // String
tags.add::<Duration>(&(crate::SECOND * 120), TagMergeMode::Append); // u64
tags.add::<Duration>(&(ClockTime::SECOND * 120), TagMergeMode::Append); // u64
tags.add::<Bitrate>(&96_000, TagMergeMode::Append); // u32
tags.add::<TrackGain>(&1f64, TagMergeMode::Append); // f64
tags.add::<Date>(

View file

@ -25,3 +25,11 @@ impl<'a> Drop for MutexGuard<'a> {
}
}
}
// rustdoc-stripper-ignore-next
/// Trait that allows accessing `Display` implementation on types external to this crate.
pub trait Displayable {
type DisplayImpl: std::fmt::Display;
fn display(self) -> Self::DisplayImpl;
}

View file

@ -26,7 +26,7 @@ enum Command {
fn send_seek_event(pipeline: &Element, rate: f64) -> bool {
// Obtain the current position, needed for the seek event
let position = match pipeline.query_position::<gst::ClockTime>() {
let position = match pipeline.query_position() {
Some(pos) => pos,
None => {
eprintln!("Unable to retrieve current position...\r");
@ -42,7 +42,7 @@ fn send_seek_event(pipeline: &Element, rate: f64) -> bool {
SeekType::Set,
position,
SeekType::End,
gst::ClockTime::from(0),
gst::ClockTime::ZERO,
)
} else {
Seek::new(

View file

@ -60,11 +60,8 @@ fn tutorial_main() {
.expect("Could not query current position.");
// If we didn't know it yet, query the stream duration
if custom_data.duration == gst::CLOCK_TIME_NONE {
custom_data.duration = custom_data
.playbin
.query_duration()
.expect("Could not query current duration.")
if custom_data.duration == gst::ClockTime::NONE {
custom_data.duration = custom_data.playbin.query_duration();
}
// Print current position and total duration
@ -73,7 +70,7 @@ fn tutorial_main() {
if custom_data.seek_enabled
&& !custom_data.seek_done
&& position > 10 * gst::SECOND
&& position > 10 * gst::ClockTime::SECOND
{
println!("\nReached 10s, performing seek...");
custom_data

View file

@ -140,16 +140,14 @@ mod tutorial5 {
let lslider = &lslider;
if let Some(dur) = pipeline.query_duration::<gst::ClockTime>() {
let seconds = dur / gst::SECOND;
lslider.set_range(0.0, seconds.map(|v| v as f64).unwrap_or(0.0));
}
lslider.set_range(0.0, dur.seconds() as f64);
if let Some(pos) = pipeline.query_position::<gst::ClockTime>() {
let seconds = pos / gst::SECOND;
lslider.block_signal(&slider_update_signal_id);
lslider.set_value(seconds.map(|v| v as f64).unwrap_or(0.0));
lslider.set_value(pos.seconds() as f64);
lslider.unblock_signal(&slider_update_signal_id);
}
}
Continue(true)
});

View file

@ -107,7 +107,7 @@ fn on_discovered(
return;
}
println!("Duration: {}", discoverer_info.duration());
println!("Duration: {}", discoverer_info.duration().display());
if let Some(tags) = discoverer_info.tags() {
println!("Tags:");

View file

@ -153,7 +153,7 @@ fn tutorial_main() -> Result<(), Error> {
if let Some(position) = pipeline.query_position::<gst::ClockTime>() {
if let Some(duration) = pipeline.query_duration::<gst::ClockTime>() {
let current_progress =
GRAPH_LENGTH as u64 * position.seconds().unwrap() / duration.seconds().unwrap();
GRAPH_LENGTH as u64 * position.seconds() / duration.seconds();
let buffering_level = buffering_level.lock().unwrap();
graph[current_progress as usize] = if *buffering_level < 100 { b'X' } else { b'>' };
}