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() .uri()
.ok_or(DiscovererError("URI should not be null"))?; .ok_or(DiscovererError("URI should not be null"))?;
println!("URI: {}", uri); println!("URI: {}", uri);
println!("Duration: {}", info.duration()); println!("Duration: {}", info.duration().display());
print_tags(info); print_tags(info);
print_stream_info( print_stream_info(
&info &info

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -35,7 +35,7 @@ glib::wrapper! {
impl ClockId { impl ClockId {
#[doc(alias = "get_time")] #[doc(alias = "get_time")]
#[doc(alias = "gst_clock_id_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)) } 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")] #[doc(alias = "gst_clock_id_wait_async")]
pub fn wait_async<F>(&self, func: F) -> Result<ClockSuccess, ClockError> pub fn wait_async<F>(&self, func: F) -> Result<ClockSuccess, ClockError>
where 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, clock: *mut ffi::GstClock,
time: ffi::GstClockTime, time: ffi::GstClockTime,
id: gpointer, id: gpointer,
@ -156,7 +158,7 @@ impl SingleShotClockId {
} }
unsafe extern "C" fn destroy_notify< unsafe extern "C" fn destroy_notify<
F: FnOnce(&Clock, ClockTime, &ClockId) + Send + 'static, F: FnOnce(&Clock, Option<ClockTime>, &ClockId) + Send + 'static,
>( >(
ptr: gpointer, ptr: gpointer,
) { ) {
@ -179,7 +181,13 @@ impl SingleShotClockId {
pub fn wait_async_future( pub fn wait_async_future(
&self, &self,
) -> Result< ) -> 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, ClockError,
> { > {
use futures_channel::oneshot; use futures_channel::oneshot;
@ -234,7 +242,7 @@ impl PeriodicClockId {
pub fn interval(&self) -> ClockTime { pub fn interval(&self) -> ClockTime {
unsafe { unsafe {
let ptr: *mut ffi::GstClockEntry = self.to_glib_none().0 as *mut _; 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")] #[doc(alias = "gst_clock_id_wait_async")]
pub fn wait_async<F>(&self, func: F) -> Result<ClockSuccess, ClockError> pub fn wait_async<F>(&self, func: F) -> Result<ClockSuccess, ClockError>
where 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, clock: *mut ffi::GstClock,
time: ffi::GstClockTime, time: ffi::GstClockTime,
id: gpointer, id: gpointer,
@ -262,7 +272,9 @@ impl PeriodicClockId {
glib::ffi::GTRUE 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, ptr: gpointer,
) { ) {
Box::<F>::from_raw(ptr as *mut _); Box::<F>::from_raw(ptr as *mut _);
@ -283,7 +295,7 @@ impl PeriodicClockId {
pub fn wait_async_stream( pub fn wait_async_stream(
&self, &self,
) -> Result< ) -> Result<
Pin<Box<dyn Stream<Item = (ClockTime, ClockId)> + Unpin + Send + 'static>>, Pin<Box<dyn Stream<Item = (Option<ClockTime>, ClockId)> + Unpin + Send + 'static>>,
ClockError, ClockError,
> { > {
use futures_channel::mpsc; use futures_channel::mpsc;
@ -348,7 +360,7 @@ impl Clock {
cexternal: ClockTime, cexternal: ClockTime,
cnum: ClockTime, cnum: ClockTime,
cdenom: ClockTime, cdenom: ClockTime,
) -> ClockTime { ) -> Option<ClockTime> {
skip_assert_initialized!(); skip_assert_initialized!();
unsafe { unsafe {
from_glib(ffi::gst_clock_adjust_with_calibration( from_glib(ffi::gst_clock_adjust_with_calibration(
@ -369,7 +381,7 @@ impl Clock {
cexternal: ClockTime, cexternal: ClockTime,
cnum: ClockTime, cnum: ClockTime,
cdenom: ClockTime, cdenom: ClockTime,
) -> ClockTime { ) -> Option<ClockTime> {
skip_assert_initialized!(); skip_assert_initialized!();
unsafe { unsafe {
from_glib(ffi::gst_clock_unadjust_with_calibration( from_glib(ffi::gst_clock_unadjust_with_calibration(
@ -416,9 +428,7 @@ pub trait ClockExtManual: 'static {
impl<O: IsA<Clock>> ClockExtManual for O { impl<O: IsA<Clock>> ClockExtManual for O {
fn new_periodic_id(&self, start_time: ClockTime, interval: ClockTime) -> PeriodicClockId { fn new_periodic_id(&self, start_time: ClockTime, interval: ClockTime) -> PeriodicClockId {
assert!(start_time.is_some()); assert_ne!(interval, ClockTime::ZERO);
assert!(interval.is_some());
assert_ne!(interval, crate::ClockTime::from(0));
unsafe { unsafe {
PeriodicClockId(from_glib_full(ffi::gst_clock_new_periodic_id( 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 { fn new_single_shot_id(&self, time: ClockTime) -> SingleShotClockId {
assert!(time.is_some());
unsafe { unsafe {
SingleShotClockId(from_glib_full(ffi::gst_clock_new_single_shot_id( SingleShotClockId(from_glib_full(ffi::gst_clock_new_single_shot_id(
self.as_ref().to_glib_none().0, self.as_ref().to_glib_none().0,
@ -518,8 +526,8 @@ mod tests {
crate::init().unwrap(); crate::init().unwrap();
let clock = SystemClock::obtain(); let clock = SystemClock::obtain();
let now = clock.time(); let now = clock.time().unwrap();
let id = clock.new_single_shot_id(now + 20 * crate::MSECOND); let id = clock.new_single_shot_id(now + 20 * ClockTime::MSECOND);
let (res, _) = id.wait(); let (res, _) = id.wait();
assert!(res == Ok(ClockSuccess::Ok) || res == Err(ClockError::Early)); assert!(res == Ok(ClockSuccess::Ok) || res == Err(ClockError::Early));
@ -532,8 +540,8 @@ mod tests {
let (sender, receiver) = channel(); let (sender, receiver) = channel();
let clock = SystemClock::obtain(); let clock = SystemClock::obtain();
let now = clock.time(); let now = clock.time().unwrap();
let id = clock.new_single_shot_id(now + 20 * crate::MSECOND); let id = clock.new_single_shot_id(now + 20 * ClockTime::MSECOND);
let res = id.wait_async(move |_, _, _| { let res = id.wait_async(move |_, _, _| {
sender.send(()).unwrap(); sender.send(()).unwrap();
}); });
@ -548,8 +556,8 @@ mod tests {
crate::init().unwrap(); crate::init().unwrap();
let clock = SystemClock::obtain(); let clock = SystemClock::obtain();
let now = clock.time(); let now = clock.time().unwrap();
let id = clock.new_periodic_id(now + 20 * crate::MSECOND, 20 * crate::MSECOND); let id = clock.new_periodic_id(now + 20 * ClockTime::MSECOND, 20 * ClockTime::MSECOND);
let (res, _) = id.wait(); let (res, _) = id.wait();
assert!(res == Ok(ClockSuccess::Ok) || res == Err(ClockError::Early)); assert!(res == Ok(ClockSuccess::Ok) || res == Err(ClockError::Early));
@ -565,8 +573,8 @@ mod tests {
let (sender, receiver) = channel(); let (sender, receiver) = channel();
let clock = SystemClock::obtain(); let clock = SystemClock::obtain();
let now = clock.time(); let now = clock.time().unwrap();
let id = clock.new_periodic_id(now + 20 * crate::MSECOND, 20 * crate::MSECOND); let id = clock.new_periodic_id(now + 20 * ClockTime::MSECOND, 20 * ClockTime::MSECOND);
let res = id.wait_async(move |_, _, _| { let res = id.wait_async(move |_, _, _| {
let _ = sender.send(()); 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. // Take a look at the license at the top of the repository in the LICENSE file.
use serde::de; use serde::de::{Deserialize, Deserializer};
use serde::de::{Deserialize, Deserializer, Visitor};
use serde::ser::{Serialize, Serializer}; use serde::ser::{Serialize, Serializer};
use std::fmt;
use crate::ClockTime; use crate::ClockTime;
impl<'a> Serialize for ClockTime { impl<'a> Serialize for ClockTime {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> { fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
match self.nanoseconds() { self.0.serialize(serializer)
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))
} }
} }
impl<'de> Deserialize<'de> for ClockTime { impl<'de> Deserialize<'de> for ClockTime {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> { fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
skip_assert_initialized!(); skip_assert_initialized!();
deserializer.deserialize_option(ClockTimeVisitor) u64::deserialize(deserializer).map(ClockTime::from_nseconds)
} }
} }
@ -53,7 +27,7 @@ mod tests {
crate::init().unwrap(); crate::init().unwrap();
// Some // 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()); let pretty_config = ron::ser::PrettyConfig::new().with_new_line("".to_string());
@ -64,7 +38,7 @@ mod tests {
assert_eq!("42123456789".to_owned(), res); assert_eq!("42123456789".to_owned(), res);
// None // None
let clocktime = ClockTime(None); let clocktime = ClockTime::NONE;
let res = ron::ser::to_string_pretty(&clocktime, pretty_config); let res = ron::ser::to_string_pretty(&clocktime, pretty_config);
assert_eq!(Ok("None".to_owned()), res); assert_eq!(Ok("None".to_owned()), res);
@ -79,46 +53,59 @@ mod tests {
// Some // Some
let clocktime_ron = "Some(42123456789)"; let clocktime_ron = "Some(42123456789)";
let clocktime: ClockTime = ron::de::from_str(clocktime_ron).unwrap(); let clocktime: Option<ClockTime> = ron::de::from_str(clocktime_ron).unwrap();
assert_eq!(clocktime.seconds(), Some(42)); let clocktime = clocktime.unwrap();
assert_eq!(clocktime.mseconds(), Some(42_123)); assert_eq!(clocktime.seconds(), 42);
assert_eq!(clocktime.useconds(), Some(42_123_456)); assert_eq!(clocktime.mseconds(), 42_123);
assert_eq!(clocktime.nseconds(), Some(42_123_456_789)); assert_eq!(clocktime.useconds(), 42_123_456);
assert_eq!(clocktime.nseconds(), 42_123_456_789);
let clocktime_json = "42123456789"; let clocktime_json = "42123456789";
let clocktime: ClockTime = serde_json::from_str(clocktime_json).unwrap(); let clocktime: Option<ClockTime> = serde_json::from_str(clocktime_json).unwrap();
assert_eq!(clocktime.seconds(), Some(42)); let clocktime = clocktime.unwrap();
assert_eq!(clocktime.mseconds(), Some(42_123)); assert_eq!(clocktime.seconds(), 42);
assert_eq!(clocktime.useconds(), Some(42_123_456)); assert_eq!(clocktime.mseconds(), 42_123);
assert_eq!(clocktime.nseconds(), Some(42_123_456_789)); assert_eq!(clocktime.useconds(), 42_123_456);
assert_eq!(clocktime.nseconds(), 42_123_456_789);
// None // None
let clocktime_ron = "None"; let clocktime_ron = "None";
let clocktime: ClockTime = ron::de::from_str(clocktime_ron).unwrap(); let clocktime: Option<ClockTime> = ron::de::from_str(clocktime_ron).unwrap();
assert_eq!(clocktime.nseconds(), None); assert!(clocktime.is_none());
let clocktime_json = "null"; let clocktime_json = "null";
let clocktime: ClockTime = serde_json::from_str(clocktime_json).unwrap(); let clocktime: Option<ClockTime> = serde_json::from_str(clocktime_json).unwrap();
assert_eq!(clocktime.nseconds(), None); assert!(clocktime.is_none());
assert!(clocktime.is_none());
} }
#[test] #[test]
fn test_serde_roundtrip() { fn test_serde_roundtrip() {
crate::init().unwrap(); crate::init().unwrap();
// Some // Direct
let clocktime = ClockTime::from_nseconds(42_123_456_789); let clocktime = ClockTime::from_nseconds(42_123_456_789);
let clocktime_ser = ron::ser::to_string(&clocktime).unwrap(); let clocktime_ser = ron::ser::to_string(&clocktime).unwrap();
let clocktime: ClockTime = ron::de::from_str(clocktime_ser.as_str()).unwrap(); let clocktime: ClockTime = ron::de::from_str(clocktime_ser.as_str()).unwrap();
assert_eq!(clocktime.seconds(), Some(42)); assert_eq!(clocktime.seconds(), 42);
assert_eq!(clocktime.mseconds(), Some(42_123)); assert_eq!(clocktime.mseconds(), 42_123);
assert_eq!(clocktime.useconds(), Some(42_123_456)); assert_eq!(clocktime.useconds(), 42_123_456);
assert_eq!(clocktime.nseconds(), Some(42_123_456_789)); 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 // None
let clocktime = ClockTime(None); let clocktime = ClockTime::NONE;
let clocktime_ser = ron::ser::to_string(&clocktime).unwrap(); let clocktime_ser = ron::ser::to_string(&clocktime).unwrap();
let clocktime: ClockTime = ron::de::from_str(clocktime_ser.as_str()).unwrap(); let clocktime: Option<ClockTime> = ron::de::from_str(clocktime_ser.as_str()).unwrap();
assert_eq!(clocktime.nseconds(), None); assert!(clocktime.is_none());
} }
} }

View file

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

View file

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

View file

@ -2,45 +2,65 @@
use crate::ClockTime; use crate::ClockTime;
use crate::Format; use crate::Format;
use glib::translate::{FromGlib, GlibNoneError, IntoGlib, OptionIntoGlib, TryFromGlib};
use muldiv::MulDiv; use muldiv::MulDiv;
use std::borrow::Borrow;
use std::convert::TryFrom; use std::convert::TryFrom;
use std::fmt;
use std::ops; use std::ops;
use thiserror::Error; use thiserror::Error;
use std::cmp;
#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)] #[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)]
#[cfg_attr(feature = "ser_de", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "ser_de", derive(serde::Serialize, serde::Deserialize))]
pub enum GenericFormattedValue { pub enum GenericFormattedValue {
Undefined(Undefined), Undefined(Undefined),
Default(Default), Default(Option<Default>),
Bytes(Bytes), Bytes(Option<Bytes>),
Time(ClockTime), Time(Option<ClockTime>),
Buffers(Buffers), Buffers(Option<Buffers>),
Percent(Percent), Percent(Option<Percent>),
Other(Format, i64), Other(Format, i64),
} }
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)] #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)]
pub struct Undefined(pub i64); pub struct Undefined(pub i64);
#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug, Default)] #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)]
pub struct Default(pub Option<u64>); pub struct Default(pub u64);
impl_common_ops_for_opt_int!(Default);
#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug, Default)] #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)]
pub struct Bytes(pub Option<u64>); pub struct Bytes(pub u64);
impl_common_ops_for_opt_int!(Bytes);
pub type Time = ClockTime; pub type Time = ClockTime;
#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug, Default)] #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)]
pub struct Buffers(pub Option<u64>); pub struct Buffers(pub u64);
impl_common_ops_for_opt_int!(Buffers); impl Buffers {
pub const OFFSET_NONE: u64 = ffi::GST_BUFFER_OFFSET_NONE;
}
#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug, Default)] #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)]
pub struct Percent(pub Option<u32>); pub struct Percent(pub u32);
impl_common_ops_for_opt_int!(Percent); 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)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Error)]
#[error("invalid generic value format")] #[error("invalid generic value format")]
@ -53,11 +73,32 @@ pub trait FormattedValue: Copy + Clone + Sized + Into<GenericFormattedValue> + '
fn format(&self) -> Format; fn format(&self) -> Format;
unsafe fn from_raw(format: Format, value: i64) -> Self; 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> {} 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 { impl FormattedValue for GenericFormattedValue {
fn default_format() -> Format { fn default_format() -> Format {
Format::Undefined Format::Undefined
@ -71,7 +112,7 @@ impl FormattedValue for GenericFormattedValue {
GenericFormattedValue::new(format, value) GenericFormattedValue::new(format, value)
} }
unsafe fn to_raw_value(&self) -> i64 { unsafe fn into_raw_value(self) -> i64 {
self.value() self.value()
} }
} }
@ -81,27 +122,11 @@ impl GenericFormattedValue {
skip_assert_initialized!(); skip_assert_initialized!();
match format { match format {
Format::Undefined => Self::Undefined(Undefined(value)), Format::Undefined => Self::Undefined(Undefined(value)),
Format::Default => Self::Default(if value == -1 { Format::Default => Self::Default(unsafe { FromGlib::from_glib(value as u64) }),
Default(None) Format::Bytes => Self::Bytes(unsafe { FromGlib::from_glib(value as u64) }),
} else { Format::Time => Self::Time(unsafe { FromGlib::from_glib(value as u64) }),
Default(Some(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::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::__Unknown(_) => Self::Other(format, value), Format::__Unknown(_) => Self::Other(format, value),
} }
} }
@ -121,153 +146,87 @@ impl GenericFormattedValue {
#[doc(alias = "get_value")] #[doc(alias = "get_value")]
pub fn value(&self) -> i64 { pub fn value(&self) -> i64 {
match *self { unsafe {
Self::Undefined(v) => v.0, match *self {
Self::Default(v) => v.map(|v| v as i64).unwrap_or(-1), Self::Undefined(v) => v.0,
Self::Bytes(v) => v.map(|v| v as i64).unwrap_or(-1), Self::Default(v) => v.into_raw_value(),
Self::Time(v) => v.map(|v| v as i64).unwrap_or(-1), Self::Bytes(v) => v.into_raw_value(),
Self::Buffers(v) => v.map(|v| v as i64).unwrap_or(-1), Self::Time(v) => v.into_raw_value(),
Self::Percent(v) => v.map(i64::from).unwrap_or(-1), Self::Buffers(v) => v.into_raw_value(),
Self::Other(_, v) => v, Self::Percent(v) => v.into_raw_value(),
Self::Other(_, v) => v,
}
} }
} }
} }
impl FormattedValueIntrinsic for GenericFormattedValue {
type FormattedValueType = GenericFormattedValue;
}
macro_rules! impl_op_same( macro_rules! impl_op_same(
($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<$name> for $name { 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; type Output = $name;
fn $op_name(self, other: $name) -> Self::Output { fn $op_name(self, rhs: RHS) -> Self::Output {
match (self.0, other.0) { (*self).$op_name(rhs)
(Some(a), Some(b)) => $name($e(a, b)),
_ => $name(None),
}
} }
} }
impl<'a> ops::$op<&'a $name> for $name { impl<RHS: Borrow<$name>> ops::$op_assign<RHS> for $name {
type Output = $name; fn $op_assign_name(&mut self, rhs: RHS) {
self.0.$op_assign_name(rhs.borrow().0)
fn $op_name(self, other: &'a $name) -> Self::Output {
self.$op_name(*other)
}
}
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)
} }
} }
}; };
); );
macro_rules! impl_op_u64( 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 { impl ops::$op<u64> for $name {
type Output = $name; type Output = $name;
fn $op_name(self, other: u64) -> Self::Output { fn $op_name(self, rhs: u64) -> Self::Output {
match self.0 { $name(self.0.$op_name(rhs))
Some(a) => $name($e(a, other)),
_ => $name(None),
}
} }
} }
impl<'a> ops::$op<&'a u64> for $name { impl ops::$op<u64> for &$name {
type Output = $name; type Output = $name;
fn $op_name(self, other: &'a u64) -> Self::Output { fn $op_name(self, rhs: u64) -> Self::Output {
self.$op_name(*other) (*self).$op_name(rhs)
}
}
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)
} }
} }
impl ops::$op<$name> for u64 { impl ops::$op<$name> for u64 {
type Output = $name; type Output = $name;
fn $op_name(self, other: $name) -> $name { fn $op_name(self, rhs: $name) -> $name {
other.$op_name(self) $name(self.$op_name(rhs.0))
} }
} }
impl<'a> ops::$op<&'a $name> for u64 { impl ops::$op<&$name> for u64 {
type Output = $name; type Output = $name;
fn $op_name(self, other: &'a $name) -> $name { fn $op_name(self, rhs: &$name) -> $name {
(*other).$op_name(self) self.$op_name(*rhs)
}
}
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)
} }
} }
impl ops::$op_assign<u64> for $name { impl ops::$op_assign<u64> for $name {
fn $op_assign_name(&mut self, other: u64) { fn $op_assign_name(&mut self, rhs: u64) {
match self.0 { self.0.$op_assign_name(rhs)
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)
} }
} }
}; };
@ -275,7 +234,7 @@ macro_rules! impl_op_u64(
macro_rules! impl_format_value_traits( macro_rules! impl_format_value_traits(
($name:ident, $format:ident, $format_value:ident) => { ($name:ident, $format:ident, $format_value:ident) => {
impl FormattedValue for $name { impl FormattedValue for Option<$name> {
fn default_format() -> Format { fn default_format() -> Format {
Format::$format Format::$format
} }
@ -284,31 +243,38 @@ macro_rules! impl_format_value_traits(
Format::$format 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); debug_assert_eq!(format, Format::$format);
if value == -1 { FromGlib::from_glib(value as u64)
$name(None)
} else {
$name(Some(value as u64))
}
} }
unsafe fn to_raw_value(&self) -> i64 { unsafe fn into_raw_value(self) -> i64 {
self.0.map(|v| v as i64).unwrap_or(-1) IntoGlib::into_glib(self) as i64
}
}
impl From<Option<$name>> for GenericFormattedValue {
fn from(v: Option<$name>) -> Self {
skip_assert_initialized!();
Self::$format_value(v)
} }
} }
impl From<$name> for GenericFormattedValue { impl From<$name> for GenericFormattedValue {
fn from(v: $name) -> Self { fn from(v: $name) -> Self {
skip_assert_initialized!(); 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; 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!(); skip_assert_initialized!();
if let GenericFormattedValue::$format_value(v) = v { if let GenericFormattedValue::$format_value(v) = v {
Ok(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 try_from(v: u64) -> Result<$name, GlibNoneError> {
fn from(v: u64) -> Self {
skip_assert_initialized!(); skip_assert_initialized!();
$name(Some(v)) unsafe { Self::try_from_glib(v) }
} }
} }
impl From<Option<u64>> for $name { impl TryFromGlib<i64> for $name {
fn from(v: Option<u64>) -> Self { type Error = GlibNoneError;
#[inline]
unsafe fn try_from_glib(val: i64) -> Result<Self, GlibNoneError> {
skip_assert_initialized!(); skip_assert_initialized!();
$name(v) <$name as TryFromGlib<u64>>::try_from_glib(val as u64)
} }
} }
impl From<$name> for Option<u64> { impl SpecificFormattedValue for Option<$name> {}
fn from(v: $name) -> Self { impl SpecificFormattedValueIntrinsic for $name {}
skip_assert_initialized!();
v.0
}
}
impl ops::Deref 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 &self.0
} }
} }
impl ops::DerefMut for $name { impl ops::DerefMut for $name {
fn deref_mut(&mut self) -> &mut Option<u64> { fn deref_mut(&mut self) -> &mut u64 {
&mut self.0 &mut self.0
} }
} }
impl AsRef<Option<u64>> for $name { impl AsRef<u64> for $name {
fn as_ref(&self) -> &Option<u64> { fn as_ref(&self) -> &u64 {
&self.0 &self.0
} }
} }
impl AsMut<Option<u64>> for $name { impl AsMut<u64> for $name {
fn as_mut(&mut self) -> &mut Option<u64> { fn as_mut(&mut self) -> &mut u64 {
&mut self.0 &mut self.0
} }
} }
impl_op_same!($name, Add, add, AddAssign, add_assign, |a: u64, b: u64| a.checked_add(b)); impl_op_same!($name, Add, add, AddAssign, add_assign);
impl_op_same!($name, Sub, sub, SubAssign, sub_assign, |a: u64, b: u64| a.checked_sub(b)); impl_op_same!($name, Sub, sub, SubAssign, sub_assign);
impl_op_same!($name, Mul, mul, MulAssign, mul_assign, |a: u64, b: u64| a.checked_mul(b)); impl_op_same!($name, Mul, mul, MulAssign, mul_assign);
impl_op_same!($name, Div, div, DivAssign, div_assign, |a: u64, b: u64| a.checked_div(b)); impl_op_same!($name, Div, div, DivAssign, div_assign);
impl_op_same!($name, Rem, rem, RemAssign, rem_assign, |a: u64, b: u64| a.checked_rem(b)); 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, Mul, mul, MulAssign, mul_assign);
impl_op_u64!($name, Div, div, DivAssign, div_assign, |a: u64, b: u64| a.checked_div(b)); impl_op_u64!($name, Div, div, DivAssign, div_assign);
impl_op_u64!($name, Rem, rem, RemAssign, rem_assign, |a: u64, b: u64| a.checked_rem(b)); 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; type Output = $name;
fn mul_div_floor(self, num: $name, denom: $name) -> Option<Self::Output> { fn mul_div_floor(self, num: ND, denom: ND) -> Option<Self::Output> {
match (self.0, num.0, denom.0) { self.0
(Some(s), Some(n), Some(d)) => s.mul_div_floor(n, d).map(|v| $name(Some(v))), .mul_div_floor(*num.borrow(), *denom.borrow())
_ => Some($name(None)), .map($name)
}
} }
fn mul_div_round(self, num: $name, denom: $name) -> Option<Self::Output> { fn mul_div_round(self, num: ND, denom: ND) -> Option<Self::Output> {
match (self.0, num.0, denom.0) { self.0
(Some(s), Some(n), Some(d)) => s.mul_div_round(n, d).map(|v| $name(Some(v))), .mul_div_round(*num.borrow(), *denom.borrow())
_ => Some($name(None)), .map($name)
}
} }
fn mul_div_ceil(self, num: $name, denom: $name) -> Option<Self::Output> { fn mul_div_ceil(self, num: ND, denom: ND) -> Option<Self::Output> {
match (self.0, num.0, denom.0) { self.0
(Some(s), Some(n), Some(d)) => s.mul_div_ceil(n, d).map(|v| $name(Some(v))), .mul_div_ceil(*num.borrow(), *denom.borrow())
_ => Some($name(None)), .map($name)
}
}
}
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)
} }
} }
}; };
); );
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); 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); 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_format_value_traits!(ClockTime, Time, Time);
impl_common_ops_for_newtype_u64!(Buffers);
impl_format_value_traits!(Buffers, Buffers, 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 { impl FormattedValue for Undefined {
fn default_format() -> Format { fn default_format() -> Format {
@ -535,7 +420,7 @@ impl FormattedValue for Undefined {
Undefined(value) Undefined(value)
} }
unsafe fn to_raw_value(&self) -> i64 { unsafe fn into_raw_value(self) -> i64 {
self.0 self.0
} }
} }
@ -560,8 +445,23 @@ impl TryFrom<GenericFormattedValue> for Undefined {
} }
} }
impl FormattedValueIntrinsic for Undefined {
type FormattedValueType = Undefined;
}
impl SpecificFormattedValue for 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 { impl From<i64> for Undefined {
fn from(v: i64) -> Self { fn from(v: i64) -> Self {
skip_assert_initialized!(); 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 { impl ops::Deref for Undefined {
type Target = i64; 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 { fn default_format() -> Format {
Format::Percent Format::Percent
} }
@ -613,29 +523,47 @@ impl FormattedValue for Percent {
unsafe fn from_raw(format: Format, value: i64) -> Self { unsafe fn from_raw(format: Format, value: i64) -> Self {
debug_assert_eq!(format, Format::Percent); debug_assert_eq!(format, Format::Percent);
if value < 0 || value > ffi::GST_FORMAT_PERCENT_MAX { Percent::try_from_glib(value as i64).ok()
Percent(None)
} else {
Percent(Some(value as u32))
}
} }
unsafe fn to_raw_value(&self) -> i64 { unsafe fn into_raw_value(self) -> i64 {
self.0.map(|v| v as i64).unwrap_or(-1) self.map_or(-1, |v| v.0 as i64)
}
}
impl From<Option<Percent>> for GenericFormattedValue {
fn from(v: Option<Percent>) -> Self {
skip_assert_initialized!();
GenericFormattedValue::Percent(v)
} }
} }
impl From<Percent> for GenericFormattedValue { impl From<Percent> for GenericFormattedValue {
fn from(v: Percent) -> Self { fn from(v: Percent) -> Self {
skip_assert_initialized!(); 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; type Error = TryFromGenericFormattedValueError;
fn try_from(v: GenericFormattedValue) -> Result<Percent, TryFromGenericFormattedValueError> { fn try_from(
v: GenericFormattedValue,
) -> Result<Option<Percent>, TryFromGenericFormattedValueError> {
skip_assert_initialized!(); skip_assert_initialized!();
if let GenericFormattedValue::Percent(v) = v { if let GenericFormattedValue::Percent(v) = v {
Ok(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 { impl ops::Deref for Percent {
type Target = Option<u32>; type Target = u32;
fn deref(&self) -> &Option<u32> { fn deref(&self) -> &u32 {
&self.0 &self.0
} }
} }
impl ops::DerefMut for Percent { impl ops::DerefMut for Percent {
fn deref_mut(&mut self) -> &mut Option<u32> { fn deref_mut(&mut self) -> &mut u32 {
&mut self.0 &mut self.0
} }
} }
impl AsRef<Option<u32>> for Percent { impl AsRef<u32> for Percent {
fn as_ref(&self) -> &Option<u32> { fn as_ref(&self) -> &u32 {
&self.0 &self.0
} }
} }
impl AsMut<Option<u32>> for Percent { impl AsMut<u32> for Percent {
fn as_mut(&mut self) -> &mut Option<u32> { fn as_mut(&mut self) -> &mut u32 {
&mut self.0 &mut self.0
} }
} }
@ -685,9 +619,9 @@ impl TryFrom<f64> for Percent {
if v < 0.0 || v > 1.0 { if v < 0.0 || v > 1.0 {
Err(TryPercentFromFloatError(())) Err(TryPercentFromFloatError(()))
} else { } else {
Ok(Percent(Some( Ok(Percent(
(v * ffi::GST_FORMAT_PERCENT_SCALE as f64).round() as u32, (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 { if v < 0.0 || v > 1.0 {
Err(TryPercentFromFloatError(())) Err(TryPercentFromFloatError(()))
} else { } else {
Ok(Percent(Some( Ok(Percent(
(v * ffi::GST_FORMAT_PERCENT_SCALE as f32).round() as u32, (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 { impl<'de> Deserialize<'de> for $t {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> { fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
skip_assert_initialized!(); 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 { impl<'de> Deserialize<'de> for Percent {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> { fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
skip_assert_initialized!(); 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 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()); let res = ron::ser::to_string_pretty(&value, pretty_config.clone());
assert_eq!(Ok("Undefined(42)".to_owned()), res); assert_eq!(Ok("Undefined(42)".to_owned()), res);
let res = serde_json::to_string(&value).unwrap(); let res = serde_json::to_string(&value).unwrap();
assert_eq!("{\"Undefined\":42}".to_owned(), res); 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()); let res = ron::ser::to_string_pretty(&value, pretty_config.clone());
assert_eq!(Ok("Default(Some(42))".to_owned()), res); assert_eq!(Ok("Default(Some(42))".to_owned()), res);
let res = serde_json::to_string(&value).unwrap(); let res = serde_json::to_string(&value).unwrap();
assert_eq!("{\"Default\":42}".to_owned(), res); 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()); let res = ron::ser::to_string_pretty(&value, pretty_config.clone());
assert_eq!(Ok("Default(None)".to_owned()), res); assert_eq!(Ok("Default(None)".to_owned()), res);
let res = serde_json::to_string(&value).unwrap(); let res = serde_json::to_string(&value).unwrap();
assert_eq!("{\"Default\":null}".to_owned(), res); 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()); let res = ron::ser::to_string_pretty(&value, pretty_config.clone());
assert_eq!(Ok("Bytes(Some(42))".to_owned()), res); assert_eq!(Ok("Bytes(Some(42))".to_owned()), res);
let res = serde_json::to_string(&value).unwrap(); let res = serde_json::to_string(&value).unwrap();
assert_eq!("{\"Bytes\":42}".to_owned(), res); 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()); let res = ron::ser::to_string_pretty(&value, pretty_config.clone());
assert_eq!(Ok("Time(Some(42123456789))".to_owned()), res); assert_eq!(Ok("Time(Some(42123456789))".to_owned()), res);
let res = serde_json::to_string(&value).unwrap(); let res = serde_json::to_string(&value).unwrap();
assert_eq!("{\"Time\":42123456789}".to_owned(), res); 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()); let res = ron::ser::to_string_pretty(&value, pretty_config.clone());
assert_eq!(Ok("Buffers(Some(42))".to_owned()), res); assert_eq!(Ok("Buffers(Some(42))".to_owned()), res);
let res = serde_json::to_string(&value).unwrap(); let res = serde_json::to_string(&value).unwrap();
assert_eq!("{\"Buffers\":42}".to_owned(), res); 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()); let res = ron::ser::to_string_pretty(&value, pretty_config.clone());
assert_eq!(Ok("Percent(Some(4200))".to_owned()), res); assert_eq!(Ok("Percent(Some(4200))".to_owned()), res);
let res = serde_json::to_string(&value).unwrap(); let res = serde_json::to_string(&value).unwrap();
@ -130,11 +130,11 @@ mod tests {
let value_ron = "Default(Some(42))"; let value_ron = "Default(Some(42))";
let value_de: GenericFormattedValue = ron::de::from_str(value_ron).unwrap(); 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_json = "{\"Default\":42}";
let value_de: GenericFormattedValue = serde_json::from_str(value_json).unwrap(); 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_ron = "Other(Percent, 42)";
let value_de: GenericFormattedValue = ron::de::from_str(value_ron).unwrap(); 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::Undefined(Undefined::from(42)));
test_roundrip!(GenericFormattedValue::Default(Default::from(42))); test_roundrip!(GenericFormattedValue::from(Default(42)));
test_roundrip!(GenericFormattedValue::Bytes(Bytes(Some(42)))); test_roundrip!(GenericFormattedValue::from(Bytes(42)));
test_roundrip!(GenericFormattedValue::Time(ClockTime::from_nseconds( test_roundrip!(GenericFormattedValue::from(ClockTime::from_nseconds(
42_123_456_789 42_123_456_789
))); )));
test_roundrip!(GenericFormattedValue::Buffers(Buffers::from(42))); test_roundrip!(GenericFormattedValue::from(Buffers(42)));
test_roundrip!(GenericFormattedValue::Percent( test_roundrip!(GenericFormattedValue::from(
Percent::try_from(0.42).unwrap() Percent::try_from(0.42).unwrap()
)); ));
test_roundrip!(GenericFormattedValue::Other(Format::Percent, 42)); test_roundrip!(GenericFormattedValue::Other(Format::Percent, 42));

View file

@ -202,7 +202,10 @@ mod typefind;
pub use crate::typefind::*; pub use crate::typefind::*;
pub mod format; pub mod format;
pub use crate::format::{FormattedValue, GenericFormattedValue, SpecificFormattedValue}; pub use crate::format::{
FormattedValue, FormattedValueIntrinsic, GenericFormattedValue, SpecificFormattedValue,
SpecificFormattedValueIntrinsic,
};
#[cfg(feature = "ser_de")] #[cfg(feature = "ser_de")]
mod format_serde; mod format_serde;
@ -230,6 +233,8 @@ pub use crate::param_spec::*;
pub mod functions; pub mod functions;
pub use crate::functions::*; pub use crate::functions::*;
mod utils;
use std::ptr; use std::ptr;
#[doc(alias = "gst_init_check")] #[doc(alias = "gst_init_check")]
@ -259,22 +264,6 @@ pub unsafe fn deinit() {
ffi::gst_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_CONTROLLABLE: glib::ParamFlags = glib::ParamFlags::USER_1;
pub const PARAM_FLAG_MUTABLE_READY: glib::ParamFlags = glib::ParamFlags::USER_2; pub const PARAM_FLAG_MUTABLE_READY: glib::ParamFlags = glib::ParamFlags::USER_2;
pub const PARAM_FLAG_MUTABLE_PAUSED: glib::ParamFlags = glib::ParamFlags::USER_3; 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 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] #[macro_use]
pub mod subclass; pub mod subclass;

View file

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

View file

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

View file

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

View file

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

View file

@ -96,10 +96,10 @@ mod tests {
let mut buffer = Buffer::from_slice(vec![1, 2, 3, 4]); let mut buffer = Buffer::from_slice(vec![1, 2, 3, 4]);
{ {
let buffer = buffer.get_mut().unwrap(); let buffer = buffer.get_mut().unwrap();
buffer.set_pts(1.into()); buffer.set_pts(Some(ClockTime::NSECOND));
buffer.set_offset(0); buffer.set_offset(0);
buffer.set_offset_end(4); buffer.set_offset_end(4);
buffer.set_duration(4.into()); buffer.set_duration(Some(4 * ClockTime::NSECOND));
} }
let caps = Caps::builder("sample/caps") let caps = Caps::builder("sample/caps")
@ -112,13 +112,13 @@ mod tests {
segment.set_rate(1f64); segment.set_rate(1f64);
segment.set_applied_rate(0.9f64); segment.set_applied_rate(0.9f64);
segment.set_format(Format::Time); segment.set_format(Format::Time);
segment.set_base(GenericFormattedValue::Time(ClockTime::from_nseconds(123))); segment.set_base(GenericFormattedValue::from(ClockTime::from_nseconds(123)));
segment.set_offset(GenericFormattedValue::Time(ClockTime::from_nseconds(42))); segment.set_offset(GenericFormattedValue::from(ClockTime::from_nseconds(42)));
segment.set_start(GenericFormattedValue::Time(ClockTime::from_nseconds(1024))); segment.set_start(GenericFormattedValue::from(ClockTime::from_nseconds(1024)));
segment.set_stop(GenericFormattedValue::Time(ClockTime::from_nseconds(2048))); segment.set_stop(GenericFormattedValue::from(ClockTime::from_nseconds(2048)));
segment.set_time(GenericFormattedValue::Time(ClockTime::from_nseconds(1042))); segment.set_time(GenericFormattedValue::from(ClockTime::from_nseconds(1042)));
segment.set_position(GenericFormattedValue::Time(ClockTime::from_nseconds(256))); segment.set_position(GenericFormattedValue::from(ClockTime::from_nseconds(256)));
segment.set_duration(GenericFormattedValue::Time(ClockTime::none())); segment.set_duration(GenericFormattedValue::from(ClockTime::NONE));
let info = Structure::builder("sample.info") let info = Structure::builder("sample.info")
.field("f3", &123i32) .field("f3", &123i32)
@ -182,10 +182,10 @@ mod tests {
let mut buffer = Buffer::from_slice(vec![1, 2, 3, 4]); let mut buffer = Buffer::from_slice(vec![1, 2, 3, 4]);
{ {
let buffer = buffer.get_mut().unwrap(); let buffer = buffer.get_mut().unwrap();
buffer.set_pts(1.into()); buffer.set_pts(Some(ClockTime::NSECOND));
buffer.set_offset(0); buffer.set_offset(0);
buffer.set_offset_end(4); buffer.set_offset_end(4);
buffer.set_duration(4.into()); buffer.set_duration(Some(4 * ClockTime::NSECOND));
} }
Sample::builder().buffer(&buffer).build() Sample::builder().buffer(&buffer).build()
}; };
@ -277,7 +277,7 @@ mod tests {
)"#; )"#;
let sample: Sample = ron::de::from_str(buffer_ron).unwrap(); let sample: Sample = ron::de::from_str(buffer_ron).unwrap();
let buffer = sample.buffer().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); assert_eq!(buffer.offset_end(), 4);
{ {
let data = buffer.map_readable().unwrap(); let data = buffer.map_readable().unwrap();
@ -326,10 +326,10 @@ mod tests {
let mut buffer = Buffer::from_slice(vec![1, 2, 3, 4]); let mut buffer = Buffer::from_slice(vec![1, 2, 3, 4]);
{ {
let buffer = buffer.get_mut().unwrap(); let buffer = buffer.get_mut().unwrap();
buffer.set_pts(1.into()); buffer.set_pts(Some(ClockTime::NSECOND));
buffer.set_offset(0); buffer.set_offset(0);
buffer.set_offset_end(4); buffer.set_offset_end(4);
buffer.set_duration(4.into()); buffer.set_duration(Some(4 * ClockTime::NSECOND));
} }
let caps = Caps::builder("sample/caps") let caps = Caps::builder("sample/caps")
@ -342,13 +342,13 @@ mod tests {
segment.set_rate(1f64); segment.set_rate(1f64);
segment.set_applied_rate(0.9f64); segment.set_applied_rate(0.9f64);
segment.set_format(Format::Time); segment.set_format(Format::Time);
segment.set_base(GenericFormattedValue::Time(ClockTime::from_nseconds(123))); segment.set_base(GenericFormattedValue::from(ClockTime::from_nseconds(123)));
segment.set_offset(GenericFormattedValue::Time(ClockTime::from_nseconds(42))); segment.set_offset(GenericFormattedValue::from(ClockTime::from_nseconds(42)));
segment.set_start(GenericFormattedValue::Time(ClockTime::from_nseconds(1024))); segment.set_start(GenericFormattedValue::from(ClockTime::from_nseconds(1024)));
segment.set_stop(GenericFormattedValue::Time(ClockTime::from_nseconds(2048))); segment.set_stop(GenericFormattedValue::from(ClockTime::from_nseconds(2048)));
segment.set_time(GenericFormattedValue::Time(ClockTime::from_nseconds(1042))); segment.set_time(GenericFormattedValue::from(ClockTime::from_nseconds(1042)));
segment.set_position(GenericFormattedValue::Time(ClockTime::from_nseconds(256))); segment.set_position(GenericFormattedValue::from(ClockTime::from_nseconds(256)));
segment.set_duration(GenericFormattedValue::Time(ClockTime::none())); segment.set_duration(GenericFormattedValue::from(ClockTime::NONE));
let info = Structure::builder("sample.info") let info = Structure::builder("sample.info")
.field("f3", &123i32) .field("f3", &123i32)
@ -364,7 +364,7 @@ mod tests {
let sample_ser = ron::ser::to_string(&sample).unwrap(); let sample_ser = ron::ser::to_string(&sample).unwrap();
let sample_de: Sample = ron::de::from_str(sample_ser.as_str()).unwrap(); let sample_de: Sample = ron::de::from_str(sample_ser.as_str()).unwrap();
let buffer_de = sample_de.buffer().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); assert_eq!(buffer_de.offset_end(), 4);
{ {
let data = buffer_de.map_readable().unwrap(); 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. // Take a look at the license at the top of the repository in the LICENSE file.
use crate::Format; use crate::Format;
use crate::FormattedValue;
use crate::GenericFormattedValue; use crate::GenericFormattedValue;
use crate::SeekFlags; use crate::SeekFlags;
use crate::SeekType; use crate::SeekType;
use crate::{FormattedValue, FormattedValueIntrinsic};
use glib::translate::*; use glib::translate::*;
use glib::StaticType; use glib::StaticType;
use std::fmt; use std::fmt;
@ -15,7 +15,7 @@ use std::ptr;
pub type Segment = FormattedSegment<GenericFormattedValue>; pub type Segment = FormattedSegment<GenericFormattedValue>;
#[repr(transparent)] #[repr(transparent)]
#[doc(alias = "GstSegment")] #[doc(alias = "GstSegment")]
pub struct FormattedSegment<T: FormattedValue>(ffi::GstSegment, PhantomData<T>); pub struct FormattedSegment<T: FormattedValueIntrinsic>(ffi::GstSegment, PhantomData<T>);
impl Segment { impl Segment {
pub fn reset_with_format(&mut self, format: Format) { pub fn reset_with_format(&mut self, format: Format) {
@ -28,16 +28,20 @@ impl Segment {
self.0.format = format.into_glib(); self.0.format = format.into_glib();
} }
pub fn downcast<T: FormattedValue>(self) -> Result<FormattedSegment<T>, Self> { pub fn downcast<T: FormattedValueIntrinsic>(self) -> Result<FormattedSegment<T>, Self> {
if T::default_format() == Format::Undefined || T::default_format() == self.format() { if T::FormattedValueType::default_format() == Format::Undefined
|| T::FormattedValueType::default_format() == self.format()
{
Ok(FormattedSegment(self.0, PhantomData)) Ok(FormattedSegment(self.0, PhantomData))
} else { } else {
Err(self) Err(self)
} }
} }
pub fn downcast_ref<T: FormattedValue>(&self) -> Option<&FormattedSegment<T>> { pub fn downcast_ref<T: FormattedValueIntrinsic>(&self) -> Option<&FormattedSegment<T>> {
if T::default_format() == Format::Undefined || T::default_format() == self.format() { if T::FormattedValueType::default_format() == Format::Undefined
|| T::FormattedValueType::default_format() == self.format()
{
Some(unsafe { Some(unsafe {
&*(self as *const FormattedSegment<GenericFormattedValue> &*(self as *const FormattedSegment<GenericFormattedValue>
as *const FormattedSegment<T>) as *const FormattedSegment<T>)
@ -47,8 +51,10 @@ impl Segment {
} }
} }
pub fn downcast_mut<T: FormattedValue>(&mut self) -> Option<&mut FormattedSegment<T>> { pub fn downcast_mut<T: FormattedValueIntrinsic>(&mut self) -> Option<&mut FormattedSegment<T>> {
if T::default_format() == Format::Undefined || T::default_format() == self.format() { if T::FormattedValueType::default_format() == Format::Undefined
|| T::FormattedValueType::default_format() == self.format()
{
Some(unsafe { Some(unsafe {
&mut *(self as *mut FormattedSegment<GenericFormattedValue> &mut *(self as *mut FormattedSegment<GenericFormattedValue>
as *mut FormattedSegment<T>) as *mut FormattedSegment<T>)
@ -59,12 +65,15 @@ impl Segment {
} }
} }
impl<T: FormattedValue> FormattedSegment<T> { impl<T: FormattedValueIntrinsic> FormattedSegment<T> {
pub fn new() -> Self { pub fn new() -> Self {
assert_initialized_main_thread!(); assert_initialized_main_thread!();
let segment = unsafe { let segment = unsafe {
let mut segment = mem::MaybeUninit::zeroed(); 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() segment.assume_init()
}; };
FormattedSegment(segment, PhantomData) FormattedSegment(segment, PhantomData)
@ -82,16 +91,23 @@ impl<T: FormattedValue> FormattedSegment<T> {
pub fn reset(&mut self) { pub fn reset(&mut self) {
unsafe { 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")] #[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 start = start.into();
let stop = stop.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(), start.format());
assert_eq!(self.format(), stop.format()); assert_eq!(self.format(), stop.format());
} }
@ -102,15 +118,15 @@ impl<T: FormattedValue> FormattedSegment<T> {
let ret = from_glib(ffi::gst_segment_clip( let ret = from_glib(ffi::gst_segment_clip(
&self.0, &self.0,
start.format().into_glib(), start.format().into_glib(),
start.to_raw_value() as u64, start.into_raw_value() as u64,
stop.to_raw_value() as u64, stop.into_raw_value() as u64,
clip_start.as_mut_ptr(), clip_start.as_mut_ptr(),
clip_stop.as_mut_ptr(), clip_stop.as_mut_ptr(),
)); ));
if ret { if ret {
Some(( Some((
T::from_raw(self.format(), clip_start.assume_init() as i64), T::FormattedValueType::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_stop.assume_init() as i64),
)) ))
} else { } else {
None None
@ -120,7 +136,7 @@ impl<T: FormattedValue> FormattedSegment<T> {
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
#[doc(alias = "gst_segment_do_seek")] #[doc(alias = "gst_segment_do_seek")]
pub fn do_seek<V: Into<T>>( pub fn do_seek<V: Into<T::FormattedValueType>>(
&mut self, &mut self,
rate: f64, rate: f64,
flags: SeekFlags, flags: SeekFlags,
@ -133,7 +149,7 @@ impl<T: FormattedValue> FormattedSegment<T> {
let start = start.into(); let start = start.into();
let stop = stop.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(), start.format());
assert_eq!(self.format(), stop.format()); assert_eq!(self.format(), stop.format());
} }
@ -146,9 +162,9 @@ impl<T: FormattedValue> FormattedSegment<T> {
self.format().into_glib(), self.format().into_glib(),
flags.into_glib(), flags.into_glib(),
start_type.into_glib(), start_type.into_glib(),
start.to_raw_value() as u64, start.into_raw_value() as u64,
stop_type.into_glib(), stop_type.into_glib(),
stop.to_raw_value() as u64, stop.into_raw_value() as u64,
update.as_mut_ptr(), update.as_mut_ptr(),
)); ));
if ret { if ret {
@ -174,30 +190,36 @@ impl<T: FormattedValue> FormattedSegment<T> {
} }
#[doc(alias = "gst_segment_position_from_running_time")] #[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(); 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()); assert_eq!(self.format(), running_time.format());
} }
unsafe { unsafe {
T::from_raw( T::FormattedValueType::from_raw(
self.format(), self.format(),
ffi::gst_segment_position_from_running_time( ffi::gst_segment_position_from_running_time(
&self.0, &self.0,
self.format().into_glib(), self.format().into_glib(),
running_time.to_raw_value() as u64, running_time.into_raw_value() as u64,
) as i64, ) as i64,
) )
} }
} }
#[doc(alias = "gst_segment_position_from_running_time_full")] #[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(); 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()); 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( let ret = ffi::gst_segment_position_from_running_time_full(
&self.0, &self.0,
self.format().into_glib(), self.format().into_glib(),
running_time.to_raw_value() as u64, running_time.into_raw_value() as u64,
position.as_mut_ptr(), position.as_mut_ptr(),
); );
( (
ret, 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")] #[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(); 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()); assert_eq!(self.format(), stream_time.format());
} }
unsafe { unsafe {
T::from_raw( T::FormattedValueType::from_raw(
self.format(), self.format(),
ffi::gst_segment_position_from_stream_time( ffi::gst_segment_position_from_stream_time(
&self.0, &self.0,
self.format().into_glib(), self.format().into_glib(),
stream_time.to_raw_value() as u64, stream_time.into_raw_value() as u64,
) as i64, ) as i64,
) )
} }
} }
#[doc(alias = "gst_segment_position_from_stream_time_full")] #[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(); 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()); 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( let ret = ffi::gst_segment_position_from_stream_time_full(
&self.0, &self.0,
self.format().into_glib(), self.format().into_glib(),
stream_time.to_raw_value() as u64, stream_time.into_raw_value() as u64,
position.as_mut_ptr(), position.as_mut_ptr(),
); );
( (
ret, 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")] #[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(); 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()); assert_eq!(self.format(), running_time.format());
} }
@ -272,7 +303,7 @@ impl<T: FormattedValue> FormattedSegment<T> {
ffi::gst_segment_set_running_time( ffi::gst_segment_set_running_time(
&mut self.0, &mut self.0,
self.format().into_glib(), 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" "Running time is not in the segment"
) )
@ -280,30 +311,36 @@ impl<T: FormattedValue> FormattedSegment<T> {
} }
#[doc(alias = "gst_segment_to_running_time")] #[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(); let position = position.into();
if T::default_format() == Format::Undefined { if T::FormattedValueType::default_format() == Format::Undefined {
assert_eq!(self.format(), position.format()); assert_eq!(self.format(), position.format());
} }
unsafe { unsafe {
T::from_raw( T::FormattedValueType::from_raw(
self.format(), self.format(),
ffi::gst_segment_to_running_time( ffi::gst_segment_to_running_time(
&self.0, &self.0,
self.format().into_glib(), self.format().into_glib(),
position.to_raw_value() as u64, position.into_raw_value() as u64,
) as i64, ) as i64,
) )
} }
} }
#[doc(alias = "gst_segment_to_running_time_full")] #[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(); let position = position.into();
if T::default_format() == Format::Undefined { if T::FormattedValueType::default_format() == Format::Undefined {
assert_eq!(self.format(), position.format()); assert_eq!(self.format(), position.format());
} }
@ -312,41 +349,47 @@ impl<T: FormattedValue> FormattedSegment<T> {
let ret = ffi::gst_segment_to_running_time_full( let ret = ffi::gst_segment_to_running_time_full(
&self.0, &self.0,
self.format().into_glib(), self.format().into_glib(),
position.to_raw_value() as u64, position.into_raw_value() as u64,
running_time.as_mut_ptr(), running_time.as_mut_ptr(),
); );
( (
ret, 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")] #[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(); let position = position.into();
if T::default_format() == Format::Undefined { if T::FormattedValueType::default_format() == Format::Undefined {
assert_eq!(self.format(), position.format()); assert_eq!(self.format(), position.format());
} }
unsafe { unsafe {
T::from_raw( T::FormattedValueType::from_raw(
self.format(), self.format(),
ffi::gst_segment_to_stream_time( ffi::gst_segment_to_stream_time(
&self.0, &self.0,
self.format().into_glib(), self.format().into_glib(),
position.to_raw_value() as u64, position.into_raw_value() as u64,
) as i64, ) as i64,
) )
} }
} }
#[doc(alias = "gst_segment_to_stream_time_full")] #[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(); let position = position.into();
if T::default_format() == Format::Undefined { if T::FormattedValueType::default_format() == Format::Undefined {
assert_eq!(self.format(), position.format()); assert_eq!(self.format(), position.format());
} }
@ -355,12 +398,12 @@ impl<T: FormattedValue> FormattedSegment<T> {
let ret = ffi::gst_segment_to_stream_time_full( let ret = ffi::gst_segment_to_stream_time_full(
&self.0, &self.0,
self.format().into_glib(), self.format().into_glib(),
position.to_raw_value() as u64, position.into_raw_value() as u64,
stream_time.as_mut_ptr(), stream_time.as_mut_ptr(),
); );
( (
ret, 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")] #[doc(alias = "get_base")]
pub fn base(&self) -> T { pub fn base(&self) -> T::FormattedValueType {
unsafe { T::from_raw(self.format(), self.0.base as i64) } 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(); let base = base.into();
if T::default_format() == Format::Undefined { if T::FormattedValueType::default_format() == Format::Undefined {
assert_eq!(self.format(), base.format()); 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")] #[doc(alias = "get_offset")]
pub fn offset(&self) -> T { pub fn offset(&self) -> T::FormattedValueType {
unsafe { T::from_raw(self.format(), self.0.offset as i64) } 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(); let offset = offset.into();
if T::default_format() == Format::Undefined { if T::FormattedValueType::default_format() == Format::Undefined {
assert_eq!(self.format(), offset.format()); 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")] #[doc(alias = "get_start")]
pub fn start(&self) -> T { pub fn start(&self) -> T::FormattedValueType {
unsafe { T::from_raw(self.format(), self.0.start as i64) } 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(); let start = start.into();
if T::default_format() == Format::Undefined { if T::FormattedValueType::default_format() == Format::Undefined {
assert_eq!(self.format(), start.format()); 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")] #[doc(alias = "get_stop")]
pub fn stop(&self) -> T { pub fn stop(&self) -> T::FormattedValueType {
unsafe { T::from_raw(self.format(), self.0.stop as i64) } 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(); let stop = stop.into();
if T::default_format() == Format::Undefined { if T::FormattedValueType::default_format() == Format::Undefined {
assert_eq!(self.format(), stop.format()); 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")] #[doc(alias = "get_time")]
pub fn time(&self) -> T { pub fn time(&self) -> T::FormattedValueType {
unsafe { T::from_raw(self.format(), self.0.time as i64) } 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(); let time = time.into();
if T::default_format() == Format::Undefined { if T::FormattedValueType::default_format() == Format::Undefined {
assert_eq!(self.format(), time.format()); 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")] #[doc(alias = "get_position")]
pub fn position(&self) -> T { pub fn position(&self) -> T::FormattedValueType {
unsafe { T::from_raw(self.format(), self.0.position as i64) } 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(); let position = position.into();
if T::default_format() == Format::Undefined { if T::FormattedValueType::default_format() == Format::Undefined {
assert_eq!(self.format(), position.format()); 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")] #[doc(alias = "get_duration")]
pub fn duration(&self) -> T { pub fn duration(&self) -> T::FormattedValueType {
unsafe { T::from_raw(self.format(), self.0.duration as i64) } 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(); let duration = duration.into();
if T::default_format() == Format::Undefined { if T::FormattedValueType::default_format() == Format::Undefined {
assert_eq!(self.format(), duration.format()); 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] #[inline]
#[doc(alias = "gst_segment_is_equal")] #[doc(alias = "gst_segment_is_equal")]
fn eq(&self, other: &Self) -> bool { 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: FormattedValueIntrinsic> Send for FormattedSegment<T> {}
unsafe impl<T: FormattedValue> Sync 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 { fn clone(&self) -> Self {
unsafe { FormattedSegment(ptr::read(&self.0), PhantomData) } 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 { fn as_ref(&self) -> &Segment {
unsafe { unsafe {
&*(self as *const FormattedSegment<T> as *const FormattedSegment<GenericFormattedValue>) &*(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 { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use crate::utils::Displayable;
let segment = self.as_ref(); let segment = self.as_ref();
match segment.format() { match segment.format() {
Format::Undefined => f Format::Undefined => f
@ -546,16 +591,16 @@ impl<T: FormattedValue> fmt::Debug for FormattedSegment<T> {
let segment = segment.downcast_ref::<crate::ClockTime>().unwrap(); let segment = segment.downcast_ref::<crate::ClockTime>().unwrap();
f.debug_struct("Segment") f.debug_struct("Segment")
.field("format", &Format::Time) .field("format", &Format::Time)
.field("start", &segment.start().to_string()) .field("start", &segment.start().display().to_string())
.field("offset", &segment.offset().to_string()) .field("offset", &segment.offset().display().to_string())
.field("stop", &segment.stop().to_string()) .field("stop", &segment.stop().display().to_string())
.field("rate", &segment.rate()) .field("rate", &segment.rate())
.field("applied_rate", &segment.applied_rate()) .field("applied_rate", &segment.applied_rate())
.field("flags", &segment.flags()) .field("flags", &segment.flags())
.field("time", &segment.time().to_string()) .field("time", &segment.time().display().to_string())
.field("base", &segment.base().to_string()) .field("base", &segment.base().display().to_string())
.field("position", &segment.position().to_string()) .field("position", &segment.position().display().to_string())
.field("duration", &segment.duration().to_string()) .field("duration", &segment.duration().display().to_string())
.finish() .finish()
} }
_ => f _ => 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 { fn default() -> Self {
Self::new() 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 { fn static_type() -> glib::types::Type {
unsafe { glib::translate::from_glib(ffi::gst_segment_get_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)] #[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 { fn to_value(&self) -> glib::Value {
let mut value = glib::Value::for_value_type::<Segment>(); let mut value = glib::Value::for_value_type::<Segment>();
unsafe { unsafe {
@ -623,7 +668,7 @@ impl<T: FormattedValue> glib::value::ToValue for FormattedSegment<T> {
} }
#[doc(hidden)] #[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 { fn to_value_optional(s: Option<&Self>) -> glib::Value {
skip_assert_initialized!(); skip_assert_initialized!();
let mut value = glib::Value::for_value_type::<Segment>(); 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)]
#[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; type GlibType = *mut ffi::GstSegment;
} }
#[doc(hidden)] #[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> for FormattedSegment<T>
{ {
type Storage = &'a FormattedSegment<T>; type Storage = &'a FormattedSegment<T>;
@ -658,7 +703,7 @@ impl<'a, T: FormattedValue> glib::translate::ToGlibPtr<'a, *const ffi::GstSegmen
} }
#[doc(hidden)] #[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> for FormattedSegment<T>
{ {
type Storage = &'a mut FormattedSegment<T>; type Storage = &'a mut FormattedSegment<T>;

View file

@ -7,10 +7,11 @@ use serde::ser::{Serialize, Serializer};
use crate::Format; use crate::Format;
use crate::FormattedSegment; use crate::FormattedSegment;
use crate::FormattedValue; use crate::FormattedValue;
use crate::FormattedValueIntrinsic;
use crate::GenericFormattedValue; use crate::GenericFormattedValue;
use crate::Segment; use crate::Segment;
use crate::SegmentFlags; use crate::SegmentFlags;
use crate::SpecificFormattedValue; use crate::SpecificFormattedValueIntrinsic;
#[derive(serde::Serialize, serde::Deserialize)] #[derive(serde::Serialize, serde::Deserialize)]
struct FormattedSegmentSerde { struct FormattedSegmentSerde {
@ -27,7 +28,7 @@ struct FormattedSegmentSerde {
duration: i64, 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> { fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let fmt_seg = unsafe { let fmt_seg = unsafe {
FormattedSegmentSerde { FormattedSegmentSerde {
@ -35,13 +36,13 @@ impl<T: FormattedValue> Serialize for FormattedSegment<T> {
rate: self.rate(), rate: self.rate(),
applied_rate: self.applied_rate(), applied_rate: self.applied_rate(),
format: self.format(), format: self.format(),
base: self.base().to_raw_value(), base: self.base().into_raw_value(),
offset: self.offset().to_raw_value(), offset: self.offset().into_raw_value(),
start: self.start().to_raw_value(), start: self.start().into_raw_value(),
stop: self.stop().to_raw_value(), stop: self.stop().into_raw_value(),
time: self.time().to_raw_value(), time: self.time().into_raw_value(),
position: self.position().to_raw_value(), position: self.position().into_raw_value(),
duration: self.duration().to_raw_value(), duration: self.duration().into_raw_value(),
} }
}; };
fmt_seg.serialize(serializer) 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> { fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
skip_assert_initialized!(); skip_assert_initialized!();
Segment::deserialize(deserializer).and_then(|segment| { Segment::deserialize(deserializer).and_then(|segment| {
@ -99,7 +100,7 @@ impl<'de, T: FormattedValue + SpecificFormattedValue> Deserialize<'de> for Forma
de::Error::custom(format!( de::Error::custom(format!(
"failed to convert segment with format {:?} to {:?}", "failed to convert segment with format {:?} to {:?}",
segment.format(), segment.format(),
T::default_format(), T::FormattedValueType::default_format(),
)) ))
}) })
}) })
@ -123,13 +124,13 @@ mod tests {
segment.set_rate(1f64); segment.set_rate(1f64);
segment.set_applied_rate(0.9f64); segment.set_applied_rate(0.9f64);
segment.set_format(Format::Time); segment.set_format(Format::Time);
segment.set_base(GenericFormattedValue::Time(ClockTime::from_nseconds(123))); segment.set_base(GenericFormattedValue::from(ClockTime::from_nseconds(123)));
segment.set_offset(GenericFormattedValue::Time(ClockTime::from_nseconds(42))); segment.set_offset(GenericFormattedValue::from(ClockTime::from_nseconds(42)));
segment.set_start(GenericFormattedValue::Time(ClockTime::from_nseconds(1024))); segment.set_start(GenericFormattedValue::from(ClockTime::from_nseconds(1024)));
segment.set_stop(GenericFormattedValue::Time(ClockTime::from_nseconds(2048))); segment.set_stop(GenericFormattedValue::from(ClockTime::from_nseconds(2048)));
segment.set_time(GenericFormattedValue::Time(ClockTime::from_nseconds(1042))); segment.set_time(GenericFormattedValue::from(ClockTime::from_nseconds(1042)));
segment.set_position(GenericFormattedValue::Time(ClockTime::from_nseconds(256))); segment.set_position(GenericFormattedValue::from(ClockTime::from_nseconds(256)));
segment.set_duration(GenericFormattedValue::Time(ClockTime::none())); segment.set_duration(GenericFormattedValue::from(ClockTime::NONE));
let pretty_config = ron::ser::PrettyConfig::new().with_new_line("".to_string()); 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.rate() - 1f64).abs() < std::f64::EPSILON);
assert!((segment.applied_rate() - 0.9f64).abs() < std::f64::EPSILON); assert!((segment.applied_rate() - 0.9f64).abs() < std::f64::EPSILON);
assert_eq!(segment.format(), Format::Time); 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!( assert_eq!(
segment.base(), segment.base(),
GenericFormattedValue::Time(ClockTime::from_nseconds(123)) GenericFormattedValue::from(ClockTime::from_nseconds(123)),
); );
assert_eq!( assert_eq!(
segment.offset(), segment.offset(),
GenericFormattedValue::Time(ClockTime::from_nseconds(42)) GenericFormattedValue::from(ClockTime::from_nseconds(42)),
); );
assert_eq!( assert_eq!(
segment.start(), segment.start(),
GenericFormattedValue::Time(ClockTime::from_nseconds(1024)) GenericFormattedValue::from(ClockTime::from_nseconds(1024)),
); );
assert_eq!( assert_eq!(
segment.stop(), segment.stop(),
GenericFormattedValue::Time(ClockTime::from_nseconds(2048)) GenericFormattedValue::from(ClockTime::from_nseconds(2048)),
); );
assert_eq!( assert_eq!(
segment.time(), segment.time(),
GenericFormattedValue::Time(ClockTime::from_nseconds(1042)) GenericFormattedValue::from(ClockTime::from_nseconds(1042)),
); );
assert_eq!( assert_eq!(
segment.position(), segment.position(),
GenericFormattedValue::Time(ClockTime::from_nseconds(256)) GenericFormattedValue::from(ClockTime::from_nseconds(256)),
); );
assert_eq!( assert_eq!(
segment.duration(), 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.rate() - 1f64).abs() < std::f64::EPSILON);
assert!((fmt_seg.applied_rate() - 0.9f64).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.format(), Format::Time);
assert_eq!(fmt_seg.base(), ClockTime::from_nseconds(123)); assert_eq!(fmt_seg.base(), Some(ClockTime::from_nseconds(123)));
assert_eq!(fmt_seg.offset(), ClockTime::from_nseconds(42)); assert_eq!(fmt_seg.offset(), Some(ClockTime::from_nseconds(42)));
assert_eq!(fmt_seg.start(), ClockTime::from_nseconds(1024)); assert_eq!(fmt_seg.start(), Some(ClockTime::from_nseconds(1024)));
assert_eq!(fmt_seg.stop(), ClockTime::from_nseconds(2048)); assert_eq!(fmt_seg.stop(), Some(ClockTime::from_nseconds(2048)));
assert_eq!(fmt_seg.time(), ClockTime::from_nseconds(1042)); assert_eq!(fmt_seg.time(), Some(ClockTime::from_nseconds(1042)));
assert_eq!(fmt_seg.position(), ClockTime::from_nseconds(256)); assert_eq!(fmt_seg.position(), Some(ClockTime::from_nseconds(256)));
assert_eq!(fmt_seg.duration(), ClockTime::none()); assert_eq!(fmt_seg.duration(), ClockTime::NONE);
} }
#[test] #[test]
@ -262,13 +267,13 @@ mod tests {
segment.set_rate(1f64); segment.set_rate(1f64);
segment.set_applied_rate(0.9f64); segment.set_applied_rate(0.9f64);
segment.set_format(Format::Time); segment.set_format(Format::Time);
segment.set_base(GenericFormattedValue::Time(ClockTime::from_nseconds(123))); segment.set_base(GenericFormattedValue::from(ClockTime::from_nseconds(123)));
segment.set_offset(GenericFormattedValue::Time(ClockTime::from_nseconds(42))); segment.set_offset(GenericFormattedValue::from(ClockTime::from_nseconds(42)));
segment.set_start(GenericFormattedValue::Time(ClockTime::from_nseconds(1024))); segment.set_start(GenericFormattedValue::from(ClockTime::from_nseconds(1024)));
segment.set_stop(GenericFormattedValue::Time(ClockTime::from_nseconds(2048))); segment.set_stop(GenericFormattedValue::from(ClockTime::from_nseconds(2048)));
segment.set_time(GenericFormattedValue::Time(ClockTime::from_nseconds(1042))); segment.set_time(GenericFormattedValue::from(ClockTime::from_nseconds(1042)));
segment.set_position(GenericFormattedValue::Time(ClockTime::from_nseconds(256))); segment.set_position(GenericFormattedValue::from(ClockTime::from_nseconds(256)));
segment.set_duration(GenericFormattedValue::Time(ClockTime::none())); segment.set_duration(GenericFormattedValue::from(ClockTime::NONE));
let segment_se = ron::ser::to_string(&segment).unwrap(); let segment_se = ron::ser::to_string(&segment).unwrap();
let segment_de: Segment = ron::de::from_str(segment_se.as_str()).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, clock: &Self::Type,
old_resolution: ClockTime, old_resolution: ClockTime,
new_resolution: ClockTime, new_resolution: ClockTime,
) -> ClockTime { ) -> Option<ClockTime> {
self.parent_change_resolution(clock, old_resolution, new_resolution) 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) 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) self.parent_internal_time(clock)
} }
@ -53,11 +53,11 @@ pub trait ClockImplExt: ObjectSubclass {
clock: &Self::Type, clock: &Self::Type,
old_resolution: ClockTime, old_resolution: ClockTime,
new_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( fn parent_wait(
&self, &self,
@ -85,7 +85,7 @@ impl<T: ClockImpl> ClockImplExt for T {
clock: &Self::Type, clock: &Self::Type,
old_resolution: ClockTime, old_resolution: ClockTime,
new_resolution: ClockTime, new_resolution: ClockTime,
) -> ClockTime { ) -> Option<ClockTime> {
unsafe { unsafe {
let data = Self::type_data(); let data = Self::type_data();
let parent_class = data.as_ref().parent_class() as *mut ffi::GstClockClass; 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 { unsafe {
let data = Self::type_data(); let data = Self::type_data();
let parent_class = data.as_ref().parent_class() as *mut ffi::GstClockClass; 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 { unsafe {
let data = Self::type_data(); let data = Self::type_data();
let parent_class = data.as_ref().parent_class() as *mut ffi::GstClockClass; let parent_class = data.as_ref().parent_class() as *mut ffi::GstClockClass;
@ -254,12 +254,17 @@ unsafe extern "C" fn clock_change_resolution<T: ClockImpl>(
let imp = instance.impl_(); let imp = instance.impl_();
let wrap: Borrowed<Clock> = from_glib_borrow(ptr); let wrap: Borrowed<Clock> = from_glib_borrow(ptr);
imp.change_resolution( let old_resolution = match from_glib(old_resolution) {
wrap.unsafe_cast_ref(), Some(old_resolution) => old_resolution,
from_glib(old_resolution), None => return ffi::GST_CLOCK_TIME_NONE,
from_glib(new_resolution), };
) let new_resolution = match from_glib(new_resolution) {
.into_glib() 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()
} }
unsafe extern "C" fn clock_get_resolution<T: ClockImpl>( unsafe extern "C" fn clock_get_resolution<T: ClockImpl>(

View file

@ -797,7 +797,7 @@ mod tests {
pipeline.set_state(crate::State::Playing).unwrap(); pipeline.set_state(crate::State::Playing).unwrap();
let bus = pipeline.bus().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()); assert!(eos.is_some());
pipeline.set_state(crate::State::Null).unwrap(); pipeline.set_state(crate::State::Null).unwrap();

View file

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

View file

@ -311,6 +311,7 @@ impl<'de> Deserialize<'de> for TagList {
mod tests { mod tests {
use crate::tags::*; use crate::tags::*;
use crate::Buffer; use crate::Buffer;
use crate::ClockTime;
use crate::Sample; use crate::Sample;
use crate::TagMergeMode; use crate::TagMergeMode;
use crate::TagScope; use crate::TagScope;
@ -325,7 +326,7 @@ mod tests {
let tags = tags.get_mut().unwrap(); let tags = tags.get_mut().unwrap();
tags.add::<Title>(&"a title", TagMergeMode::Append); // String tags.add::<Title>(&"a title", TagMergeMode::Append); // String
tags.add::<Title>(&"another 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::<Bitrate>(&96_000, TagMergeMode::Append); // u32
tags.add::<TrackGain>(&1f64, TagMergeMode::Append); // f64 tags.add::<TrackGain>(&1f64, TagMergeMode::Append); // f64
tags.add::<Date>( tags.add::<Date>(
@ -465,9 +466,10 @@ mod tests {
assert_eq!(tags.index::<Title>(0).unwrap().get(), "a title"); 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::<Title>(1).unwrap().get(), "another title");
assert_eq!( assert_eq!(
tags.index::<Duration>(0).unwrap().get(), tags.index::<Duration>(0).unwrap().get(),
crate::SECOND * 120 120 * ClockTime::SECOND,
); );
assert_eq!(tags.index::<Bitrate>(0).unwrap().get(), 96_000); assert_eq!(tags.index::<Bitrate>(0).unwrap().get(), 96_000);
assert!((tags.index::<TrackGain>(0).unwrap().get() - 1f64).abs() < std::f64::EPSILON); assert!((tags.index::<TrackGain>(0).unwrap().get() - 1f64).abs() < std::f64::EPSILON);
@ -534,7 +536,7 @@ mod tests {
tags.set_scope(TagScope::Global); tags.set_scope(TagScope::Global);
tags.add::<Title>(&"a title", TagMergeMode::Append); // String tags.add::<Title>(&"a title", TagMergeMode::Append); // String
tags.add::<Title>(&"another 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::<Bitrate>(&96_000, TagMergeMode::Append); // u32
tags.add::<TrackGain>(&1f64, TagMergeMode::Append); // f64 tags.add::<TrackGain>(&1f64, TagMergeMode::Append); // f64
tags.add::<Date>( 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 { fn send_seek_event(pipeline: &Element, rate: f64) -> bool {
// Obtain the current position, needed for the seek event // 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, Some(pos) => pos,
None => { None => {
eprintln!("Unable to retrieve current position...\r"); eprintln!("Unable to retrieve current position...\r");
@ -42,7 +42,7 @@ fn send_seek_event(pipeline: &Element, rate: f64) -> bool {
SeekType::Set, SeekType::Set,
position, position,
SeekType::End, SeekType::End,
gst::ClockTime::from(0), gst::ClockTime::ZERO,
) )
} else { } else {
Seek::new( Seek::new(

View file

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

View file

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

View file

@ -107,7 +107,7 @@ fn on_discovered(
return; return;
} }
println!("Duration: {}", discoverer_info.duration()); println!("Duration: {}", discoverer_info.duration().display());
if let Some(tags) = discoverer_info.tags() { if let Some(tags) = discoverer_info.tags() {
println!("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(position) = pipeline.query_position::<gst::ClockTime>() {
if let Some(duration) = pipeline.query_duration::<gst::ClockTime>() { if let Some(duration) = pipeline.query_duration::<gst::ClockTime>() {
let current_progress = 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(); let buffering_level = buffering_level.lock().unwrap();
graph[current_progress as usize] = if *buffering_level < 100 { b'X' } else { b'>' }; graph[current_progress as usize] = if *buffering_level < 100 { b'X' } else { b'>' };
} }