Change FormatValue related API to be more convenient to use

FormatValue is now renamed to GenericFormattedValue and the API slightly
changed. In addition there is now a FormattedValue trait, and a
SpecificFormattedValue trait plus types for Bytes, Buffers and the
existing ClockTime.

This allows to create functions like
  Pad::query_duration<F: SpecificFormattedValue>() -> Option<F>
and doesn't require the caller to unwrap the generic value anymore,
which is completely unneeded in these cases.

In addition, Segment became FormattedSegment<T> with API to
upcast/downcast between the specific formatted values and the generic
formatted value. This greatly simplifies usage of Segments.
This commit is contained in:
Sebastian Dröge 2017-12-09 18:20:21 +02:00
parent 520a9bb879
commit c99928d030
17 changed files with 1212 additions and 761 deletions

View file

@ -59,13 +59,9 @@ fn create_ui(app: &gtk::Application) {
let pipeline_clone = pipeline.clone(); let pipeline_clone = pipeline.clone();
gtk::timeout_add(500, move || { gtk::timeout_add(500, move || {
let pipeline = &pipeline_clone; let pipeline = &pipeline_clone;
let position = if let Some(gst::FormatValue::Time(position)) = let position = pipeline
pipeline.query_position(gst::Format::Time) .query_position::<gst::ClockTime>()
{ .unwrap_or(0.into());
position
} else {
0.into()
};
label.set_text(&format!("Position: {:.0}", position)); label.set_text(&format!("Position: {:.0}", position));
glib::Continue(true) glib::Continue(true)

View file

@ -129,13 +129,9 @@ fn create_ui(app: &gtk::Application) {
let pipeline_clone = pipeline.clone(); let pipeline_clone = pipeline.clone();
gtk::timeout_add(500, move || { gtk::timeout_add(500, move || {
let pipeline = &pipeline_clone; let pipeline = &pipeline_clone;
let position = if let Some(gst::FormatValue::Time(position)) = let position = pipeline
pipeline.query_position(gst::Format::Time) .query_position::<gst::ClockTime>()
{ .unwrap_or(0.into());
position
} else {
0.into()
};
label.set_text(&format!("Position: {:.0}", position)); label.set_text(&format!("Position: {:.0}", position));
glib::Continue(true) glib::Continue(true)

View file

@ -41,7 +41,7 @@ fn example_main() {
} else { } else {
None None
} }
}.and_then(|pos| pos.try_to_time()) }.and_then(|pos| pos.try_into_time().ok())
.unwrap(); .unwrap();
let dur = { let dur = {
@ -54,7 +54,7 @@ fn example_main() {
} else { } else {
None None
} }
}.and_then(|dur| dur.try_to_time()) }.and_then(|dur| dur.try_into_time().ok())
.unwrap(); .unwrap();
println!("{} / {}", pos, dur); println!("{} / {}", pos, dur);

View file

@ -11,7 +11,7 @@ use glib_ffi;
use gobject_ffi; use gobject_ffi;
use gst; use gst;
use gst::miniobject::MiniObject; use gst::prelude::*;
use glib; use glib;
use glib::translate::{from_glib, from_glib_full, from_glib_none, FromGlibPtrNone, ToGlib, use glib::translate::{from_glib, from_glib_full, from_glib_none, FromGlibPtrNone, ToGlib,
ToGlibPtr, ToGlibPtrMut}; ToGlibPtr, ToGlibPtrMut};
@ -155,23 +155,47 @@ impl AudioInfo {
} }
} }
pub fn convert( pub fn convert<V: Into<gst::GenericFormattedValue>, U: gst::SpecificFormattedValue>(
&self, &self,
src_val: gst::FormatValue, src_val: V,
dest_fmt: gst::Format, ) -> Option<U> {
) -> Option<gst::FormatValue> {
assert_initialized_main_thread!(); assert_initialized_main_thread!();
let src_val = src_val.into();
unsafe { unsafe {
let mut dest_val = mem::uninitialized(); let mut dest_val = mem::uninitialized();
if from_glib(ffi::gst_audio_info_convert( if from_glib(ffi::gst_audio_info_convert(
&self.0, &self.0,
src_val.to_format().to_glib(), src_val.get_format().to_glib(),
src_val.to_value(), src_val.to_glib(),
U::get_default_format().to_glib(),
&mut dest_val,
)) {
Some(U::from_glib(U::get_default_format(), dest_val))
} else {
None
}
}
}
pub fn convert_generic<V: Into<gst::GenericFormattedValue>>(
&self,
src_val: V,
dest_fmt: gst::Format,
) -> Option<gst::GenericFormattedValue> {
assert_initialized_main_thread!();
let src_val = src_val.into();
unsafe {
let mut dest_val = mem::uninitialized();
if from_glib(ffi::gst_audio_info_convert(
&self.0,
src_val.get_format().to_glib(),
src_val.to_glib(),
dest_fmt.to_glib(), dest_fmt.to_glib(),
&mut dest_val, &mut dest_val,
)) { )) {
Some(gst::FormatValue::new(dest_fmt, dest_val)) Some(gst::GenericFormattedValue::new(dest_fmt, dest_val))
} else { } else {
None None
} }

View file

@ -11,7 +11,7 @@ use glib_ffi;
use gobject_ffi; use gobject_ffi;
use gst; use gst;
use gst::miniobject::MiniObject; use gst::prelude::*;
use glib; use glib;
use glib::translate::{from_glib, from_glib_full, from_glib_none, FromGlib, FromGlibPtrNone, use glib::translate::{from_glib, from_glib_full, from_glib_none, FromGlib, FromGlibPtrNone,
ToGlib, ToGlibPtr, ToGlibPtrMut}; ToGlib, ToGlibPtr, ToGlibPtrMut};
@ -545,25 +545,47 @@ impl VideoInfo {
self.format_info().n_components() self.format_info().n_components()
} }
pub fn convert<V: Into<gst::FormatValue>>( pub fn convert<V: Into<gst::GenericFormattedValue>, U: gst::SpecificFormattedValue>(
&self, &self,
src_val: V, src_val: V,
dest_fmt: gst::Format, ) -> Option<U> {
) -> Option<gst::FormatValue> {
skip_assert_initialized!(); skip_assert_initialized!();
let src_val = src_val.into(); let src_val = src_val.into();
unsafe { unsafe {
let mut dest_val = mem::uninitialized(); let mut dest_val = mem::uninitialized();
if from_glib(ffi::gst_video_info_convert( if from_glib(ffi::gst_video_info_convert(
&self.0 as *const _ as *mut _, &self.0 as *const _ as *mut _,
src_val.to_format().to_glib(), src_val.get_format().to_glib(),
src_val.to_value(), src_val.to_glib(),
U::get_default_format().to_glib(),
&mut dest_val,
)) {
Some(U::from_glib(U::get_default_format(), dest_val))
} else {
None
}
}
}
pub fn convert_generic<V: Into<gst::GenericFormattedValue>>(
&self,
src_val: V,
dest_fmt: gst::Format,
) -> Option<gst::GenericFormattedValue> {
skip_assert_initialized!();
let src_val = src_val.into();
unsafe {
let mut dest_val = mem::uninitialized();
if from_glib(ffi::gst_video_info_convert(
&self.0 as *const _ as *mut _,
src_val.get_format().to_glib(),
src_val.to_glib(),
dest_fmt.to_glib(), dest_fmt.to_glib(),
&mut dest_val, &mut dest_val,
)) { )) {
Some(gst::FormatValue::new(dest_fmt, dest_val)) Some(gst::GenericFormattedValue::new(dest_fmt, dest_val))
} else { } else {
None None
} }

View file

@ -6,12 +6,10 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use std::ops;
use ffi; use ffi;
use glib; use glib;
use glib::translate::*; use glib::translate::*;
use std::{cmp, fmt}; use std::{cmp, fmt};
use muldiv::MulDiv;
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)] #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)]
pub struct ClockTime(pub Option<u64>); pub struct ClockTime(pub Option<u64>);
@ -66,56 +64,6 @@ impl ClockTime {
} }
} }
impl From<u64> for ClockTime {
fn from(v: u64) -> ClockTime {
from_glib(v)
}
}
impl From<Option<u64>> for ClockTime {
fn from(v: Option<u64>) -> ClockTime {
ClockTime(v)
}
}
impl Into<u64> for ClockTime {
fn into(self) -> u64 {
self.to_glib()
}
}
impl Into<Option<u64>> for ClockTime {
fn into(self) -> Option<u64> {
self.0
}
}
impl ops::Deref for ClockTime {
type Target = Option<u64>;
fn deref(&self) -> &Option<u64> {
&self.0
}
}
impl ops::DerefMut for ClockTime {
fn deref_mut(&mut self) -> &mut Option<u64> {
&mut self.0
}
}
impl AsRef<Option<u64>> for ClockTime {
fn as_ref(&self) -> &Option<u64> {
&self.0
}
}
impl AsMut<Option<u64>> for ClockTime {
fn as_mut(&mut self) -> &mut Option<u64> {
&mut self.0
}
}
impl fmt::Display for ClockTime { impl fmt::Display for ClockTime {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
let precision = f.precision().unwrap_or(9); let precision = f.precision().unwrap_or(9);
@ -156,108 +104,6 @@ impl fmt::Display for ClockTime {
} }
} }
macro_rules! impl_op_same(
($op:ident, $op_name:ident, $op_assign:ident, $op_assign_name:ident, $e:expr) => {
impl ops::$op<ClockTime> for ClockTime {
type Output = ClockTime;
fn $op_name(self, other: ClockTime) -> ClockTime {
match (self.0, other.0) {
(Some(a), Some(b)) => ClockTime(Some($e(a, b))),
_ => ClockTime(None),
}
}
}
impl<'a> ops::$op<&'a ClockTime> for ClockTime {
type Output = ClockTime;
fn $op_name(self, other: &'a ClockTime) -> ClockTime {
self.$op_name(*other)
}
}
impl ops::$op_assign<ClockTime> for ClockTime {
fn $op_assign_name(&mut self, other: ClockTime) {
match (self.0, other.0) {
(Some(a), Some(b)) => self.0 = Some($e(a, b)),
_ => self.0 = None,
}
}
}
impl<'a> ops::$op_assign<&'a ClockTime> for ClockTime {
fn $op_assign_name(&mut self, other: &'a ClockTime) {
self.$op_assign_name(*other)
}
}
};
);
impl_op_same!(Add, add, AddAssign, add_assign, |a, b| a + b);
impl_op_same!(Sub, sub, SubAssign, sub_assign, |a, b| a - b);
impl_op_same!(Mul, mul, MulAssign, mul_assign, |a, b| a * b);
impl_op_same!(Div, div, DivAssign, div_assign, |a, b| a / b);
impl_op_same!(Rem, rem, RemAssign, rem_assign, |a, b| a % b);
macro_rules! impl_op_u64(
($op:ident, $op_name:ident, $op_assign:ident, $op_assign_name:ident, $e:expr) => {
impl ops::$op<u64> for ClockTime {
type Output = ClockTime;
fn $op_name(self, other: u64) -> ClockTime {
match self.0 {
Some(a) => ClockTime(Some($e(a, other))),
_ => ClockTime(None),
}
}
}
impl<'a> ops::$op<&'a u64> for ClockTime {
type Output = ClockTime;
fn $op_name(self, other: &'a u64) -> ClockTime {
self.$op_name(*other)
}
}
impl ops::$op_assign<u64> for ClockTime {
fn $op_assign_name(&mut self, other: u64) {
match self.0 {
Some(a) => self.0 = Some($e(a, other)),
_ => self.0 = None,
}
}
}
impl<'a> ops::$op_assign<&'a u64> for ClockTime {
fn $op_assign_name(&mut self, other: &'a u64) {
self.$op_assign_name(*other)
}
}
};
);
impl_op_u64!(Mul, mul, MulAssign, mul_assign, |a, b| a * b);
impl_op_u64!(Div, div, DivAssign, div_assign, |a, b| a / b);
impl_op_u64!(Rem, rem, RemAssign, rem_assign, |a, b| a % b);
impl ops::Mul<ClockTime> for u64 {
type Output = ClockTime;
fn mul(self, other: ClockTime) -> ClockTime {
other.mul(self)
}
}
impl<'a> ops::Mul<&'a ClockTime> for u64 {
type Output = ClockTime;
fn mul(self, other: &'a ClockTime) -> ClockTime {
other.mul(self)
}
}
#[doc(hidden)] #[doc(hidden)]
impl ToGlib for ClockTime { impl ToGlib for ClockTime {
type GlibType = ffi::GstClockTime; type GlibType = ffi::GstClockTime;
@ -309,76 +155,3 @@ impl glib::StaticType for ClockTime {
<u64 as glib::StaticType>::static_type() <u64 as glib::StaticType>::static_type()
} }
} }
impl MulDiv<ClockTime> for ClockTime {
type Output = ClockTime;
fn mul_div_floor(self, num: ClockTime, denom: ClockTime) -> Option<Self::Output> {
match (self.0, num.0, denom.0) {
(Some(s), Some(n), Some(d)) => s.mul_div_floor(n, d).map(ClockTime::from_nseconds),
_ => Some(ClockTime(None)),
}
}
fn mul_div_round(self, num: ClockTime, denom: ClockTime) -> Option<Self::Output> {
match (self.0, num.0, denom.0) {
(Some(s), Some(n), Some(d)) => s.mul_div_round(n, d).map(ClockTime::from_nseconds),
_ => Some(ClockTime(None)),
}
}
fn mul_div_ceil(self, num: ClockTime, denom: ClockTime) -> Option<Self::Output> {
match (self.0, num.0, denom.0) {
(Some(s), Some(n), Some(d)) => s.mul_div_ceil(n, d).map(ClockTime::from_nseconds),
_ => Some(ClockTime(None)),
}
}
}
impl<'a> MulDiv<&'a ClockTime> for ClockTime {
type Output = ClockTime;
fn mul_div_floor(self, num: &ClockTime, denom: &ClockTime) -> Option<Self::Output> {
self.mul_div_floor(*num, *denom)
}
fn mul_div_round(self, num: &ClockTime, denom: &ClockTime) -> Option<Self::Output> {
self.mul_div_round(*num, *denom)
}
fn mul_div_ceil(self, num: &ClockTime, denom: &ClockTime) -> Option<Self::Output> {
self.mul_div_ceil(*num, *denom)
}
}
impl<'a> MulDiv<u64> for ClockTime {
type Output = ClockTime;
fn mul_div_floor(self, num: u64, denom: u64) -> Option<Self::Output> {
self.mul_div_floor(ClockTime::from(num), ClockTime::from(denom))
}
fn mul_div_round(self, num: u64, denom: u64) -> Option<Self::Output> {
self.mul_div_round(ClockTime::from(num), ClockTime::from(denom))
}
fn mul_div_ceil(self, num: u64, denom: u64) -> Option<Self::Output> {
self.mul_div_ceil(ClockTime::from(num), ClockTime::from(denom))
}
}
impl<'a> MulDiv<&'a u64> for ClockTime {
type Output = ClockTime;
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)
}
}

View file

@ -16,6 +16,10 @@ use QueryRef;
use Event; use Event;
use Pad; use Pad;
use PadTemplate; use PadTemplate;
use Format;
use GenericFormattedValue;
use FormattedValue;
use SpecificFormattedValue;
use miniobject::MiniObject; use miniobject::MiniObject;
use std::ffi::CStr; use std::ffi::CStr;
@ -137,15 +141,23 @@ pub trait ElementExtManual {
#[cfg(any(feature = "v1_10", feature = "dox"))] #[cfg(any(feature = "v1_10", feature = "dox"))]
fn remove_property_notify_watch(&self, watch_id: NotifyWatchId); fn remove_property_notify_watch(&self, watch_id: NotifyWatchId);
fn query_convert<V: Into<::FormatValue>>( fn query_convert<V: Into<GenericFormattedValue>, U: SpecificFormattedValue>(
&self, &self,
src_val: V, src_val: V,
dest_format: ::Format, ) -> Option<U>;
) -> Option<::FormatValue>; fn query_convert_generic<V: Into<GenericFormattedValue>>(
fn query_duration(&self, format: ::Format) -> Option<::FormatValue>; &self,
fn query_position(&self, format: ::Format) -> Option<::FormatValue>; src_val: V,
dest_format: Format,
) -> Option<GenericFormattedValue>;
fn seek<V: Into<::FormatValue>>( fn query_duration<T: SpecificFormattedValue>(&self) -> Option<T>;
fn query_duration_generic(&self, format: Format) -> Option<GenericFormattedValue>;
fn query_position<T: SpecificFormattedValue>(&self) -> Option<T>;
fn query_position_generic(&self, format: Format) -> Option<GenericFormattedValue>;
fn seek<V: Into<GenericFormattedValue>>(
&self, &self,
rate: f64, rate: f64,
flags: ::SeekFlags, flags: ::SeekFlags,
@ -154,7 +166,7 @@ pub trait ElementExtManual {
stop_type: ::SeekType, stop_type: ::SeekType,
stop: V, stop: V,
) -> Result<(), glib::error::BoolError>; ) -> Result<(), glib::error::BoolError>;
fn seek_simple<V: Into<::FormatValue>>( fn seek_simple<V: Into<GenericFormattedValue>>(
&self, &self,
seek_flags: ::SeekFlags, seek_flags: ::SeekFlags,
seek_pos: V, seek_pos: V,
@ -363,30 +375,68 @@ impl<O: IsA<Element>> ElementExtManual for O {
} }
} }
fn query_convert<V: Into<::FormatValue>>( fn query_convert<V: Into<GenericFormattedValue>, U: SpecificFormattedValue>(
&self, &self,
src_val: V, src_val: V,
dest_format: ::Format, ) -> Option<U> {
) -> Option<::FormatValue> {
let src_val = src_val.into(); let src_val = src_val.into();
unsafe { unsafe {
let mut dest_val = mem::uninitialized(); let mut dest_val = mem::uninitialized();
let ret = from_glib(ffi::gst_element_query_convert( let ret = from_glib(ffi::gst_element_query_convert(
self.to_glib_none().0, self.to_glib_none().0,
src_val.to_format().to_glib(), src_val.get_format().to_glib(),
src_val.to_value(), src_val.to_glib(),
dest_format.to_glib(), U::get_default_format().to_glib(),
&mut dest_val, &mut dest_val,
)); ));
if ret { if ret {
Some(::FormatValue::new(dest_format, dest_val)) Some(U::from_glib(U::get_default_format(), dest_val))
} else { } else {
None None
} }
} }
} }
fn query_duration(&self, format: ::Format) -> Option<::FormatValue> { fn query_convert_generic<V: Into<GenericFormattedValue>>(
&self,
src_val: V,
dest_format: Format,
) -> Option<GenericFormattedValue> {
let src_val = src_val.into();
unsafe {
let mut dest_val = mem::uninitialized();
let ret = from_glib(ffi::gst_element_query_convert(
self.to_glib_none().0,
src_val.get_format().to_glib(),
src_val.get_value(),
dest_format.to_glib(),
&mut dest_val,
));
if ret {
Some(GenericFormattedValue::new(dest_format, dest_val))
} else {
None
}
}
}
fn query_duration<T: SpecificFormattedValue>(&self) -> Option<T> {
unsafe {
let mut duration = mem::uninitialized();
let ret = from_glib(ffi::gst_element_query_duration(
self.to_glib_none().0,
T::get_default_format().to_glib(),
&mut duration,
));
if ret {
Some(T::from_glib(T::get_default_format(), duration))
} else {
None
}
}
}
fn query_duration_generic(&self, format: Format) -> Option<GenericFormattedValue> {
unsafe { unsafe {
let mut duration = mem::uninitialized(); let mut duration = mem::uninitialized();
let ret = from_glib(ffi::gst_element_query_duration( let ret = from_glib(ffi::gst_element_query_duration(
@ -395,14 +445,30 @@ impl<O: IsA<Element>> ElementExtManual for O {
&mut duration, &mut duration,
)); ));
if ret { if ret {
Some(::FormatValue::new(format, duration)) Some(GenericFormattedValue::new(format, duration))
} else { } else {
None None
} }
} }
} }
fn query_position(&self, format: ::Format) -> Option<::FormatValue> { fn query_position<T: SpecificFormattedValue>(&self) -> Option<T> {
unsafe {
let mut cur = mem::uninitialized();
let ret = from_glib(ffi::gst_element_query_position(
self.to_glib_none().0,
T::get_default_format().to_glib(),
&mut cur,
));
if ret {
Some(T::from_glib(T::get_default_format(), cur))
} else {
None
}
}
}
fn query_position_generic(&self, format: Format) -> Option<GenericFormattedValue> {
unsafe { unsafe {
let mut cur = mem::uninitialized(); let mut cur = mem::uninitialized();
let ret = from_glib(ffi::gst_element_query_position( let ret = from_glib(ffi::gst_element_query_position(
@ -411,14 +477,14 @@ impl<O: IsA<Element>> ElementExtManual for O {
&mut cur, &mut cur,
)); ));
if ret { if ret {
Some(::FormatValue::new(format, cur)) Some(GenericFormattedValue::new(format, cur))
} else { } else {
None None
} }
} }
} }
fn seek<V: Into<::FormatValue>>( fn seek<V: Into<GenericFormattedValue>>(
&self, &self,
rate: f64, rate: f64,
flags: ::SeekFlags, flags: ::SeekFlags,
@ -430,26 +496,26 @@ impl<O: IsA<Element>> ElementExtManual for O {
let start = start.into(); let start = start.into();
let stop = stop.into(); let stop = stop.into();
assert_eq!(stop.to_format(), start.to_format()); assert_eq!(stop.get_format(), start.get_format());
unsafe { unsafe {
glib::error::BoolError::from_glib( glib::error::BoolError::from_glib(
ffi::gst_element_seek( ffi::gst_element_seek(
self.to_glib_none().0, self.to_glib_none().0,
rate, rate,
start.to_format().to_glib(), start.get_format().to_glib(),
flags.to_glib(), flags.to_glib(),
start_type.to_glib(), start_type.to_glib(),
start.to_value(), start.get_value(),
stop_type.to_glib(), stop_type.to_glib(),
stop.to_value(), stop.get_value(),
), ),
"Failed to seek", "Failed to seek",
) )
} }
} }
fn seek_simple<V: Into<::FormatValue>>( fn seek_simple<V: Into<GenericFormattedValue>>(
&self, &self,
seek_flags: ::SeekFlags, seek_flags: ::SeekFlags,
seek_pos: V, seek_pos: V,
@ -459,9 +525,9 @@ impl<O: IsA<Element>> ElementExtManual for O {
glib::error::BoolError::from_glib( glib::error::BoolError::from_glib(
ffi::gst_element_seek_simple( ffi::gst_element_seek_simple(
self.to_glib_none().0, self.to_glib_none().0,
seek_pos.to_format().to_glib(), seek_pos.get_format().to_glib(),
seek_flags.to_glib(), seek_flags.to_glib(),
seek_pos.to_value(), seek_pos.get_value(),
), ),
"Failed to seek", "Failed to seek",
) )

View file

@ -9,6 +9,7 @@
use ffi; use ffi;
use miniobject::*; use miniobject::*;
use structure::*; use structure::*;
use GenericFormattedValue;
use std::ptr; use std::ptr;
use std::mem; use std::mem;
@ -264,9 +265,9 @@ impl GstRc<EventRef> {
CapsBuilder::new(caps) CapsBuilder::new(caps)
} }
pub fn new_segment(segment: &::Segment) -> SegmentBuilder { pub fn new_segment<F: ::FormattedValue>(segment: &::FormattedSegment<F>) -> SegmentBuilder {
assert_initialized_main_thread!(); assert_initialized_main_thread!();
SegmentBuilder::new(segment) SegmentBuilder::new(segment.as_ref())
} }
#[cfg(any(feature = "v1_10", feature = "dox"))] #[cfg(any(feature = "v1_10", feature = "dox"))]
@ -282,7 +283,7 @@ impl GstRc<EventRef> {
TagBuilder::new(tags) TagBuilder::new(tags)
} }
pub fn new_buffer_size<'a, V: Into<::FormatValue>>( pub fn new_buffer_size<'a, V: Into<GenericFormattedValue>>(
minsize: V, minsize: V,
maxsize: V, maxsize: V,
async: bool, async: bool,
@ -290,7 +291,7 @@ impl GstRc<EventRef> {
assert_initialized_main_thread!(); assert_initialized_main_thread!();
let minsize = minsize.into(); let minsize = minsize.into();
let maxsize = maxsize.into(); let maxsize = maxsize.into();
assert_eq!(minsize.to_format(), maxsize.to_format()); assert_eq!(minsize.get_format(), maxsize.get_format());
BufferSizeBuilder::new(minsize, maxsize, async) BufferSizeBuilder::new(minsize, maxsize, async)
} }
@ -325,7 +326,9 @@ impl GstRc<EventRef> {
ProtectionBuilder::new(system_id, data, origin) ProtectionBuilder::new(system_id, data, origin)
} }
pub fn new_segment_done<'a, V: Into<::FormatValue>>(position: V) -> SegmentDoneBuilder<'a> { pub fn new_segment_done<'a, V: Into<GenericFormattedValue>>(
position: V,
) -> SegmentDoneBuilder<'a> {
assert_initialized_main_thread!(); assert_initialized_main_thread!();
let position = position.into(); let position = position.into();
SegmentDoneBuilder::new(position) SegmentDoneBuilder::new(position)
@ -346,7 +349,7 @@ impl GstRc<EventRef> {
QosBuilder::new(type_, proportion, diff, timestamp) QosBuilder::new(type_, proportion, diff, timestamp)
} }
pub fn new_seek<'a, V: Into<::FormatValue>>( pub fn new_seek<'a, V: Into<GenericFormattedValue>>(
rate: f64, rate: f64,
flags: ::SeekFlags, flags: ::SeekFlags,
start_type: ::SeekType, start_type: ::SeekType,
@ -357,7 +360,7 @@ impl GstRc<EventRef> {
assert_initialized_main_thread!(); assert_initialized_main_thread!();
let start = start.into(); let start = start.into();
let stop = stop.into(); let stop = stop.into();
assert_eq!(start.to_format(), stop.to_format()); assert_eq!(start.get_format(), stop.get_format());
SeekBuilder::new(rate, flags, start_type, start, stop_type, stop) SeekBuilder::new(rate, flags, start_type, start, stop_type, stop)
} }
@ -372,7 +375,7 @@ impl GstRc<EventRef> {
LatencyBuilder::new(latency) LatencyBuilder::new(latency)
} }
pub fn new_step<'a, V: Into<::FormatValue>>( pub fn new_step<'a, V: Into<GenericFormattedValue>>(
amount: V, amount: V,
rate: f64, rate: f64,
flush: bool, flush: bool,
@ -597,7 +600,7 @@ impl<'a> Tag<'a> {
pub struct BufferSize<'a>(&'a EventRef); pub struct BufferSize<'a>(&'a EventRef);
impl<'a> BufferSize<'a> { impl<'a> BufferSize<'a> {
pub fn get(&self) -> (::FormatValue, ::FormatValue, bool) { pub fn get(&self) -> (GenericFormattedValue, GenericFormattedValue, bool) {
unsafe { unsafe {
let mut fmt = mem::uninitialized(); let mut fmt = mem::uninitialized();
let mut minsize = mem::uninitialized(); let mut minsize = mem::uninitialized();
@ -612,8 +615,8 @@ impl<'a> BufferSize<'a> {
&mut async, &mut async,
); );
( (
::FormatValue::new(from_glib(fmt), minsize), GenericFormattedValue::new(from_glib(fmt), minsize),
::FormatValue::new(from_glib(fmt), maxsize), GenericFormattedValue::new(from_glib(fmt), maxsize),
from_glib(async), from_glib(async),
) )
} }
@ -687,14 +690,14 @@ impl<'a> Protection<'a> {
pub struct SegmentDone<'a>(&'a EventRef); pub struct SegmentDone<'a>(&'a EventRef);
impl<'a> SegmentDone<'a> { impl<'a> SegmentDone<'a> {
pub fn get(&self) -> ::FormatValue { pub fn get(&self) -> GenericFormattedValue {
unsafe { unsafe {
let mut fmt = mem::uninitialized(); let mut fmt = mem::uninitialized();
let mut position = mem::uninitialized(); let mut position = mem::uninitialized();
ffi::gst_event_parse_segment_done(self.0.as_mut_ptr(), &mut fmt, &mut position); ffi::gst_event_parse_segment_done(self.0.as_mut_ptr(), &mut fmt, &mut position);
::FormatValue::new(from_glib(fmt), position) GenericFormattedValue::new(from_glib(fmt), position)
} }
} }
} }
@ -744,9 +747,9 @@ impl<'a> Seek<'a> {
f64, f64,
::SeekFlags, ::SeekFlags,
::SeekType, ::SeekType,
::FormatValue, GenericFormattedValue,
::SeekType, ::SeekType,
::FormatValue, GenericFormattedValue,
) { ) {
unsafe { unsafe {
let mut rate = mem::uninitialized(); let mut rate = mem::uninitialized();
@ -772,9 +775,9 @@ impl<'a> Seek<'a> {
rate, rate,
from_glib(flags), from_glib(flags),
from_glib(start_type), from_glib(start_type),
::FormatValue::new(from_glib(fmt), start), GenericFormattedValue::new(from_glib(fmt), start),
from_glib(stop_type), from_glib(stop_type),
::FormatValue::new(from_glib(fmt), stop), GenericFormattedValue::new(from_glib(fmt), stop),
) )
} }
} }
@ -797,7 +800,7 @@ impl<'a> Latency<'a> {
pub struct Step<'a>(&'a EventRef); pub struct Step<'a>(&'a EventRef);
impl<'a> Step<'a> { impl<'a> Step<'a> {
pub fn get(&self) -> (::FormatValue, f64, bool, bool) { pub fn get(&self) -> (GenericFormattedValue, f64, bool, bool) {
unsafe { unsafe {
let mut fmt = mem::uninitialized(); let mut fmt = mem::uninitialized();
let mut amount = mem::uninitialized(); let mut amount = mem::uninitialized();
@ -815,7 +818,7 @@ impl<'a> Step<'a> {
); );
( (
::FormatValue::new(from_glib(fmt), amount as i64), GenericFormattedValue::new(from_glib(fmt), amount as i64),
rate, rate,
from_glib(flush), from_glib(flush),
from_glib(intermediate), from_glib(intermediate),
@ -1093,12 +1096,12 @@ pub struct BufferSizeBuilder<'a> {
seqnum: Option<Seqnum>, seqnum: Option<Seqnum>,
running_time_offset: Option<i64>, running_time_offset: Option<i64>,
other_fields: Vec<(&'a str, &'a ToSendValue)>, other_fields: Vec<(&'a str, &'a ToSendValue)>,
minsize: ::FormatValue, minsize: GenericFormattedValue,
maxsize: ::FormatValue, maxsize: GenericFormattedValue,
async: bool, async: bool,
} }
impl<'a> BufferSizeBuilder<'a> { impl<'a> BufferSizeBuilder<'a> {
fn new(minsize: ::FormatValue, maxsize: ::FormatValue, async: bool) -> Self { fn new(minsize: GenericFormattedValue, maxsize: GenericFormattedValue, async: bool) -> Self {
skip_assert_initialized!(); skip_assert_initialized!();
Self { Self {
seqnum: None, seqnum: None,
@ -1112,9 +1115,9 @@ impl<'a> BufferSizeBuilder<'a> {
event_builder_generic_impl!(|s: &Self| { event_builder_generic_impl!(|s: &Self| {
ffi::gst_event_new_buffer_size( ffi::gst_event_new_buffer_size(
s.minsize.to_format().to_glib(), s.minsize.get_format().to_glib(),
s.minsize.to_value(), s.minsize.get_value(),
s.maxsize.to_value(), s.maxsize.get_value(),
s.async.to_glib(), s.async.to_glib(),
) )
}); });
@ -1244,10 +1247,10 @@ pub struct SegmentDoneBuilder<'a> {
seqnum: Option<Seqnum>, seqnum: Option<Seqnum>,
running_time_offset: Option<i64>, running_time_offset: Option<i64>,
other_fields: Vec<(&'a str, &'a ToSendValue)>, other_fields: Vec<(&'a str, &'a ToSendValue)>,
position: ::FormatValue, position: GenericFormattedValue,
} }
impl<'a> SegmentDoneBuilder<'a> { impl<'a> SegmentDoneBuilder<'a> {
fn new(position: ::FormatValue) -> Self { fn new(position: GenericFormattedValue) -> Self {
skip_assert_initialized!(); skip_assert_initialized!();
Self { Self {
seqnum: None, seqnum: None,
@ -1258,7 +1261,7 @@ impl<'a> SegmentDoneBuilder<'a> {
} }
event_builder_generic_impl!(|s: &Self| { event_builder_generic_impl!(|s: &Self| {
ffi::gst_event_new_segment_done(s.position.to_format().to_glib(), s.position.to_value()) ffi::gst_event_new_segment_done(s.position.get_format().to_glib(), s.position.get_value())
}); });
} }
@ -1326,18 +1329,18 @@ pub struct SeekBuilder<'a> {
rate: f64, rate: f64,
flags: ::SeekFlags, flags: ::SeekFlags,
start_type: ::SeekType, start_type: ::SeekType,
start: ::FormatValue, start: GenericFormattedValue,
stop_type: ::SeekType, stop_type: ::SeekType,
stop: ::FormatValue, stop: GenericFormattedValue,
} }
impl<'a> SeekBuilder<'a> { impl<'a> SeekBuilder<'a> {
fn new( fn new(
rate: f64, rate: f64,
flags: ::SeekFlags, flags: ::SeekFlags,
start_type: ::SeekType, start_type: ::SeekType,
start: ::FormatValue, start: GenericFormattedValue,
stop_type: ::SeekType, stop_type: ::SeekType,
stop: ::FormatValue, stop: GenericFormattedValue,
) -> Self { ) -> Self {
skip_assert_initialized!(); skip_assert_initialized!();
Self { Self {
@ -1356,12 +1359,12 @@ impl<'a> SeekBuilder<'a> {
event_builder_generic_impl!(|s: &Self| { event_builder_generic_impl!(|s: &Self| {
ffi::gst_event_new_seek( ffi::gst_event_new_seek(
s.rate, s.rate,
s.start.to_format().to_glib(), s.start.get_format().to_glib(),
s.flags.to_glib(), s.flags.to_glib(),
s.start_type.to_glib(), s.start_type.to_glib(),
s.start.to_value(), s.start.get_value(),
s.stop_type.to_glib(), s.stop_type.to_glib(),
s.stop.to_value(), s.stop.get_value(),
) )
}); });
} }
@ -1416,13 +1419,13 @@ pub struct StepBuilder<'a> {
seqnum: Option<Seqnum>, seqnum: Option<Seqnum>,
running_time_offset: Option<i64>, running_time_offset: Option<i64>,
other_fields: Vec<(&'a str, &'a ToSendValue)>, other_fields: Vec<(&'a str, &'a ToSendValue)>,
amount: ::FormatValue, amount: GenericFormattedValue,
rate: f64, rate: f64,
flush: bool, flush: bool,
intermediate: bool, intermediate: bool,
} }
impl<'a> StepBuilder<'a> { impl<'a> StepBuilder<'a> {
fn new(amount: ::FormatValue, rate: f64, flush: bool, intermediate: bool) -> Self { fn new(amount: GenericFormattedValue, rate: f64, flush: bool, intermediate: bool) -> Self {
skip_assert_initialized!(); skip_assert_initialized!();
Self { Self {
seqnum: None, seqnum: None,
@ -1437,8 +1440,8 @@ impl<'a> StepBuilder<'a> {
event_builder_generic_impl!(|s: &Self| { event_builder_generic_impl!(|s: &Self| {
ffi::gst_event_new_step( ffi::gst_event_new_step(
s.amount.to_format().to_glib(), s.amount.get_format().to_glib(),
s.amount.to_value() as u64, s.amount.get_value() as u64,
s.rate, s.rate,
s.flush.to_glib(), s.flush.to_glib(),
s.intermediate.to_glib(), s.intermediate.to_glib(),

View file

@ -8,162 +8,477 @@
use ClockTime; use ClockTime;
use Format; use Format;
use std::ops;
use muldiv::MulDiv;
#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)] #[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)]
pub enum FormatValue { pub enum GenericFormattedValue {
Undefined(i64), Undefined(i64),
Default(Option<u64>), Default(Default),
Bytes(Option<u64>), Bytes(Bytes),
Time(ClockTime), Time(ClockTime),
Buffers(Option<u64>), Buffers(Buffers),
Percent(Option<u32>), Percent(Option<u32>),
Other(Format, i64), Other(Format, i64),
} }
impl FormatValue { #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)]
pub struct Default(pub Option<u64>);
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)]
pub struct Bytes(pub Option<u64>);
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug, Default)]
pub struct Buffers(pub Option<u64>);
pub type Time = ClockTime;
pub trait FormattedValue: Copy + Clone + Sized + 'static {
fn get_default_format() -> Format;
fn try_from(v: GenericFormattedValue) -> Option<Self>;
fn get_format(&self) -> Format;
unsafe fn from_glib(format: Format, value: i64) -> Self;
unsafe fn to_glib(&self) -> i64;
}
pub trait SpecificFormattedValue: FormattedValue {}
impl FormattedValue for GenericFormattedValue {
fn get_default_format() -> Format {
Format::Undefined
}
fn try_from(v: GenericFormattedValue) -> Option<Self> {
Some(v)
}
fn get_format(&self) -> Format {
self.get_format()
}
unsafe fn from_glib(format: Format, value: i64) -> Self {
GenericFormattedValue::new(format, value)
}
unsafe fn to_glib(&self) -> i64 {
self.get_value()
}
}
impl GenericFormattedValue {
pub fn new(format: Format, value: i64) -> Self { pub fn new(format: Format, value: i64) -> Self {
match format { match format {
Format::Undefined => FormatValue::Undefined(value), Format::Undefined => GenericFormattedValue::Undefined(value),
Format::Default => FormatValue::Default(if value == -1 { Format::Default => GenericFormattedValue::Default(if value == -1 {
None Default(None)
} else { } else {
Some(value as u64) Default(Some(value as u64))
}), }),
Format::Bytes => FormatValue::Bytes(if value == -1 { Format::Bytes => GenericFormattedValue::Bytes(if value == -1 {
None Bytes(None)
} else { } else {
Some(value as u64) Bytes(Some(value as u64))
}), }),
Format::Time => FormatValue::Time(if value == -1 { Format::Time => GenericFormattedValue::Time(if value == -1 {
ClockTime::none() ClockTime::none()
} else { } else {
ClockTime::from(value as u64) ClockTime::from_nseconds(value as u64)
}), }),
Format::Buffers => FormatValue::Buffers(if value == -1 { Format::Buffers => GenericFormattedValue::Buffers(if value == -1 {
None Buffers(None)
} else { } else {
Some(value as u64) Buffers(Some(value as u64))
}), }),
Format::Percent => FormatValue::Percent(if value == -1 { Format::Percent => GenericFormattedValue::Percent(if value == -1 {
None None
} else { } else {
Some(value as u32) Some(value as u32)
}), }),
Format::__Unknown(_) => FormatValue::Other(format, value), Format::__Unknown(_) => GenericFormattedValue::Other(format, value),
} }
} }
pub fn from_undefined(v: i64) -> Self { pub fn from_undefined(v: i64) -> Self {
FormatValue::Undefined(v) GenericFormattedValue::Undefined(v)
} }
pub fn from_default<V: Into<Option<u64>>>(v: V) -> Self { pub fn from_default<V: Into<Default>>(v: V) -> Self {
FormatValue::Default(v.into()) GenericFormattedValue::Default(v.into())
} }
pub fn from_bytes<V: Into<Option<u64>>>(v: V) -> Self { pub fn from_bytes<V: Into<Bytes>>(v: V) -> Self {
FormatValue::Bytes(v.into()) GenericFormattedValue::Bytes(v.into())
} }
pub fn from_time(v: ClockTime) -> Self { pub fn from_time<V: Into<ClockTime>>(v: V) -> Self {
FormatValue::Time(v) GenericFormattedValue::Time(v.into())
} }
pub fn from_buffers<V: Into<Option<u64>>>(v: V) -> Self { pub fn from_buffers<V: Into<Buffers>>(v: V) -> Self {
FormatValue::Buffers(v.into()) GenericFormattedValue::Buffers(v.into())
} }
pub fn from_percent<V: Into<Option<u32>>>(v: V) -> Self { pub fn from_percent<V: Into<Option<u32>>>(v: V) -> Self {
FormatValue::Percent(v.into()) GenericFormattedValue::Percent(v.into())
} }
pub fn from_other(format: Format, v: i64) -> Self { pub fn from_other(format: Format, v: i64) -> Self {
FormatValue::Other(format, v) GenericFormattedValue::Other(format, v)
} }
pub fn to_format(&self) -> Format { pub fn get_format(&self) -> Format {
match *self { match *self {
FormatValue::Undefined(_) => Format::Undefined, GenericFormattedValue::Undefined(_) => Format::Undefined,
FormatValue::Default(_) => Format::Default, GenericFormattedValue::Default(_) => Format::Default,
FormatValue::Bytes(_) => Format::Bytes, GenericFormattedValue::Bytes(_) => Format::Bytes,
FormatValue::Time(_) => Format::Time, GenericFormattedValue::Time(_) => Format::Time,
FormatValue::Buffers(_) => Format::Buffers, GenericFormattedValue::Buffers(_) => Format::Buffers,
FormatValue::Percent(_) => Format::Percent, GenericFormattedValue::Percent(_) => Format::Percent,
FormatValue::Other(f, _) => f, GenericFormattedValue::Other(f, _) => f,
} }
} }
pub fn to_value(&self) -> i64 { pub fn get_value(&self) -> i64 {
match *self { match *self {
FormatValue::Undefined(v) => v, GenericFormattedValue::Undefined(v) => v,
FormatValue::Default(v) => v.map(|v| v as i64).unwrap_or(-1), GenericFormattedValue::Default(v) => v.map(|v| v as i64).unwrap_or(-1),
FormatValue::Bytes(v) => v.map(|v| v as i64).unwrap_or(-1), GenericFormattedValue::Bytes(v) => v.map(|v| v as i64).unwrap_or(-1),
FormatValue::Time(v) => v.map(|v| v as i64).unwrap_or(-1), GenericFormattedValue::Time(v) => v.map(|v| v as i64).unwrap_or(-1),
FormatValue::Buffers(v) => v.map(|v| v as i64).unwrap_or(-1), GenericFormattedValue::Buffers(v) => v.map(|v| v as i64).unwrap_or(-1),
FormatValue::Percent(v) => v.map(|v| v as i64).unwrap_or(-1), GenericFormattedValue::Percent(v) => v.map(|v| v as i64).unwrap_or(-1),
FormatValue::Other(_, v) => v, GenericFormattedValue::Other(_, v) => v,
} }
} }
pub fn try_to_undefined(&self) -> Option<i64> { pub fn try_into<F: FormattedValue>(self) -> Result<F, Self> {
if let FormatValue::Undefined(v) = *self { if F::get_default_format() == self.get_format()
|| F::get_default_format() == Format::Undefined
{
Ok(unsafe { F::from_glib(self.get_format(), self.to_glib()) })
} else {
Err(self)
}
}
pub fn try_into_undefined(self) -> Result<i64, Self> {
if let GenericFormattedValue::Undefined(v) = self {
Ok(v)
} else {
Err(self)
}
}
pub fn try_into_default(self) -> Result<Default, Self> {
if let GenericFormattedValue::Default(v) = self {
Ok(v)
} else {
Err(self)
}
}
pub fn try_into_bytes(self) -> Result<Bytes, Self> {
if let GenericFormattedValue::Bytes(v) = self {
Ok(v)
} else {
Err(self)
}
}
pub fn try_into_time(self) -> Result<ClockTime, Self> {
if let GenericFormattedValue::Time(v) = self {
Ok(v)
} else {
Err(self)
}
}
pub fn try_into_buffers(self) -> Result<Buffers, Self> {
if let GenericFormattedValue::Buffers(v) = self {
Ok(v)
} else {
Err(self)
}
}
pub fn try_into_percent(self) -> Result<Option<u32>, Self> {
if let GenericFormattedValue::Percent(v) = self {
Ok(v)
} else {
Err(self)
}
}
pub fn try_into_other(self) -> Result<(Format, i64), Self> {
if let GenericFormattedValue::Other(f, v) = self {
Ok((f, v))
} else {
Err(self)
}
}
}
macro_rules! impl_op_same(
($name:ident, $op:ident, $op_name:ident, $op_assign:ident, $op_assign_name:ident, $e:expr) => {
impl ops::$op<$name> for $name {
type Output = $name;
fn $op_name(self, other: $name) -> $name {
match (self.0, other.0) {
(Some(a), Some(b)) => $name(Some($e(a, b))),
_ => $name(None),
}
}
}
impl<'a> ops::$op<&'a $name> for $name {
type Output = $name;
fn $op_name(self, other: &'a $name) -> $name {
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 = Some($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(
($name:ident, $op:ident, $op_name:ident, $op_assign:ident, $op_assign_name:ident, $e:expr) => {
impl ops::$op<u64> for $name {
type Output = $name;
fn $op_name(self, other: u64) -> $name {
match self.0 {
Some(a) => $name(Some($e(a, other))),
_ => $name(None),
}
}
}
impl<'a> ops::$op<&'a u64> for $name {
type Output = $name;
fn $op_name(self, other: &'a u64) -> $name {
self.$op_name(*other)
}
}
impl ops::$op_assign<u64> for $name {
fn $op_assign_name(&mut self, other: u64) {
match self.0 {
Some(a) => self.0 = Some($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)
}
}
};
);
macro_rules! impl_format_value_traits(
($name:ident, $format:ident, $format_value:ident) => {
impl From<$name> for GenericFormattedValue {
fn from(v: $name) -> GenericFormattedValue {
GenericFormattedValue::$format_value(v)
}
}
impl FormattedValue for $name {
fn get_default_format() -> Format {
Format::$format
}
fn try_from(v: GenericFormattedValue) -> Option<Self> {
if let GenericFormattedValue::$format_value(v) = v {
Some(v) Some(v)
} else { } else {
None None
} }
} }
pub fn try_to_default(&self) -> Option<Option<u64>> { fn get_format(&self) -> Format {
if let FormatValue::Default(v) = *self { Format::$format
Some(v) }
unsafe fn from_glib(format: Format, value: i64) -> Self {
debug_assert_eq!(format, Format::$format);
if value == -1 {
$name(None)
} else { } else {
None $name(Some(value as u64))
} }
} }
pub fn try_to_bytes(&self) -> Option<Option<u64>> { unsafe fn to_glib(&self) -> i64 {
if let FormatValue::Bytes(v) = *self { self.0.map(|v| v as i64).unwrap_or(-1)
Some(v)
} else {
None
} }
} }
pub fn try_to_time(&self) -> Option<ClockTime> { impl SpecificFormattedValue for $name { }
if let FormatValue::Time(v) = *self {
Some(v) impl From<u64> for $name {
} else { fn from(v: u64) -> $name {
None $name(Some(v))
} }
} }
pub fn try_to_buffers(&self) -> Option<Option<u64>> { impl From<Option<u64>> for $name {
if let FormatValue::Buffers(v) = *self { fn from(v: Option<u64>) -> $name {
Some(v) $name(v)
} else {
None
} }
} }
pub fn try_to_percent(&self) -> Option<Option<u32>> { impl Into<Option<u64>> for $name {
if let FormatValue::Percent(v) = *self { fn into(self) -> Option<u64> {
Some(v) self.0
} else {
None
} }
} }
pub fn try_to_other(&self) -> Option<(Format, i64)> { impl ops::Deref for $name {
if let FormatValue::Other(f, v) = *self { type Target = Option<u64>;
Some((f, v))
} else { fn deref(&self) -> &Option<u64> {
None &self.0
}
}
impl ops::DerefMut for $name {
fn deref_mut(&mut self) -> &mut Option<u64> {
&mut self.0
}
}
impl AsRef<Option<u64>> for $name {
fn as_ref(&self) -> &Option<u64> {
&self.0
}
}
impl AsMut<Option<u64>> for $name {
fn as_mut(&mut self) -> &mut Option<u64> {
&mut self.0
}
}
impl_op_same!($name, Add, add, AddAssign, add_assign, |a, b| a + b);
impl_op_same!($name, Sub, sub, SubAssign, sub_assign, |a, b| a - b);
impl_op_same!($name, Mul, mul, MulAssign, mul_assign, |a, b| a * b);
impl_op_same!($name, Div, div, DivAssign, div_assign, |a, b| a / b);
impl_op_same!($name, Rem, rem, RemAssign, rem_assign, |a, b| a % b);
impl_op_u64!($name, Mul, mul, MulAssign, mul_assign, |a, b| a * b);
impl_op_u64!($name, Div, div, DivAssign, div_assign, |a, b| a / b);
impl_op_u64!($name, Rem, rem, RemAssign, rem_assign, |a, b| a % b);
impl ops::Mul<$name> for u64 {
type Output = $name;
fn mul(self, other: $name) -> $name {
other.mul(self)
}
}
impl<'a> ops::Mul<&'a $name> for u64 {
type Output = $name;
fn mul(self, other: &'a $name) -> $name {
other.mul(self)
}
}
impl MulDiv<$name> for $name {
type Output = $name;
fn mul_div_floor(self, num: $name, denom: $name) -> Option<Self::Output> {
match (self.0, num.0, denom.0) {
(Some(s), Some(n), Some(d)) => s.mul_div_floor(n, d).map(|v| $name(Some(v))),
_ => Some($name(None)),
}
}
fn mul_div_round(self, num: $name, denom: $name) -> Option<Self::Output> {
match (self.0, num.0, denom.0) {
(Some(s), Some(n), Some(d)) => s.mul_div_round(n, d).map(|v| $name(Some(v))),
_ => Some($name(None)),
}
}
fn mul_div_ceil(self, num: $name, denom: $name) -> Option<Self::Output> {
match (self.0, num.0, denom.0) {
(Some(s), Some(n), Some(d)) => s.mul_div_ceil(n, d).map(|v| $name(Some(v))),
_ => Some($name(None)),
} }
} }
} }
impl From<ClockTime> for FormatValue { impl<'a> MulDiv<&'a $name> for $name {
fn from(v: ClockTime) -> FormatValue { type Output = $name;
FormatValue::Time(v)
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_format_value_traits!(Default, Default, Default);
impl_format_value_traits!(Bytes, Bytes, Bytes);
impl_format_value_traits!(ClockTime, Time, Time);
impl_format_value_traits!(Buffers, Buffers, Buffers);

View file

@ -105,7 +105,6 @@ mod device_provider;
mod parse_context; mod parse_context;
mod enums; mod enums;
mod clock_time; mod clock_time;
mod format;
mod date_time; mod date_time;
pub use object::GstObjectExtManual; pub use object::GstObjectExtManual;
pub use element::{ElementExtManual, ElementMessageType, NotifyWatchId}; pub use element::{ElementExtManual, ElementMessageType, NotifyWatchId};
@ -124,7 +123,9 @@ pub use bus::BusStream;
pub use enums::{ClockError, ClockSuccess, FlowError, FlowSuccess, PadLinkError, PadLinkSuccess, pub use enums::{ClockError, ClockSuccess, FlowError, FlowSuccess, PadLinkError, PadLinkSuccess,
StateChangeError, StateChangeSuccess}; StateChangeError, StateChangeSuccess};
pub use clock_time::ClockTime; pub use clock_time::ClockTime;
pub use format::FormatValue;
pub mod format;
pub use format::{FormattedValue, GenericFormattedValue, SpecificFormattedValue};
mod value; mod value;
pub use value::*; pub use value::*;
@ -196,6 +197,8 @@ pub mod prelude {
pub use miniobject::MiniObject; pub use miniobject::MiniObject;
pub use muldiv::MulDiv; pub use muldiv::MulDiv;
pub use format::{FormattedValue, SpecificFormattedValue};
} }
mod utils; mod utils;

View file

@ -14,6 +14,7 @@ use TagList;
use GstObjectExt; use GstObjectExt;
use Seqnum; use Seqnum;
use GroupId; use GroupId;
use GenericFormattedValue;
use std::ptr; use std::ptr;
use std::mem; use std::mem;
@ -156,7 +157,7 @@ impl GstRc<MessageRef> {
StateDirtyBuilder::new() StateDirtyBuilder::new()
} }
pub fn new_step_done<'a, V: Into<::FormatValue>>( pub fn new_step_done<'a, V: Into<GenericFormattedValue>>(
amount: V, amount: V,
rate: f64, rate: f64,
flush: bool, flush: bool,
@ -214,13 +215,17 @@ impl GstRc<MessageRef> {
ElementBuilder::new(structure) ElementBuilder::new(structure)
} }
pub fn new_segment_start<'a, V: Into<::FormatValue>>(position: V) -> SegmentStartBuilder<'a> { pub fn new_segment_start<'a, V: Into<GenericFormattedValue>>(
position: V,
) -> SegmentStartBuilder<'a> {
assert_initialized_main_thread!(); assert_initialized_main_thread!();
let position = position.into(); let position = position.into();
SegmentStartBuilder::new(position) SegmentStartBuilder::new(position)
} }
pub fn new_segment_done<'a, V: Into<::FormatValue>>(position: V) -> SegmentDoneBuilder<'a> { pub fn new_segment_done<'a, V: Into<GenericFormattedValue>>(
position: V,
) -> SegmentDoneBuilder<'a> {
assert_initialized_main_thread!(); assert_initialized_main_thread!();
let position = position.into(); let position = position.into();
SegmentDoneBuilder::new(position) SegmentDoneBuilder::new(position)
@ -251,7 +256,7 @@ impl GstRc<MessageRef> {
RequestStateBuilder::new(state) RequestStateBuilder::new(state)
} }
pub fn new_step_start<'a, V: Into<::FormatValue>>( pub fn new_step_start<'a, V: Into<GenericFormattedValue>>(
active: bool, active: bool,
amount: V, amount: V,
rate: f64, rate: f64,
@ -627,7 +632,16 @@ pub struct StateDirty<'a>(&'a MessageRef);
pub struct StepDone<'a>(&'a MessageRef); pub struct StepDone<'a>(&'a MessageRef);
impl<'a> StepDone<'a> { impl<'a> StepDone<'a> {
pub fn get(&self) -> (::FormatValue, f64, bool, bool, ::FormatValue, bool) { pub fn get(
&self,
) -> (
GenericFormattedValue,
f64,
bool,
bool,
GenericFormattedValue,
bool,
) {
unsafe { unsafe {
let mut format = mem::uninitialized(); let mut format = mem::uninitialized();
let mut amount = mem::uninitialized(); let mut amount = mem::uninitialized();
@ -649,11 +663,11 @@ impl<'a> StepDone<'a> {
); );
( (
::FormatValue::new(from_glib(format), amount as i64), GenericFormattedValue::new(from_glib(format), amount as i64),
rate, rate,
from_glib(flush), from_glib(flush),
from_glib(intermediate), from_glib(intermediate),
::FormatValue::new(from_glib(format), duration as i64), GenericFormattedValue::new(from_glib(format), duration as i64),
from_glib(eos), from_glib(eos),
) )
} }
@ -758,28 +772,28 @@ pub struct Element<'a>(&'a MessageRef);
pub struct SegmentStart<'a>(&'a MessageRef); pub struct SegmentStart<'a>(&'a MessageRef);
impl<'a> SegmentStart<'a> { impl<'a> SegmentStart<'a> {
pub fn get(&self) -> ::FormatValue { pub fn get(&self) -> GenericFormattedValue {
unsafe { unsafe {
let mut format = mem::uninitialized(); let mut format = mem::uninitialized();
let mut position = mem::uninitialized(); let mut position = mem::uninitialized();
ffi::gst_message_parse_segment_start(self.0.as_mut_ptr(), &mut format, &mut position); ffi::gst_message_parse_segment_start(self.0.as_mut_ptr(), &mut format, &mut position);
::FormatValue::new(from_glib(format), position) GenericFormattedValue::new(from_glib(format), position)
} }
} }
} }
pub struct SegmentDone<'a>(&'a MessageRef); pub struct SegmentDone<'a>(&'a MessageRef);
impl<'a> SegmentDone<'a> { impl<'a> SegmentDone<'a> {
pub fn get(&self) -> ::FormatValue { pub fn get(&self) -> GenericFormattedValue {
unsafe { unsafe {
let mut format = mem::uninitialized(); let mut format = mem::uninitialized();
let mut position = mem::uninitialized(); let mut position = mem::uninitialized();
ffi::gst_message_parse_segment_done(self.0.as_mut_ptr(), &mut format, &mut position); ffi::gst_message_parse_segment_done(self.0.as_mut_ptr(), &mut format, &mut position);
::FormatValue::new(from_glib(format), position) GenericFormattedValue::new(from_glib(format), position)
} }
} }
} }
@ -818,7 +832,7 @@ impl<'a> RequestState<'a> {
pub struct StepStart<'a>(&'a MessageRef); pub struct StepStart<'a>(&'a MessageRef);
impl<'a> StepStart<'a> { impl<'a> StepStart<'a> {
pub fn get(&self) -> (bool, ::FormatValue, f64, bool, bool) { pub fn get(&self) -> (bool, GenericFormattedValue, f64, bool, bool) {
unsafe { unsafe {
let mut active = mem::uninitialized(); let mut active = mem::uninitialized();
let mut format = mem::uninitialized(); let mut format = mem::uninitialized();
@ -839,7 +853,7 @@ impl<'a> StepStart<'a> {
( (
from_glib(active), from_glib(active),
::FormatValue::new(from_glib(format), amount as i64), GenericFormattedValue::new(from_glib(format), amount as i64),
rate, rate,
from_glib(flush), from_glib(flush),
from_glib(intermediate), from_glib(intermediate),
@ -894,7 +908,7 @@ impl<'a> Qos<'a> {
} }
} }
pub fn get_stats(&self) -> (::FormatValue, ::FormatValue) { pub fn get_stats(&self) -> (GenericFormattedValue, GenericFormattedValue) {
unsafe { unsafe {
let mut format = mem::uninitialized(); let mut format = mem::uninitialized();
let mut processed = mem::uninitialized(); let mut processed = mem::uninitialized();
@ -908,8 +922,8 @@ impl<'a> Qos<'a> {
); );
( (
::FormatValue::new(from_glib(format), processed as i64), GenericFormattedValue::new(from_glib(format), processed as i64),
::FormatValue::new(from_glib(format), dropped as i64), GenericFormattedValue::new(from_glib(format), dropped as i64),
) )
} }
} }
@ -1554,24 +1568,24 @@ pub struct StepDoneBuilder<'a> {
src: Option<Object>, src: Option<Object>,
seqnum: Option<Seqnum>, seqnum: Option<Seqnum>,
other_fields: Vec<(&'a str, &'a ToSendValue)>, other_fields: Vec<(&'a str, &'a ToSendValue)>,
amount: ::FormatValue, amount: GenericFormattedValue,
rate: f64, rate: f64,
flush: bool, flush: bool,
intermediate: bool, intermediate: bool,
duration: ::FormatValue, duration: GenericFormattedValue,
eos: bool, eos: bool,
} }
impl<'a> StepDoneBuilder<'a> { impl<'a> StepDoneBuilder<'a> {
fn new( fn new(
amount: ::FormatValue, amount: GenericFormattedValue,
rate: f64, rate: f64,
flush: bool, flush: bool,
intermediate: bool, intermediate: bool,
duration: ::FormatValue, duration: GenericFormattedValue,
eos: bool, eos: bool,
) -> Self { ) -> Self {
skip_assert_initialized!(); skip_assert_initialized!();
assert_eq!(amount.to_format(), duration.to_format()); assert_eq!(amount.get_format(), duration.get_format());
Self { Self {
src: None, src: None,
seqnum: None, seqnum: None,
@ -1588,12 +1602,12 @@ impl<'a> StepDoneBuilder<'a> {
message_builder_generic_impl!(|s: &mut Self, src| { message_builder_generic_impl!(|s: &mut Self, src| {
ffi::gst_message_new_step_done( ffi::gst_message_new_step_done(
src, src,
s.amount.to_format().to_glib(), s.amount.get_format().to_glib(),
s.amount.to_value() as u64, s.amount.get_value() as u64,
s.rate, s.rate,
s.flush.to_glib(), s.flush.to_glib(),
s.intermediate.to_glib(), s.intermediate.to_glib(),
s.duration.to_value() as u64, s.duration.get_value() as u64,
s.eos.to_glib(), s.eos.to_glib(),
) )
}); });
@ -1784,10 +1798,10 @@ pub struct SegmentStartBuilder<'a> {
src: Option<Object>, src: Option<Object>,
seqnum: Option<Seqnum>, seqnum: Option<Seqnum>,
other_fields: Vec<(&'a str, &'a ToSendValue)>, other_fields: Vec<(&'a str, &'a ToSendValue)>,
position: ::FormatValue, position: GenericFormattedValue,
} }
impl<'a> SegmentStartBuilder<'a> { impl<'a> SegmentStartBuilder<'a> {
fn new(position: ::FormatValue) -> Self { fn new(position: GenericFormattedValue) -> Self {
skip_assert_initialized!(); skip_assert_initialized!();
Self { Self {
src: None, src: None,
@ -1800,8 +1814,8 @@ impl<'a> SegmentStartBuilder<'a> {
message_builder_generic_impl!(|s: &mut Self, src| { message_builder_generic_impl!(|s: &mut Self, src| {
ffi::gst_message_new_segment_start( ffi::gst_message_new_segment_start(
src, src,
s.position.to_format().to_glib(), s.position.get_format().to_glib(),
s.position.to_value(), s.position.get_value(),
) )
}); });
} }
@ -1810,10 +1824,10 @@ pub struct SegmentDoneBuilder<'a> {
src: Option<Object>, src: Option<Object>,
seqnum: Option<Seqnum>, seqnum: Option<Seqnum>,
other_fields: Vec<(&'a str, &'a ToSendValue)>, other_fields: Vec<(&'a str, &'a ToSendValue)>,
position: ::FormatValue, position: GenericFormattedValue,
} }
impl<'a> SegmentDoneBuilder<'a> { impl<'a> SegmentDoneBuilder<'a> {
fn new(position: ::FormatValue) -> Self { fn new(position: GenericFormattedValue) -> Self {
skip_assert_initialized!(); skip_assert_initialized!();
Self { Self {
src: None, src: None,
@ -1826,8 +1840,8 @@ impl<'a> SegmentDoneBuilder<'a> {
message_builder_generic_impl!(|s: &mut Self, src| { message_builder_generic_impl!(|s: &mut Self, src| {
ffi::gst_message_new_segment_done( ffi::gst_message_new_segment_done(
src, src,
s.position.to_format().to_glib(), s.position.get_format().to_glib(),
s.position.to_value(), s.position.get_value(),
) )
}); });
} }
@ -1935,7 +1949,7 @@ pub struct StepStartBuilder<'a> {
seqnum: Option<Seqnum>, seqnum: Option<Seqnum>,
other_fields: Vec<(&'a str, &'a ToSendValue)>, other_fields: Vec<(&'a str, &'a ToSendValue)>,
active: bool, active: bool,
amount: ::FormatValue, amount: GenericFormattedValue,
rate: f64, rate: f64,
flush: bool, flush: bool,
intermediate: bool, intermediate: bool,
@ -1943,7 +1957,7 @@ pub struct StepStartBuilder<'a> {
impl<'a> StepStartBuilder<'a> { impl<'a> StepStartBuilder<'a> {
fn new( fn new(
active: bool, active: bool,
amount: ::FormatValue, amount: GenericFormattedValue,
rate: f64, rate: f64,
flush: bool, flush: bool,
intermediate: bool, intermediate: bool,
@ -1965,8 +1979,8 @@ impl<'a> StepStartBuilder<'a> {
ffi::gst_message_new_step_start( ffi::gst_message_new_step_start(
src, src,
s.active.to_glib(), s.active.to_glib(),
s.amount.to_format().to_glib(), s.amount.get_format().to_glib(),
s.amount.to_value() as u64, s.amount.get_value() as u64,
s.rate, s.rate,
s.flush.to_glib(), s.flush.to_glib(),
s.intermediate.to_glib(), s.intermediate.to_glib(),
@ -1984,7 +1998,7 @@ pub struct QosBuilder<'a> {
timestamp: ::ClockTime, timestamp: ::ClockTime,
duration: ::ClockTime, duration: ::ClockTime,
values: Option<(i64, f64, i32)>, values: Option<(i64, f64, i32)>,
stats: Option<(::FormatValue, ::FormatValue)>, stats: Option<(GenericFormattedValue, GenericFormattedValue)>,
} }
impl<'a> QosBuilder<'a> { impl<'a> QosBuilder<'a> {
fn new( fn new(
@ -2016,8 +2030,10 @@ impl<'a> QosBuilder<'a> {
} }
} }
pub fn stats(self, processed: ::FormatValue, dropped: ::FormatValue) -> Self { pub fn stats<V: Into<GenericFormattedValue>>(self, processed: V, dropped: V) -> Self {
assert_eq!(processed.to_format(), dropped.to_format()); let processed = processed.into();
let dropped = dropped.into();
assert_eq!(processed.get_format(), dropped.get_format());
Self { Self {
stats: Some((processed, dropped)), stats: Some((processed, dropped)),
..self ..self
@ -2039,9 +2055,9 @@ impl<'a> QosBuilder<'a> {
if let Some((processed, dropped)) = s.stats { if let Some((processed, dropped)) = s.stats {
ffi::gst_message_set_qos_stats( ffi::gst_message_set_qos_stats(
msg, msg,
processed.to_format().to_glib(), processed.get_format().to_glib(),
processed.to_value() as u64, processed.get_value() as u64,
dropped.to_value() as u64, dropped.get_value() as u64,
); );
} }
msg msg

View file

@ -12,6 +12,9 @@ use PadProbeReturn;
use Buffer; use Buffer;
use BufferList; use BufferList;
use Format; use Format;
use GenericFormattedValue;
use FormattedValue;
use SpecificFormattedValue;
use FlowReturn; use FlowReturn;
use Query; use Query;
use QueryRef; use QueryRef;
@ -188,20 +191,37 @@ pub trait PadExtManual {
fn start_task<F: FnMut() + Send + 'static>(&self, func: F) -> Result<(), glib::BoolError>; fn start_task<F: FnMut() + Send + 'static>(&self, func: F) -> Result<(), glib::BoolError>;
fn peer_query_convert<V: Into<::FormatValue>>( fn peer_query_convert<V: Into<GenericFormattedValue>, U: SpecificFormattedValue>(
&self,
src_val: V,
) -> Option<U>;
fn peer_query_convert_generic<V: Into<GenericFormattedValue>>(
&self, &self,
src_val: V, src_val: V,
dest_format: Format, dest_format: Format,
) -> Option<::FormatValue>; ) -> Option<GenericFormattedValue>;
fn peer_query_duration(&self, format: Format) -> Option<::FormatValue>;
fn peer_query_position(&self, format: Format) -> Option<::FormatValue>; fn peer_query_duration<T: SpecificFormattedValue>(&self) -> Option<T>;
fn query_convert<V: Into<::FormatValue>>( fn peer_query_duration_generic(&self, format: Format) -> Option<GenericFormattedValue>;
fn peer_query_position<T: SpecificFormattedValue>(&self) -> Option<T>;
fn peer_query_position_generic(&self, format: Format) -> Option<GenericFormattedValue>;
fn query_convert<V: Into<GenericFormattedValue>, U: SpecificFormattedValue>(
&self,
src_val: V,
) -> Option<U>;
fn query_convert_generic<V: Into<GenericFormattedValue>>(
&self, &self,
src_val: V, src_val: V,
dest_format: Format, dest_format: Format,
) -> Option<::FormatValue>; ) -> Option<GenericFormattedValue>;
fn query_duration(&self, format: Format) -> Option<::FormatValue>;
fn query_position(&self, format: Format) -> Option<::FormatValue>; fn query_duration<T: SpecificFormattedValue>(&self) -> Option<T>;
fn query_duration_generic(&self, format: Format) -> Option<GenericFormattedValue>;
fn query_position<T: SpecificFormattedValue>(&self) -> Option<T>;
fn query_position_generic(&self, format: Format) -> Option<GenericFormattedValue>;
} }
impl<O: IsA<Pad>> PadExtManual for O { impl<O: IsA<Pad>> PadExtManual for O {
@ -611,30 +631,68 @@ impl<O: IsA<Pad>> PadExtManual for O {
} }
} }
fn peer_query_convert<V: Into<::FormatValue>>( fn peer_query_convert<V: Into<GenericFormattedValue>, U: SpecificFormattedValue>(
&self, &self,
src_val: V, src_val: V,
dest_format: Format, ) -> Option<U> {
) -> Option<::FormatValue> {
let src_val = src_val.into(); let src_val = src_val.into();
unsafe { unsafe {
let mut dest_val = mem::uninitialized(); let mut dest_val = mem::uninitialized();
let ret = from_glib(ffi::gst_pad_peer_query_convert( let ret = from_glib(ffi::gst_pad_peer_query_convert(
self.to_glib_none().0, self.to_glib_none().0,
src_val.to_format().to_glib(), src_val.get_format().to_glib(),
src_val.to_value(), src_val.to_glib(),
dest_format.to_glib(), U::get_default_format().to_glib(),
&mut dest_val, &mut dest_val,
)); ));
if ret { if ret {
Some(::FormatValue::new(dest_format, dest_val)) Some(U::from_glib(U::get_default_format(), dest_val))
} else { } else {
None None
} }
} }
} }
fn peer_query_duration(&self, format: Format) -> Option<::FormatValue> { fn peer_query_convert_generic<V: Into<GenericFormattedValue>>(
&self,
src_val: V,
dest_format: Format,
) -> Option<GenericFormattedValue> {
let src_val = src_val.into();
unsafe {
let mut dest_val = mem::uninitialized();
let ret = from_glib(ffi::gst_pad_peer_query_convert(
self.to_glib_none().0,
src_val.get_format().to_glib(),
src_val.to_glib(),
dest_format.to_glib(),
&mut dest_val,
));
if ret {
Some(GenericFormattedValue::new(dest_format, dest_val))
} else {
None
}
}
}
fn peer_query_duration<T: SpecificFormattedValue>(&self) -> Option<T> {
unsafe {
let mut duration = mem::uninitialized();
let ret = from_glib(ffi::gst_pad_peer_query_duration(
self.to_glib_none().0,
T::get_default_format().to_glib(),
&mut duration,
));
if ret {
Some(T::from_glib(T::get_default_format(), duration))
} else {
None
}
}
}
fn peer_query_duration_generic(&self, format: Format) -> Option<GenericFormattedValue> {
unsafe { unsafe {
let mut duration = mem::uninitialized(); let mut duration = mem::uninitialized();
let ret = from_glib(ffi::gst_pad_peer_query_duration( let ret = from_glib(ffi::gst_pad_peer_query_duration(
@ -643,14 +701,30 @@ impl<O: IsA<Pad>> PadExtManual for O {
&mut duration, &mut duration,
)); ));
if ret { if ret {
Some(::FormatValue::new(format, duration)) Some(GenericFormattedValue::new(format, duration))
} else { } else {
None None
} }
} }
} }
fn peer_query_position(&self, format: Format) -> Option<::FormatValue> { fn peer_query_position<T: SpecificFormattedValue>(&self) -> Option<T> {
unsafe {
let mut cur = mem::uninitialized();
let ret = from_glib(ffi::gst_pad_peer_query_position(
self.to_glib_none().0,
T::get_default_format().to_glib(),
&mut cur,
));
if ret {
Some(T::from_glib(T::get_default_format(), cur))
} else {
None
}
}
}
fn peer_query_position_generic(&self, format: Format) -> Option<GenericFormattedValue> {
unsafe { unsafe {
let mut cur = mem::uninitialized(); let mut cur = mem::uninitialized();
let ret = from_glib(ffi::gst_pad_peer_query_position( let ret = from_glib(ffi::gst_pad_peer_query_position(
@ -659,38 +733,77 @@ impl<O: IsA<Pad>> PadExtManual for O {
&mut cur, &mut cur,
)); ));
if ret { if ret {
Some(::FormatValue::new(format, cur)) Some(GenericFormattedValue::new(format, cur))
} else { } else {
None None
} }
} }
} }
fn query_convert<V: Into<::FormatValue>>( fn query_convert<V: Into<GenericFormattedValue>, U: SpecificFormattedValue>(
&self, &self,
src_val: V, src_val: V,
dest_format: Format, ) -> Option<U> {
) -> Option<::FormatValue> {
let src_val = src_val.into(); let src_val = src_val.into();
unsafe { unsafe {
let mut dest_val = mem::uninitialized(); let mut dest_val = mem::uninitialized();
let ret = from_glib(ffi::gst_pad_query_convert( let ret = from_glib(ffi::gst_pad_query_convert(
self.to_glib_none().0, self.to_glib_none().0,
src_val.to_format().to_glib(), src_val.get_format().to_glib(),
src_val.to_value(), src_val.to_glib(),
dest_format.to_glib(), U::get_default_format().to_glib(),
&mut dest_val, &mut dest_val,
)); ));
if ret { if ret {
Some(::FormatValue::new(dest_format, dest_val)) Some(U::from_glib(U::get_default_format(), dest_val))
} else { } else {
None None
} }
} }
} }
fn query_duration(&self, format: Format) -> Option<::FormatValue> { fn query_convert_generic<V: Into<GenericFormattedValue>>(
&self,
src_val: V,
dest_format: Format,
) -> Option<GenericFormattedValue> {
let src_val = src_val.into();
unsafe {
let mut dest_val = mem::uninitialized();
let ret = from_glib(ffi::gst_pad_query_convert(
self.to_glib_none().0,
src_val.get_format().to_glib(),
src_val.get_value(),
dest_format.to_glib(),
&mut dest_val,
));
if ret {
Some(GenericFormattedValue::new(dest_format, dest_val))
} else {
None
}
}
}
fn query_duration<T: SpecificFormattedValue>(&self) -> Option<T> {
unsafe {
let mut duration = mem::uninitialized();
let ret = from_glib(ffi::gst_pad_query_duration(
self.to_glib_none().0,
T::get_default_format().to_glib(),
&mut duration,
));
if ret {
Some(T::from_glib(T::get_default_format(), duration))
} else {
None
}
}
}
fn query_duration_generic(&self, format: Format) -> Option<GenericFormattedValue> {
unsafe { unsafe {
let mut duration = mem::uninitialized(); let mut duration = mem::uninitialized();
let ret = from_glib(ffi::gst_pad_query_duration( let ret = from_glib(ffi::gst_pad_query_duration(
@ -699,14 +812,30 @@ impl<O: IsA<Pad>> PadExtManual for O {
&mut duration, &mut duration,
)); ));
if ret { if ret {
Some(::FormatValue::new(format, duration)) Some(GenericFormattedValue::new(format, duration))
} else { } else {
None None
} }
} }
} }
fn query_position(&self, format: Format) -> Option<::FormatValue> { fn query_position<T: SpecificFormattedValue>(&self) -> Option<T> {
unsafe {
let mut cur = mem::uninitialized();
let ret = from_glib(ffi::gst_pad_query_position(
self.to_glib_none().0,
T::get_default_format().to_glib(),
&mut cur,
));
if ret {
Some(T::from_glib(T::get_default_format(), cur))
} else {
None
}
}
}
fn query_position_generic(&self, format: Format) -> Option<GenericFormattedValue> {
unsafe { unsafe {
let mut cur = mem::uninitialized(); let mut cur = mem::uninitialized();
let ret = from_glib(ffi::gst_pad_query_position( let ret = from_glib(ffi::gst_pad_query_position(
@ -715,7 +844,7 @@ impl<O: IsA<Pad>> PadExtManual for O {
&mut cur, &mut cur,
)); ));
if ret { if ret {
Some(::FormatValue::new(format, cur)) Some(GenericFormattedValue::new(format, cur))
} else { } else {
None None
} }
@ -1065,9 +1194,10 @@ mod tests {
pad.set_active(true).unwrap(); pad.set_active(true).unwrap();
assert!(pad.send_event(::Event::new_stream_start("test").build())); assert!(pad.send_event(::Event::new_stream_start("test").build()));
let mut segment = ::Segment::default(); let segment = ::FormattedSegment::<::ClockTime>::new();
segment.init(::Format::Time); assert!(pad.send_event(
assert!(pad.send_event(::Event::new_segment(&segment).build())); ::Event::new_segment(segment.as_ref()).build()
));
assert_eq!(pad.chain(::Buffer::new()), ::FlowReturn::Ok); assert_eq!(pad.chain(::Buffer::new()), ::FlowReturn::Ok);

View file

@ -9,6 +9,7 @@
use ffi; use ffi;
use miniobject::*; use miniobject::*;
use structure::*; use structure::*;
use GenericFormattedValue;
use std::ptr; use std::ptr;
use std::mem; use std::mem;
@ -57,12 +58,13 @@ impl GstRc<QueryRef> {
unsafe { from_glib_full(ffi::gst_query_new_segment(fmt.to_glib())) } unsafe { from_glib_full(ffi::gst_query_new_segment(fmt.to_glib())) }
} }
pub fn new_convert(value: ::FormatValue, dest_fmt: ::Format) -> Self { pub fn new_convert<V: Into<GenericFormattedValue>>(value: V, dest_fmt: ::Format) -> Self {
assert_initialized_main_thread!(); assert_initialized_main_thread!();
let value = value.into();
unsafe { unsafe {
from_glib_full(ffi::gst_query_new_convert( from_glib_full(ffi::gst_query_new_convert(
value.to_format().to_glib(), value.get_format().to_glib(),
value.to_value(), value.get_value(),
dest_fmt.to_glib(), dest_fmt.to_glib(),
)) ))
} }
@ -235,14 +237,14 @@ pub enum QueryView<T> {
pub struct Position<T>(T); pub struct Position<T>(T);
impl<'a> Position<&'a QueryRef> { impl<'a> Position<&'a QueryRef> {
pub fn get_result(&self) -> ::FormatValue { pub fn get_result(&self) -> GenericFormattedValue {
unsafe { unsafe {
let mut fmt = mem::uninitialized(); let mut fmt = mem::uninitialized();
let mut pos = mem::uninitialized(); let mut pos = mem::uninitialized();
ffi::gst_query_parse_position(self.0.as_mut_ptr(), &mut fmt, &mut pos); ffi::gst_query_parse_position(self.0.as_mut_ptr(), &mut fmt, &mut pos);
::FormatValue::new(from_glib(fmt), pos) GenericFormattedValue::new(from_glib(fmt), pos)
} }
} }
@ -262,14 +264,14 @@ impl<'a> Position<&'a QueryRef> {
} }
impl<'a> Position<&'a mut QueryRef> { impl<'a> Position<&'a mut QueryRef> {
pub fn set<V: Into<::FormatValue>>(&mut self, pos: V) { pub fn set<V: Into<GenericFormattedValue>>(&mut self, pos: V) {
let pos = pos.into(); let pos = pos.into();
assert_eq!(pos.to_format(), self.get_format()); assert_eq!(pos.get_format(), self.get_format());
unsafe { unsafe {
ffi::gst_query_set_position( ffi::gst_query_set_position(
self.0.as_mut_ptr(), self.0.as_mut_ptr(),
pos.to_format().to_glib(), pos.get_format().to_glib(),
pos.to_value(), pos.get_value(),
); );
} }
} }
@ -281,14 +283,14 @@ impl<'a> Position<&'a mut QueryRef> {
pub struct Duration<T>(T); pub struct Duration<T>(T);
impl<'a> Duration<&'a QueryRef> { impl<'a> Duration<&'a QueryRef> {
pub fn get_result(&self) -> ::FormatValue { pub fn get_result(&self) -> GenericFormattedValue {
unsafe { unsafe {
let mut fmt = mem::uninitialized(); let mut fmt = mem::uninitialized();
let mut pos = mem::uninitialized(); let mut pos = mem::uninitialized();
ffi::gst_query_parse_duration(self.0.as_mut_ptr(), &mut fmt, &mut pos); ffi::gst_query_parse_duration(self.0.as_mut_ptr(), &mut fmt, &mut pos);
::FormatValue::new(from_glib(fmt), pos) GenericFormattedValue::new(from_glib(fmt), pos)
} }
} }
@ -308,14 +310,14 @@ impl<'a> Duration<&'a QueryRef> {
} }
impl<'a> Duration<&'a mut QueryRef> { impl<'a> Duration<&'a mut QueryRef> {
pub fn set<V: Into<::FormatValue>>(&mut self, dur: V) { pub fn set<V: Into<GenericFormattedValue>>(&mut self, dur: V) {
let dur = dur.into(); let dur = dur.into();
assert_eq!(dur.to_format(), self.get_format()); assert_eq!(dur.get_format(), self.get_format());
unsafe { unsafe {
ffi::gst_query_set_duration( ffi::gst_query_set_duration(
self.0.as_mut_ptr(), self.0.as_mut_ptr(),
dur.to_format().to_glib(), dur.get_format().to_glib(),
dur.to_value(), dur.get_value(),
); );
} }
} }
@ -389,7 +391,7 @@ impl<'a> Rate<&'a mut QueryRef> {
pub struct Seeking<T>(T); pub struct Seeking<T>(T);
impl<'a> Seeking<&'a QueryRef> { impl<'a> Seeking<&'a QueryRef> {
pub fn get_result(&self) -> (bool, ::FormatValue, ::FormatValue) { pub fn get_result(&self) -> (bool, GenericFormattedValue, GenericFormattedValue) {
unsafe { unsafe {
let mut fmt = mem::uninitialized(); let mut fmt = mem::uninitialized();
let mut seekable = mem::uninitialized(); let mut seekable = mem::uninitialized();
@ -405,8 +407,8 @@ impl<'a> Seeking<&'a QueryRef> {
( (
from_glib(seekable), from_glib(seekable),
::FormatValue::new(from_glib(fmt), start), GenericFormattedValue::new(from_glib(fmt), start),
::FormatValue::new(from_glib(fmt), end), GenericFormattedValue::new(from_glib(fmt), end),
) )
} }
} }
@ -432,20 +434,20 @@ impl<'a> Seeking<&'a QueryRef> {
} }
impl<'a> Seeking<&'a mut QueryRef> { impl<'a> Seeking<&'a mut QueryRef> {
pub fn set<V: Into<::FormatValue>>(&mut self, seekable: bool, start: V, end: V) { pub fn set<V: Into<GenericFormattedValue>>(&mut self, seekable: bool, start: V, end: V) {
let start = start.into(); let start = start.into();
let end = end.into(); let end = end.into();
assert_eq!(self.get_format(), start.to_format()); assert_eq!(self.get_format(), start.get_format());
assert_eq!(start.to_format(), end.to_format()); assert_eq!(start.get_format(), end.get_format());
unsafe { unsafe {
ffi::gst_query_set_seeking( ffi::gst_query_set_seeking(
self.0.as_mut_ptr(), self.0.as_mut_ptr(),
start.to_format().to_glib(), start.get_format().to_glib(),
seekable.to_glib(), seekable.to_glib(),
start.to_value(), start.get_value(),
end.to_value(), end.get_value(),
); );
} }
} }
@ -457,7 +459,7 @@ impl<'a> Seeking<&'a mut QueryRef> {
pub struct Segment<T>(T); pub struct Segment<T>(T);
impl<'a> Segment<&'a QueryRef> { impl<'a> Segment<&'a QueryRef> {
pub fn get_result(&self) -> (f64, ::FormatValue, ::FormatValue) { pub fn get_result(&self) -> (f64, GenericFormattedValue, GenericFormattedValue) {
unsafe { unsafe {
let mut rate = mem::uninitialized(); let mut rate = mem::uninitialized();
let mut fmt = mem::uninitialized(); let mut fmt = mem::uninitialized();
@ -473,8 +475,8 @@ impl<'a> Segment<&'a QueryRef> {
); );
( (
rate, rate,
::FormatValue::new(from_glib(fmt), start), GenericFormattedValue::new(from_glib(fmt), start),
::FormatValue::new(from_glib(fmt), stop), GenericFormattedValue::new(from_glib(fmt), stop),
) )
} }
} }
@ -500,19 +502,19 @@ impl<'a> Segment<&'a QueryRef> {
} }
impl<'a> Segment<&'a mut QueryRef> { impl<'a> Segment<&'a mut QueryRef> {
pub fn set<V: Into<::FormatValue>>(&mut self, rate: f64, start: V, stop: V) { pub fn set<V: Into<GenericFormattedValue>>(&mut self, rate: f64, start: V, stop: V) {
let start = start.into(); let start = start.into();
let stop = stop.into(); let stop = stop.into();
assert_eq!(start.to_format(), stop.to_format()); assert_eq!(start.get_format(), stop.get_format());
unsafe { unsafe {
ffi::gst_query_set_segment( ffi::gst_query_set_segment(
self.0.as_mut_ptr(), self.0.as_mut_ptr(),
rate, rate,
start.to_format().to_glib(), start.get_format().to_glib(),
start.to_value(), start.get_value(),
stop.to_value(), stop.get_value(),
); );
} }
} }
@ -524,7 +526,7 @@ impl<'a> Segment<&'a mut QueryRef> {
pub struct Convert<T>(T); pub struct Convert<T>(T);
impl<'a> Convert<&'a QueryRef> { impl<'a> Convert<&'a QueryRef> {
pub fn get_result(&self) -> (::FormatValue, ::FormatValue) { pub fn get_result(&self) -> (GenericFormattedValue, GenericFormattedValue) {
unsafe { unsafe {
let mut src_fmt = mem::uninitialized(); let mut src_fmt = mem::uninitialized();
let mut src = mem::uninitialized(); let mut src = mem::uninitialized();
@ -539,13 +541,13 @@ impl<'a> Convert<&'a QueryRef> {
&mut dest, &mut dest,
); );
( (
::FormatValue::new(from_glib(src_fmt), src), GenericFormattedValue::new(from_glib(src_fmt), src),
::FormatValue::new(from_glib(dest_fmt), dest), GenericFormattedValue::new(from_glib(dest_fmt), dest),
) )
} }
} }
pub fn get(&self) -> (::FormatValue, ::Format) { pub fn get(&self) -> (GenericFormattedValue, ::Format) {
unsafe { unsafe {
let mut src_fmt = mem::uninitialized(); let mut src_fmt = mem::uninitialized();
let mut src = mem::uninitialized(); let mut src = mem::uninitialized();
@ -559,7 +561,7 @@ impl<'a> Convert<&'a QueryRef> {
ptr::null_mut(), ptr::null_mut(),
); );
( (
::FormatValue::new(from_glib(src_fmt), src), GenericFormattedValue::new(from_glib(src_fmt), src),
from_glib(dest_fmt), from_glib(dest_fmt),
) )
} }
@ -571,17 +573,17 @@ impl<'a> Convert<&'a QueryRef> {
} }
impl<'a> Convert<&'a mut QueryRef> { impl<'a> Convert<&'a mut QueryRef> {
pub fn set<V: Into<::FormatValue>>(&mut self, src: V, dest: V) { pub fn set<V: Into<GenericFormattedValue>>(&mut self, src: V, dest: V) {
let src = src.into(); let src = src.into();
let dest = dest.into(); let dest = dest.into();
unsafe { unsafe {
ffi::gst_query_set_convert( ffi::gst_query_set_convert(
self.0.as_mut_ptr(), self.0.as_mut_ptr(),
src.to_format().to_glib(), src.get_format().to_glib(),
src.to_value(), src.get_value(),
dest.to_format().to_glib(), dest.get_format().to_glib(),
dest.to_value(), dest.get_value(),
); );
} }
} }
@ -656,7 +658,7 @@ impl<'a> Buffering<&'a QueryRef> {
} }
} }
pub fn get_range(&self) -> (::FormatValue, ::FormatValue, i64) { pub fn get_range(&self) -> (GenericFormattedValue, GenericFormattedValue, i64) {
unsafe { unsafe {
let mut fmt = mem::uninitialized(); let mut fmt = mem::uninitialized();
let mut start = mem::uninitialized(); let mut start = mem::uninitialized();
@ -671,8 +673,8 @@ impl<'a> Buffering<&'a QueryRef> {
&mut estimated_total, &mut estimated_total,
); );
( (
::FormatValue::new(from_glib(fmt), start), GenericFormattedValue::new(from_glib(fmt), start),
::FormatValue::new(from_glib(fmt), stop), GenericFormattedValue::new(from_glib(fmt), stop),
estimated_total, estimated_total,
) )
} }
@ -697,7 +699,7 @@ impl<'a> Buffering<&'a QueryRef> {
} }
} }
pub fn get_ranges(&self) -> Vec<(::FormatValue, ::FormatValue)> { pub fn get_ranges(&self) -> Vec<(GenericFormattedValue, GenericFormattedValue)> {
unsafe { unsafe {
let mut fmt = mem::uninitialized(); let mut fmt = mem::uninitialized();
ffi::gst_query_parse_buffering_range( ffi::gst_query_parse_buffering_range(
@ -722,8 +724,8 @@ impl<'a> Buffering<&'a QueryRef> {
)); ));
if s { if s {
res.push(( res.push((
::FormatValue::new(fmt, start), GenericFormattedValue::new(fmt, start),
::FormatValue::new(fmt, stop), GenericFormattedValue::new(fmt, stop),
)); ));
} }
} }
@ -744,19 +746,24 @@ impl<'a> Buffering<&'a mut QueryRef> {
} }
} }
pub fn set_range<V: Into<::FormatValue>>(&mut self, start: V, stop: V, estimated_total: i64) { pub fn set_range<V: Into<GenericFormattedValue>>(
&mut self,
start: V,
stop: V,
estimated_total: i64,
) {
let start = start.into(); let start = start.into();
let stop = stop.into(); let stop = stop.into();
assert_eq!(self.get_format(), start.to_format()); assert_eq!(self.get_format(), start.get_format());
assert_eq!(start.to_format(), stop.to_format()); assert_eq!(start.get_format(), stop.get_format());
unsafe { unsafe {
ffi::gst_query_set_buffering_range( ffi::gst_query_set_buffering_range(
self.0.as_mut_ptr(), self.0.as_mut_ptr(),
start.to_format().to_glib(), start.get_format().to_glib(),
start.to_value(), start.get_value(),
stop.to_value(), stop.get_value(),
estimated_total, estimated_total,
); );
} }
@ -781,19 +788,22 @@ impl<'a> Buffering<&'a mut QueryRef> {
} }
} }
pub fn add_buffering_ranges<V: Into<::FormatValue> + Copy>(&mut self, ranges: &[(V, V)]) { pub fn add_buffering_ranges<V: Into<GenericFormattedValue> + Copy>(
&mut self,
ranges: &[(V, V)],
) {
unsafe { unsafe {
let fmt = self.get_format(); let fmt = self.get_format();
for &(start, stop) in ranges { for &(start, stop) in ranges {
let start = start.into(); let start = start.into();
let stop = stop.into(); let stop = stop.into();
assert_eq!(start.to_format(), fmt); assert_eq!(start.get_format(), fmt);
assert_eq!(stop.to_format(), fmt); assert_eq!(stop.get_format(), fmt);
ffi::gst_query_add_buffering_range( ffi::gst_query_add_buffering_range(
self.0.as_mut_ptr(), self.0.as_mut_ptr(),
start.to_value(), start.get_value(),
stop.to_value(), stop.get_value(),
); );
} }
} }
@ -1159,7 +1169,7 @@ mod tests {
match q.get_mut().unwrap().view_mut() { match q.get_mut().unwrap().view_mut() {
QueryView::Position(ref mut p) => { QueryView::Position(ref mut p) => {
let pos = p.get_result(); let pos = p.get_result();
assert_eq!(pos.try_to_time(), Some(::CLOCK_TIME_NONE)); assert_eq!(pos.try_into_time(), Ok(::CLOCK_TIME_NONE));
p.set(2 * ::SECOND); p.set(2 * ::SECOND);
} }
_ => (), _ => (),
@ -1168,7 +1178,7 @@ mod tests {
match q.view() { match q.view() {
QueryView::Position(ref p) => { QueryView::Position(ref p) => {
let pos = p.get_result(); let pos = p.get_result();
assert_eq!(pos.try_to_time(), Some(2 * ::SECOND)); assert_eq!(pos.try_into_time(), Ok(2 * ::SECOND));
} }
_ => (), _ => (),
} }

View file

@ -18,7 +18,9 @@ use miniobject::*;
use Buffer; use Buffer;
use BufferList; use BufferList;
use Caps; use Caps;
use FormattedValue;
use Segment; use Segment;
use FormattedSegment;
use StructureRef; use StructureRef;
pub type Sample = GstRc<SampleRef>; pub type Sample = GstRc<SampleRef>;
@ -29,10 +31,10 @@ unsafe impl MiniObject for SampleRef {
} }
impl GstRc<SampleRef> { impl GstRc<SampleRef> {
pub fn new( pub fn new<F: FormattedValue>(
buffer: Option<&Buffer>, buffer: Option<&Buffer>,
caps: Option<&Caps>, caps: Option<&Caps>,
segment: Option<&Segment>, segment: Option<&FormattedSegment<F>>,
info: Option<&StructureRef>, info: Option<&StructureRef>,
) -> Self { ) -> Self {
assert_initialized_main_thread!(); assert_initialized_main_thread!();

View file

@ -7,7 +7,8 @@
// except according to those terms. // except according to those terms.
use Format; use Format;
use FormatValue; use GenericFormattedValue;
use FormattedValue;
use SeekFlags; use SeekFlags;
use SeekType; use SeekType;
use ffi; use ffi;
@ -18,39 +19,102 @@ use glib;
use std::mem; use std::mem;
use std::ptr; use std::ptr;
use std::fmt; use std::fmt;
use std::marker::PhantomData;
pub struct Segment(ffi::GstSegment); pub type Segment = FormattedSegment<GenericFormattedValue>;
pub struct FormattedSegment<T: FormattedValue>(ffi::GstSegment, PhantomData<T>);
impl Segment { impl Segment {
pub fn new() -> Segment { pub fn reset_with_format(&mut self, format: Format) {
assert_initialized_main_thread!(); unsafe {
unsafe { Self::uninitialized() } ffi::gst_segment_init(self.to_glib_none_mut().0, format.to_glib());
}
} }
pub fn clip<V: Into<FormatValue>>( pub fn set_format(&mut self, format: Format) {
&self, self.0.format = format.to_glib();
start: V, }
stop: V,
) -> Option<(FormatValue, FormatValue)> { pub fn downcast<T: FormattedValue>(self) -> Result<FormattedSegment<T>, Self> {
if T::get_default_format() == Format::Undefined
|| T::get_default_format() == self.get_format()
{
Ok(FormattedSegment(self.0, PhantomData))
} else {
Err(self)
}
}
pub fn downcast_ref<T: FormattedValue>(&self) -> Option<&FormattedSegment<T>> {
if T::get_default_format() == Format::Undefined
|| T::get_default_format() == self.get_format()
{
Some(unsafe { mem::transmute(self) })
} else {
None
}
}
pub fn downcast_mut<T: FormattedValue>(&mut self) -> Option<&mut FormattedSegment<T>> {
if T::get_default_format() == Format::Undefined
|| T::get_default_format() == self.get_format()
{
Some(unsafe { mem::transmute(self) })
} else {
None
}
}
}
impl<T: FormattedValue> FormattedSegment<T> {
pub fn new() -> Self {
assert_initialized_main_thread!();
let segment = unsafe {
let mut segment = mem::zeroed();
ffi::gst_segment_init(&mut segment, T::get_default_format().to_glib());
segment
};
FormattedSegment(segment, PhantomData)
}
pub fn upcast(self) -> Segment {
FormattedSegment(self.0, PhantomData)
}
pub fn upcast_ref(&self) -> &Segment {
unsafe { mem::transmute(self) }
}
pub fn reset(&mut self) {
unsafe {
ffi::gst_segment_init(&mut self.0, T::get_default_format().to_glib());
}
}
pub fn clip<V: Into<T>>(&self, start: V, stop: V) -> Option<(T, T)> {
let start = start.into(); let start = start.into();
let stop = stop.into(); let stop = stop.into();
assert_eq!(self.get_format(), start.to_format());
assert_eq!(start.to_format(), stop.to_format()); if T::get_default_format() == Format::Undefined {
assert_eq!(self.get_format(), start.get_format());
assert_eq!(self.get_format(), stop.get_format());
}
unsafe { unsafe {
let mut clip_start = mem::uninitialized(); let mut clip_start = mem::uninitialized();
let mut clip_stop = mem::uninitialized(); let mut clip_stop = mem::uninitialized();
let ret = from_glib(ffi::gst_segment_clip( let ret = from_glib(ffi::gst_segment_clip(
self.to_glib_none().0, &self.0,
start.to_format().to_glib(), start.get_format().to_glib(),
start.to_value() as u64, start.to_glib() as u64,
stop.to_value() as u64, stop.to_glib() as u64,
&mut clip_start, &mut clip_start,
&mut clip_stop, &mut clip_stop,
)); ));
if ret { if ret {
Some(( Some((
FormatValue::new(self.get_format(), clip_start as i64), T::from_glib(self.get_format(), clip_start as i64),
FormatValue::new(self.get_format(), clip_stop as i64), T::from_glib(self.get_format(), clip_stop as i64),
)) ))
} else { } else {
None None
@ -58,14 +122,8 @@ impl Segment {
} }
} }
pub fn copy_into(&self, dest: &mut Segment) {
unsafe {
ffi::gst_segment_copy_into(self.to_glib_none().0, dest.to_glib_none_mut().0);
}
}
#[cfg_attr(feature = "cargo-clippy", allow(too_many_arguments))] #[cfg_attr(feature = "cargo-clippy", allow(too_many_arguments))]
pub fn do_seek<V: Into<FormatValue>>( pub fn do_seek<V: Into<T>>(
&mut self, &mut self,
rate: f64, rate: f64,
flags: SeekFlags, flags: SeekFlags,
@ -77,19 +135,23 @@ impl Segment {
skip_assert_initialized!(); skip_assert_initialized!();
let start = start.into(); let start = start.into();
let stop = stop.into(); let stop = stop.into();
assert_eq!(self.get_format(), start.to_format());
assert_eq!(start.to_format(), stop.to_format()); if T::get_default_format() == Format::Undefined {
assert_eq!(self.get_format(), start.get_format());
assert_eq!(self.get_format(), stop.get_format());
}
unsafe { unsafe {
let mut update = mem::uninitialized(); let mut update = mem::uninitialized();
let ret = from_glib(ffi::gst_segment_do_seek( let ret = from_glib(ffi::gst_segment_do_seek(
self.to_glib_none_mut().0, &mut self.0,
rate, rate,
self.get_format().to_glib(), self.get_format().to_glib(),
flags.to_glib(), flags.to_glib(),
start_type.to_glib(), start_type.to_glib(),
start.to_value() as u64, start.to_glib() as u64,
stop_type.to_glib(), stop_type.to_glib(),
stop.to_value() as u64, stop.to_glib() as u64,
&mut update, &mut update,
)); ));
if ret { if ret {
@ -100,184 +162,200 @@ impl Segment {
} }
} }
pub fn init(&mut self, format: Format) { pub fn offset_running_time(&mut self, offset: i64) -> bool {
unsafe {
ffi::gst_segment_init(self.to_glib_none_mut().0, format.to_glib());
}
}
fn is_equal(&self, s1: &Segment) -> bool {
unsafe {
from_glib(ffi::gst_segment_is_equal(
self.to_glib_none().0,
s1.to_glib_none().0,
))
}
}
pub fn offset_running_time(&mut self, format: Format, offset: i64) -> bool {
unsafe { unsafe {
from_glib(ffi::gst_segment_offset_running_time( from_glib(ffi::gst_segment_offset_running_time(
self.to_glib_none_mut().0, &mut self.0,
format.to_glib(), self.get_format().to_glib(),
offset, offset,
)) ))
} }
} }
pub fn position_from_running_time<V: Into<FormatValue>>(&self, running_time: V) -> FormatValue { pub fn position_from_running_time<V: Into<T>>(&self, running_time: V) -> T {
let running_time = running_time.into(); let running_time = running_time.into();
assert_eq!(self.get_format(), running_time.to_format());
if T::get_default_format() == Format::Undefined {
assert_eq!(self.get_format(), running_time.get_format());
}
unsafe { unsafe {
FormatValue::new( T::from_glib(
self.get_format(), self.get_format(),
ffi::gst_segment_position_from_running_time( ffi::gst_segment_position_from_running_time(
self.to_glib_none().0, &self.0,
self.get_format().to_glib(), self.get_format().to_glib(),
running_time.to_value() as u64, running_time.to_glib() as u64,
) as i64, ) as i64,
) )
} }
} }
pub fn position_from_running_time_full<V: Into<FormatValue>>( pub fn position_from_running_time_full<V: Into<T>>(&self, running_time: V) -> (i32, T) {
&self,
running_time: V,
) -> (i32, FormatValue) {
let running_time = running_time.into(); let running_time = running_time.into();
assert_eq!(self.get_format(), running_time.to_format());
if T::get_default_format() == Format::Undefined {
assert_eq!(self.get_format(), running_time.get_format());
}
unsafe { unsafe {
let mut position = mem::uninitialized(); let mut position = mem::uninitialized();
let ret = ffi::gst_segment_position_from_running_time_full( let ret = ffi::gst_segment_position_from_running_time_full(
self.to_glib_none().0, &self.0,
self.get_format().to_glib(), self.get_format().to_glib(),
running_time.to_value() as u64, running_time.to_glib() as u64,
&mut position, &mut position,
); );
(ret, FormatValue::new(self.get_format(), position as i64)) (ret, T::from_glib(self.get_format(), position as i64))
} }
} }
pub fn position_from_stream_time<V: Into<FormatValue>>(&self, stream_time: V) -> FormatValue { pub fn position_from_stream_time<V: Into<T>>(&self, stream_time: V) -> T {
let stream_time = stream_time.into(); let stream_time = stream_time.into();
assert_eq!(self.get_format(), stream_time.to_format());
if T::get_default_format() == Format::Undefined {
assert_eq!(self.get_format(), stream_time.get_format());
}
unsafe { unsafe {
FormatValue::new( T::from_glib(
self.get_format(), self.get_format(),
ffi::gst_segment_position_from_stream_time( ffi::gst_segment_position_from_stream_time(
self.to_glib_none().0, &self.0,
self.get_format().to_glib(), self.get_format().to_glib(),
stream_time.to_value() as u64, stream_time.to_glib() as u64,
) as i64, ) as i64,
) )
} }
} }
pub fn position_from_stream_time_full<V: Into<FormatValue>>( pub fn position_from_stream_time_full<V: Into<T>>(&self, stream_time: V) -> (i32, T) {
&self,
stream_time: V,
) -> (i32, FormatValue) {
let stream_time = stream_time.into(); let stream_time = stream_time.into();
assert_eq!(self.get_format(), stream_time.to_format());
if T::get_default_format() == Format::Undefined {
assert_eq!(self.get_format(), stream_time.get_format());
}
unsafe { unsafe {
let mut position = mem::uninitialized(); let mut position = mem::uninitialized();
let ret = ffi::gst_segment_position_from_stream_time_full( let ret = ffi::gst_segment_position_from_stream_time_full(
self.to_glib_none().0, &self.0,
self.get_format().to_glib(), self.get_format().to_glib(),
stream_time.to_value() as u64, stream_time.to_glib() as u64,
&mut position, &mut position,
); );
(ret, FormatValue::new(self.get_format(), position as i64)) (ret, T::from_glib(self.get_format(), position as i64))
} }
} }
pub fn set_running_time<V: Into<FormatValue>>(&mut self, running_time: V) -> bool { pub fn set_running_time<V: Into<T>>(&mut self, running_time: V) -> bool {
let running_time = running_time.into(); let running_time = running_time.into();
assert_eq!(self.get_format(), running_time.to_format());
if T::get_default_format() == Format::Undefined {
assert_eq!(self.get_format(), running_time.get_format());
}
unsafe { unsafe {
from_glib(ffi::gst_segment_set_running_time( from_glib(ffi::gst_segment_set_running_time(
self.to_glib_none_mut().0, &mut self.0,
self.get_format().to_glib(), self.get_format().to_glib(),
running_time.to_value() as u64, running_time.to_glib() as u64,
)) ))
} }
} }
pub fn to_position<V: Into<FormatValue>>(&self, running_time: V) -> FormatValue { pub fn to_position<V: Into<T>>(&self, running_time: V) -> T {
let running_time = running_time.into(); let running_time = running_time.into();
assert_eq!(self.get_format(), running_time.to_format());
if T::get_default_format() == Format::Undefined {
assert_eq!(self.get_format(), running_time.get_format());
}
unsafe { unsafe {
FormatValue::new( T::from_glib(
self.get_format(), self.get_format(),
ffi::gst_segment_to_position( ffi::gst_segment_to_position(
self.to_glib_none().0, &self.0,
self.get_format().to_glib(), self.get_format().to_glib(),
running_time.to_value() as u64, running_time.to_glib() as u64,
) as i64, ) as i64,
) )
} }
} }
pub fn to_running_time<V: Into<FormatValue>>(&self, position: V) -> FormatValue { pub fn to_running_time<V: Into<T>>(&self, position: V) -> T {
let position = position.into(); let position = position.into();
assert_eq!(self.get_format(), position.to_format());
if T::get_default_format() == Format::Undefined {
assert_eq!(self.get_format(), position.get_format());
}
unsafe { unsafe {
FormatValue::new( T::from_glib(
self.get_format(), self.get_format(),
ffi::gst_segment_to_running_time( ffi::gst_segment_to_running_time(
self.to_glib_none().0, &self.0,
self.get_format().to_glib(), self.get_format().to_glib(),
position.to_value() as u64, position.to_glib() as u64,
) as i64, ) as i64,
) )
} }
} }
pub fn to_running_time_full<V: Into<FormatValue>>(&self, position: V) -> (i32, FormatValue) { pub fn to_running_time_full<V: Into<T>>(&self, position: V) -> (i32, T) {
let position = position.into(); let position = position.into();
assert_eq!(self.get_format(), position.to_format());
if T::get_default_format() == Format::Undefined {
assert_eq!(self.get_format(), position.get_format());
}
unsafe { unsafe {
let mut running_time = mem::uninitialized(); let mut running_time = mem::uninitialized();
let ret = ffi::gst_segment_to_running_time_full( let ret = ffi::gst_segment_to_running_time_full(
self.to_glib_none().0, &self.0,
self.get_format().to_glib(), self.get_format().to_glib(),
position.to_value() as u64, position.to_glib() as u64,
&mut running_time, &mut running_time,
); );
( (ret, T::from_glib(self.get_format(), running_time as i64))
ret,
FormatValue::new(self.get_format(), running_time as i64),
)
} }
} }
pub fn to_stream_time<V: Into<FormatValue>>(&self, position: V) -> FormatValue { pub fn to_stream_time<V: Into<T>>(&self, position: V) -> T {
let position = position.into(); let position = position.into();
assert_eq!(self.get_format(), position.to_format());
if T::get_default_format() == Format::Undefined {
assert_eq!(self.get_format(), position.get_format());
}
unsafe { unsafe {
FormatValue::new( T::from_glib(
self.get_format(), self.get_format(),
ffi::gst_segment_to_stream_time( ffi::gst_segment_to_stream_time(
self.to_glib_none().0, &self.0,
self.get_format().to_glib(), self.get_format().to_glib(),
position.to_value() as u64, position.to_glib() as u64,
) as i64, ) as i64,
) )
} }
} }
pub fn to_stream_time_full<V: Into<FormatValue>>(&self, position: V) -> (i32, FormatValue) { pub fn to_stream_time_full<V: Into<T>>(&self, position: V) -> (i32, T) {
let position = position.into(); let position = position.into();
assert_eq!(self.get_format(), position.to_format());
if T::get_default_format() == Format::Undefined {
assert_eq!(self.get_format(), position.get_format());
}
unsafe { unsafe {
let mut stream_time = mem::uninitialized(); let mut stream_time = mem::uninitialized();
let ret = ffi::gst_segment_to_stream_time_full( let ret = ffi::gst_segment_to_stream_time_full(
self.to_glib_none().0, &self.0,
self.get_format().to_glib(), self.get_format().to_glib(),
position.to_value() as u64, position.to_glib() as u64,
&mut stream_time, &mut stream_time,
); );
(ret, FormatValue::new(self.get_format(), stream_time as i64)) (ret, T::from_glib(self.get_format(), stream_time as i64))
} }
} }
@ -294,6 +372,7 @@ impl Segment {
} }
pub fn set_rate(&mut self, rate: f64) { pub fn set_rate(&mut self, rate: f64) {
assert_ne!(rate, 0.0);
self.0.rate = rate; self.0.rate = rate;
} }
@ -302,6 +381,7 @@ impl Segment {
} }
pub fn set_applied_rate(&mut self, applied_rate: f64) { pub fn set_applied_rate(&mut self, applied_rate: f64) {
assert_ne!(applied_rate, 0.0);
self.0.applied_rate = applied_rate; self.0.applied_rate = applied_rate;
} }
@ -309,158 +389,180 @@ impl Segment {
from_glib(self.0.format) from_glib(self.0.format)
} }
pub fn set_format(&mut self, format: Format) { pub fn get_base(&self) -> T {
self.0.format = format.to_glib(); unsafe { T::from_glib(self.get_format(), self.0.base as i64) }
} }
pub fn get_base(&self) -> FormatValue { pub fn set_base<V: Into<T>>(&mut self, base: V) {
FormatValue::new(self.get_format(), self.0.base as i64)
}
pub fn set_base<V: Into<FormatValue>>(&mut self, base: V) {
let base = base.into(); let base = base.into();
assert_eq!(self.get_format(), base.to_format());
self.0.base = base.to_value() as u64; if T::get_default_format() == Format::Undefined {
assert_eq!(self.get_format(), base.get_format());
} }
pub fn get_offset(&self) -> FormatValue { self.0.base = unsafe { base.to_glib() } as u64;
FormatValue::new(self.get_format(), self.0.offset as i64)
} }
pub fn set_offset<V: Into<FormatValue>>(&mut self, offset: V) { pub fn get_offset(&self) -> T {
unsafe { T::from_glib(self.get_format(), self.0.offset as i64) }
}
pub fn set_offset<V: Into<T>>(&mut self, offset: V) {
let offset = offset.into(); let offset = offset.into();
assert_eq!(self.get_format(), offset.to_format());
self.0.offset = offset.to_value() as u64; if T::get_default_format() == Format::Undefined {
assert_eq!(self.get_format(), offset.get_format());
} }
pub fn get_start(&self) -> FormatValue { self.0.offset = unsafe { offset.to_glib() } as u64;
FormatValue::new(self.get_format(), self.0.start as i64)
} }
pub fn set_start<V: Into<FormatValue>>(&mut self, start: V) { pub fn get_start(&self) -> T {
unsafe { T::from_glib(self.get_format(), self.0.start as i64) }
}
pub fn set_start<V: Into<T>>(&mut self, start: V) {
let start = start.into(); let start = start.into();
assert_eq!(self.get_format(), start.to_format());
self.0.start = start.to_value() as u64; if T::get_default_format() == Format::Undefined {
assert_eq!(self.get_format(), start.get_format());
} }
pub fn get_stop(&self) -> FormatValue { self.0.start = unsafe { start.to_glib() } as u64;
FormatValue::new(self.get_format(), self.0.stop as i64)
} }
pub fn set_stop<V: Into<FormatValue>>(&mut self, stop: V) { pub fn get_stop(&self) -> T {
unsafe { T::from_glib(self.get_format(), self.0.stop as i64) }
}
pub fn set_stop<V: Into<T>>(&mut self, stop: V) {
let stop = stop.into(); let stop = stop.into();
assert_eq!(self.get_format(), stop.to_format());
self.0.stop = stop.to_value() as u64; if T::get_default_format() == Format::Undefined {
assert_eq!(self.get_format(), stop.get_format());
} }
pub fn get_time(&self) -> FormatValue { self.0.stop = unsafe { stop.to_glib() } as u64;
FormatValue::new(self.get_format(), self.0.time as i64)
} }
pub fn set_time<V: Into<FormatValue>>(&mut self, time: V) { pub fn get_time(&self) -> T {
unsafe { T::from_glib(self.get_format(), self.0.time as i64) }
}
pub fn set_time<V: Into<T>>(&mut self, time: V) {
let time = time.into(); let time = time.into();
assert_eq!(self.get_format(), time.to_format());
self.0.time = time.to_value() as u64; if T::get_default_format() == Format::Undefined {
assert_eq!(self.get_format(), time.get_format());
} }
pub fn get_position(&self) -> FormatValue { self.0.time = unsafe { time.to_glib() } as u64;
FormatValue::new(self.get_format(), self.0.position as i64)
} }
pub fn set_position<V: Into<FormatValue>>(&mut self, position: V) { pub fn get_position(&self) -> T {
unsafe { T::from_glib(self.get_format(), self.0.position as i64) }
}
pub fn set_position<V: Into<T>>(&mut self, position: V) {
let position = position.into(); let position = position.into();
assert_eq!(self.get_format(), position.to_format());
self.0.position = position.to_value() as u64; if T::get_default_format() == Format::Undefined {
assert_eq!(self.get_format(), position.get_format());
} }
pub fn get_duration(&self) -> FormatValue { self.0.position = unsafe { position.to_glib() } as u64;
FormatValue::new(self.get_format(), self.0.duration as i64)
} }
pub fn set_duration<V: Into<FormatValue>>(&mut self, duration: V) { pub fn get_duration(&self) -> T {
unsafe { T::from_glib(self.get_format(), self.0.duration as i64) }
}
pub fn set_duration<V: Into<T>>(&mut self, duration: V) {
let duration = duration.into(); let duration = duration.into();
assert_eq!(self.get_format(), duration.to_format());
self.0.duration = duration.to_value() as u64; if T::get_default_format() == Format::Undefined {
assert_eq!(self.get_format(), duration.get_format());
}
self.0.duration = unsafe { duration.to_glib() } as u64;
} }
} }
impl PartialEq for Segment { impl<T: FormattedValue> PartialEq for FormattedSegment<T> {
#[inline] #[inline]
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
self.is_equal(other) unsafe { from_glib(ffi::gst_segment_is_equal(&self.0, &other.0)) }
} }
} }
impl Eq for Segment {} impl<T: FormattedValue> Eq for FormattedSegment<T> {}
unsafe impl Send for Segment {} unsafe impl<T: FormattedValue> Send for FormattedSegment<T> {}
impl Clone for Segment { impl<T: FormattedValue> Clone for FormattedSegment<T> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
unsafe { Segment(ptr::read(&self.0)) } unsafe { FormattedSegment(ptr::read(&self.0), PhantomData) }
} }
} }
impl fmt::Debug for Segment { impl<T: FormattedValue> AsRef<Segment> for FormattedSegment<T> {
fn as_ref(&self) -> &Segment {
unsafe { mem::transmute(self) }
}
}
impl<T: FormattedValue> fmt::Debug for FormattedSegment<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.get_format() { let segment = self.as_ref();
match segment.get_format() {
Format::Undefined => f.debug_struct("Segment") Format::Undefined => f.debug_struct("Segment")
.field("format", &Format::Undefined) .field("format", &Format::Undefined)
.finish(), .finish(),
Format::Time => f.debug_struct("Segment") Format::Time => {
let segment = segment.downcast_ref::<::ClockTime>().unwrap();
f.debug_struct("Segment")
.field("format", &Format::Time) .field("format", &Format::Time)
.field( .field("start", &segment.get_start().to_string())
"start", .field("offset", &segment.get_offset().to_string())
&self.get_start().try_to_time().unwrap().to_string(), .field("stop", &segment.get_stop().to_string())
) .field("rate", &segment.get_rate())
.field( .field("applied_rate", &segment.get_applied_rate())
"offset", .field("flags", &segment.get_flags())
&self.get_offset().try_to_time().unwrap().to_string(), .field("time", &segment.get_time().to_string())
) .field("base", &segment.get_base().to_string())
.field("stop", &self.get_stop().try_to_time().unwrap().to_string()) .field("position", &segment.get_position().to_string())
.field("rate", &self.get_rate()) .field("duration", &segment.get_duration().to_string())
.field("applied_rate", &self.get_applied_rate()) .finish()
.field("flags", &self.get_flags()) }
.field("time", &self.get_time().try_to_time().unwrap().to_string())
.field("base", &self.get_base().try_to_time().unwrap().to_string())
.field(
"position",
&self.get_position().try_to_time().unwrap().to_string(),
)
.field(
"duration",
&self.get_duration().try_to_time().unwrap().to_string(),
)
.finish(),
_ => f.debug_struct("Segment") _ => f.debug_struct("Segment")
.field("format", &self.get_format()) .field("format", &segment.get_format())
.field("start", &self.get_start()) .field("start", &segment.get_start())
.field("offset", &self.get_offset()) .field("offset", &segment.get_offset())
.field("stop", &self.get_stop()) .field("stop", &segment.get_stop())
.field("rate", &self.get_rate()) .field("rate", &segment.get_rate())
.field("applied_rate", &self.get_applied_rate()) .field("applied_rate", &segment.get_applied_rate())
.field("flags", &self.get_flags()) .field("flags", &segment.get_flags())
.field("time", &self.get_time()) .field("time", &segment.get_time())
.field("base", &self.get_base()) .field("base", &segment.get_base())
.field("position", &self.get_position()) .field("position", &segment.get_position())
.field("duration", &self.get_duration()) .field("duration", &segment.get_duration())
.finish(), .finish(),
} }
} }
} }
impl glib::types::StaticType for Segment { impl<T: FormattedValue> Default for FormattedSegment<T> {
fn static_type() -> glib::types::Type {
unsafe { glib::translate::from_glib(ffi::gst_segment_get_type()) }
}
}
impl Default for Segment {
fn default() -> Self { fn default() -> Self {
Self::new() Self::new()
} }
} }
impl<T: FormattedValue> glib::types::StaticType for FormattedSegment<T> {
fn static_type() -> glib::types::Type {
unsafe { glib::translate::from_glib(ffi::gst_segment_get_type()) }
}
}
#[doc(hidden)] #[doc(hidden)]
impl<'a> glib::value::FromValueOptional<'a> for Segment { impl<'a> glib::value::FromValueOptional<'a> for Segment {
unsafe fn from_value_optional(value: &glib::Value) -> Option<Self> { unsafe fn from_value_optional(value: &glib::Value) -> Option<Self> {
@ -470,7 +572,7 @@ impl<'a> glib::value::FromValueOptional<'a> for Segment {
} }
#[doc(hidden)] #[doc(hidden)]
impl glib::value::SetValue for Segment { impl<T: FormattedValue> glib::value::SetValue for FormattedSegment<T> {
unsafe fn set_value(value: &mut glib::Value, this: &Self) { unsafe fn set_value(value: &mut glib::Value, this: &Self) {
gobject_ffi::g_value_set_boxed( gobject_ffi::g_value_set_boxed(
value.to_glib_none_mut().0, value.to_glib_none_mut().0,
@ -481,7 +583,7 @@ impl glib::value::SetValue for Segment {
} }
#[doc(hidden)] #[doc(hidden)]
impl glib::value::SetValueOptional for Segment { impl<T: FormattedValue> glib::value::SetValueOptional for FormattedSegment<T> {
unsafe fn set_value_optional(value: &mut glib::Value, this: Option<&Self>) { unsafe fn set_value_optional(value: &mut glib::Value, this: Option<&Self>) {
gobject_ffi::g_value_set_boxed( gobject_ffi::g_value_set_boxed(
value.to_glib_none_mut().0, value.to_glib_none_mut().0,
@ -492,20 +594,14 @@ impl glib::value::SetValueOptional for Segment {
} }
#[doc(hidden)] #[doc(hidden)]
impl glib::translate::Uninitialized for Segment { impl<T: FormattedValue> glib::translate::GlibPtrDefault for FormattedSegment<T> {
unsafe fn uninitialized() -> Self {
mem::zeroed()
}
}
#[doc(hidden)]
impl glib::translate::GlibPtrDefault for Segment {
type GlibType = *mut ffi::GstSegment; type GlibType = *mut ffi::GstSegment;
} }
#[doc(hidden)] #[doc(hidden)]
impl<'a> glib::translate::ToGlibPtr<'a, *const ffi::GstSegment> for Segment { impl<'a, T: FormattedValue> glib::translate::ToGlibPtr<'a, *const ffi::GstSegment>
type Storage = &'a Segment; for FormattedSegment<T> {
type Storage = &'a FormattedSegment<T>;
fn to_glib_none(&'a self) -> glib::translate::Stash<'a, *const ffi::GstSegment, Self> { fn to_glib_none(&'a self) -> glib::translate::Stash<'a, *const ffi::GstSegment, Self> {
glib::translate::Stash(&self.0, self) glib::translate::Stash(&self.0, self)
@ -517,8 +613,9 @@ impl<'a> glib::translate::ToGlibPtr<'a, *const ffi::GstSegment> for Segment {
} }
#[doc(hidden)] #[doc(hidden)]
impl<'a> glib::translate::ToGlibPtrMut<'a, *mut ffi::GstSegment> for Segment { impl<'a, T: FormattedValue> glib::translate::ToGlibPtrMut<'a, *mut ffi::GstSegment>
type Storage = &'a mut Segment; for FormattedSegment<T> {
type Storage = &'a mut FormattedSegment<T>;
#[inline] #[inline]
fn to_glib_none_mut(&'a mut self) -> glib::translate::StashMut<'a, *mut ffi::GstSegment, Self> { fn to_glib_none_mut(&'a mut self) -> glib::translate::StashMut<'a, *mut ffi::GstSegment, Self> {
@ -530,7 +627,7 @@ impl<'a> glib::translate::ToGlibPtrMut<'a, *mut ffi::GstSegment> for Segment {
impl glib::translate::FromGlibPtrNone<*const ffi::GstSegment> for Segment { impl glib::translate::FromGlibPtrNone<*const ffi::GstSegment> for Segment {
#[inline] #[inline]
unsafe fn from_glib_none(ptr: *const ffi::GstSegment) -> Self { unsafe fn from_glib_none(ptr: *const ffi::GstSegment) -> Self {
Segment(ptr::read(ptr)) FormattedSegment(ptr::read(ptr), PhantomData)
} }
} }
@ -538,7 +635,7 @@ impl glib::translate::FromGlibPtrNone<*const ffi::GstSegment> for Segment {
impl glib::translate::FromGlibPtrNone<*mut ffi::GstSegment> for Segment { impl glib::translate::FromGlibPtrNone<*mut ffi::GstSegment> for Segment {
#[inline] #[inline]
unsafe fn from_glib_none(ptr: *mut ffi::GstSegment) -> Self { unsafe fn from_glib_none(ptr: *mut ffi::GstSegment) -> Self {
Segment(ptr::read(ptr)) FormattedSegment(ptr::read(ptr), PhantomData)
} }
} }
@ -546,7 +643,7 @@ impl glib::translate::FromGlibPtrNone<*mut ffi::GstSegment> for Segment {
impl glib::translate::FromGlibPtrBorrow<*mut ffi::GstSegment> for Segment { impl glib::translate::FromGlibPtrBorrow<*mut ffi::GstSegment> for Segment {
#[inline] #[inline]
unsafe fn from_glib_borrow(ptr: *mut ffi::GstSegment) -> Self { unsafe fn from_glib_borrow(ptr: *mut ffi::GstSegment) -> Self {
Segment(ptr::read(ptr)) FormattedSegment(ptr::read(ptr), PhantomData)
} }
} }

View file

@ -57,16 +57,14 @@ fn tutorial_main() {
if custom_data.playing { if custom_data.playing {
let position = custom_data let position = custom_data
.playbin .playbin
.query_position(gst::Format::Time) .query_position::<gst::ClockTime>()
.and_then(|v| v.try_to_time())
.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::CLOCK_TIME_NONE {
custom_data.duration = custom_data custom_data.duration = custom_data
.playbin .playbin
.query_duration(gst::Format::Time) .query_duration()
.and_then(|v| v.try_to_time())
.expect("Could not query current duration.") .expect("Could not query current duration.")
} }

View file

@ -147,12 +147,12 @@ mod tutorial5 {
let pipeline = &pipeline; let pipeline = &pipeline;
let lslider = &lslider; let lslider = &lslider;
if let Some(gst::FormatValue::Time(dur)) = pipeline.query_duration(gst::Format::Time) { if let Some(dur) = pipeline.query_duration::<gst::ClockTime>() {
let seconds = dur / gst::SECOND; let seconds = dur / gst::SECOND;
lslider.set_range(0.0, seconds.map(|v| v as f64).unwrap_or(0.0)); lslider.set_range(0.0, seconds.map(|v| v as f64).unwrap_or(0.0));
} }
if let Some(gst::FormatValue::Time(pos)) = pipeline.query_position(gst::Format::Time) { if let Some(pos) = pipeline.query_position::<gst::ClockTime>() {
let seconds = pos / gst::SECOND; let seconds = pos / gst::SECOND;
lslider.block_signal(&slider_update_signal_id); lslider.block_signal(&slider_update_signal_id);
lslider.set_value(seconds.map(|v| v as f64).unwrap_or(0.0)); lslider.set_value(seconds.map(|v| v as f64).unwrap_or(0.0));