diff --git a/examples/src/bin/queries.rs b/examples/src/bin/queries.rs index ca50168f9..d49e51e72 100644 --- a/examples/src/bin/queries.rs +++ b/examples/src/bin/queries.rs @@ -25,19 +25,14 @@ fn example_main() { let pipeline_clone = pipeline.clone(); glib::timeout_add_seconds(1, move || { - use gst::QueryView; - let pipeline = &pipeline_clone; //let pos = pipeline.query_position(gst::Format::Time).unwrap_or(-1); //let dur = pipeline.query_duration(gst::Format::Time).unwrap_or(-1); let pos = { let mut q = gst::Query::new_position(gst::Format::Time); - if pipeline.query(q.get_mut().unwrap()) { - match q.view() { - QueryView::Position(ref p) => Some(p.get_result()), - _ => None, - } + if pipeline.query(&mut q) { + Some(q.get_result()) } else { None } @@ -46,11 +41,8 @@ fn example_main() { let dur = { let mut q = gst::Query::new_duration(gst::Format::Time); - if pipeline.query(q.get_mut().unwrap()) { - match q.view() { - QueryView::Duration(ref p) => Some(p.get_result()), - _ => None, - } + if pipeline.query(&mut q) { + Some(q.get_result()) } else { None } diff --git a/gstreamer/src/query.rs b/gstreamer/src/query.rs index 84dea242e..95304b867 100644 --- a/gstreamer/src/query.rs +++ b/gstreamer/src/query.rs @@ -15,10 +15,10 @@ use std::ptr; use std::mem; use std::fmt; use std::ffi::CStr; -use std::ops::Deref; +use std::ops::{Deref, DerefMut}; use glib; -use glib::translate::{from_glib, from_glib_full, ToGlib, ToGlibPtr}; +use glib::translate::*; #[repr(C)] pub struct QueryRef(ffi::GstQuery); @@ -33,92 +33,151 @@ unsafe impl MiniObject for QueryRef { } impl GstRc { - pub fn new_position(fmt: ::Format) -> Self { + pub fn new_position(fmt: ::Format) -> Position { assert_initialized_main_thread!(); - unsafe { from_glib_full(ffi::gst_query_new_position(fmt.to_glib())) } + unsafe { + Position::( + from_glib_full(ffi::gst_query_new_position(fmt.to_glib())) + ) + } } - pub fn new_duration(fmt: ::Format) -> Self { + pub fn new_duration(fmt: ::Format) -> Duration { assert_initialized_main_thread!(); - unsafe { from_glib_full(ffi::gst_query_new_duration(fmt.to_glib())) } + unsafe { + Duration::( + from_glib_full(ffi::gst_query_new_duration(fmt.to_glib())) + ) + } } - pub fn new_latency() -> Self { + pub fn new_latency() -> Latency { assert_initialized_main_thread!(); - unsafe { from_glib_full(ffi::gst_query_new_latency()) } + unsafe { + Latency::( + from_glib_full(ffi::gst_query_new_latency()) + ) + } } - pub fn new_seeking(fmt: ::Format) -> Self { + pub fn new_seeking(fmt: ::Format) -> Seeking { assert_initialized_main_thread!(); - unsafe { from_glib_full(ffi::gst_query_new_seeking(fmt.to_glib())) } + unsafe { + Seeking::( + from_glib_full(ffi::gst_query_new_seeking(fmt.to_glib())) + ) + } } - pub fn new_segment(fmt: ::Format) -> Self { + pub fn new_segment(fmt: ::Format) -> Segment { assert_initialized_main_thread!(); - unsafe { from_glib_full(ffi::gst_query_new_segment(fmt.to_glib())) } + unsafe { + Segment::( + from_glib_full(ffi::gst_query_new_segment(fmt.to_glib())) + ) + } } - pub fn new_convert>(value: V, dest_fmt: ::Format) -> Self { + pub fn new_convert>( + value: V, + dest_fmt: ::Format + ) -> Convert { assert_initialized_main_thread!(); let value = value.into(); unsafe { - from_glib_full(ffi::gst_query_new_convert( - value.get_format().to_glib(), - value.get_value(), - dest_fmt.to_glib(), - )) + Convert::( + from_glib_full(ffi::gst_query_new_convert( + value.get_format().to_glib(), + value.get_value(), + dest_fmt.to_glib(), + )) + ) } } - pub fn new_formats() -> Self { - assert_initialized_main_thread!(); - unsafe { from_glib_full(ffi::gst_query_new_formats()) } - } - - pub fn new_buffering(fmt: ::Format) -> Self { - assert_initialized_main_thread!(); - unsafe { from_glib_full(ffi::gst_query_new_buffering(fmt.to_glib())) } - } - - pub fn new_custom(structure: ::Structure) -> Self { + pub fn new_formats() -> Formats { assert_initialized_main_thread!(); unsafe { - from_glib_full(ffi::gst_query_new_custom( - ffi::GST_QUERY_CUSTOM, - structure.into_ptr(), - )) + Formats::( + from_glib_full(ffi::gst_query_new_formats()) + ) } } - pub fn new_uri() -> Self { + pub fn new_buffering(fmt: ::Format) -> Buffering { assert_initialized_main_thread!(); - unsafe { from_glib_full(ffi::gst_query_new_uri()) } + unsafe { + Buffering::( + from_glib_full(ffi::gst_query_new_buffering(fmt.to_glib())) + ) + } } - pub fn new_scheduling() -> Self { + pub fn new_custom(structure: ::Structure) -> Custom { assert_initialized_main_thread!(); - unsafe { from_glib_full(ffi::gst_query_new_scheduling()) } + unsafe { + Custom::( + from_glib_full(ffi::gst_query_new_custom( + ffi::GST_QUERY_CUSTOM, + structure.into_ptr(), + )) + ) + } } - pub fn new_accept_caps(caps: &::Caps) -> Self { + pub fn new_uri() -> Uri { assert_initialized_main_thread!(); - unsafe { from_glib_full(ffi::gst_query_new_accept_caps(caps.as_mut_ptr())) } + unsafe { + Uri::( + from_glib_full(ffi::gst_query_new_uri()) + ) + } } - pub fn new_caps<'a, P: Into>>(filter: P) -> Self { + pub fn new_scheduling() -> Scheduling { + assert_initialized_main_thread!(); + unsafe { + Scheduling::( + from_glib_full(ffi::gst_query_new_scheduling()) + ) + } + } + + pub fn new_accept_caps(caps: &::Caps) -> AcceptCaps { + assert_initialized_main_thread!(); + unsafe { + AcceptCaps::( + from_glib_full(ffi::gst_query_new_accept_caps(caps.as_mut_ptr())) + ) + } + } + + pub fn new_caps<'a, P: Into>>(filter: P) -> Caps { assert_initialized_main_thread!(); let filter = filter.into(); - unsafe { from_glib_full(ffi::gst_query_new_caps(filter.to_glib_none().0)) } + unsafe { + Caps::( + from_glib_full(ffi::gst_query_new_caps(filter.to_glib_none().0)) + ) + } } - pub fn new_drain() -> Self { + pub fn new_drain() -> Drain { assert_initialized_main_thread!(); - unsafe { from_glib_full(ffi::gst_query_new_drain()) } + unsafe { + Drain::( + from_glib_full(ffi::gst_query_new_drain()) + ) + } } - pub fn new_context(context_type: &str) -> Self { + pub fn new_context(context_type: &str) -> Context { assert_initialized_main_thread!(); - unsafe { from_glib_full(ffi::gst_query_new_context(context_type.to_glib_none().0)) } + unsafe { + Context::( + from_glib_full(ffi::gst_query_new_context(context_type.to_glib_none().0)) + ) + } } } @@ -208,17 +267,45 @@ impl fmt::Debug for QueryRef { } } -impl ToOwned for QueryRef { - type Owned = GstRc; +pub unsafe trait AsPtr { + unsafe fn as_ptr(&self) -> *mut ffi::GstQuery; +} - fn to_owned(&self) -> GstRc { - unsafe { - from_glib_full(ffi::gst_mini_object_copy(self.as_ptr() as *const _) - as *mut _) - } +pub unsafe trait AsMutPtr: AsPtr { + unsafe fn as_mut_ptr(&self) -> *mut ffi::GstQuery; +} + +unsafe impl AsPtr for Query { + unsafe fn as_ptr(&self) -> *mut ffi::GstQuery { + self.as_ref().as_ptr() as *mut ffi::GstQuery } } +unsafe impl AsMutPtr for Query { + unsafe fn as_mut_ptr(&self) -> *mut ffi::GstQuery { + self.as_ref().as_mut_ptr() + } +} + +unsafe impl<'a> AsPtr for &'a QueryRef { + unsafe fn as_ptr(&self) -> *mut ffi::GstQuery { + MiniObject::as_ptr(self as &QueryRef) as *mut ffi::GstQuery + } +} + +unsafe impl<'a> AsPtr for &'a mut QueryRef { + unsafe fn as_ptr(&self) -> *mut ffi::GstQuery { + MiniObject::as_ptr(self as &QueryRef) as *mut ffi::GstQuery + } +} + +unsafe impl<'a> AsMutPtr for &'a mut QueryRef { + unsafe fn as_mut_ptr(&self) -> *mut ffi::GstQuery { + MiniObject::as_mut_ptr(self as &QueryRef) as *mut ffi::GstQuery + } +} + +#[derive(Debug)] pub enum QueryView { Position(Position), Duration(Duration), @@ -244,6 +331,7 @@ pub enum QueryView { macro_rules! declare_concrete_query( ($name:ident, $param:ident) => { + #[derive(Debug)] pub struct $name<$param>($param); impl<'a> $name<&'a QueryRef> { @@ -260,12 +348,6 @@ macro_rules! declare_concrete_query( } } - impl<'a> $name<&'a mut QueryRef> { - pub fn get_mut_query(&mut self) -> &mut QueryRef { - self.0 - } - } - impl<'a> Deref for $name<&'a mut QueryRef> { type Target = $name<&'a QueryRef>; @@ -275,17 +357,43 @@ macro_rules! declare_concrete_query( } } } + + impl<'a> $name<&'a mut QueryRef> { + pub fn get_mut_query(&mut self) -> &mut QueryRef { + self.0 + } + } + + impl Deref for $name { + type Target = QueryRef; + + fn deref(&self) -> &Self::Target { + &self.0 + } + } + + impl DerefMut for $name { + fn deref_mut(&mut self) -> &mut Self::Target { + self.0.get_mut().unwrap() + } + } + + impl From<$name> for Query { + fn from(concrete: $name) -> Self { + unsafe { from_glib_none(concrete.0.as_mut_ptr()) } + } + } } ); declare_concrete_query!(Position, T); -impl<'a> Position<&'a QueryRef> { +impl Position { pub fn get_result(&self) -> GenericFormattedValue { unsafe { let mut fmt = mem::uninitialized(); let mut pos = mem::uninitialized(); - ffi::gst_query_parse_position(self.as_mut_ptr(), &mut fmt, &mut pos); + ffi::gst_query_parse_position(self.0.as_ptr(), &mut fmt, &mut pos); GenericFormattedValue::new(from_glib(fmt), pos) } @@ -295,20 +403,20 @@ impl<'a> Position<&'a QueryRef> { unsafe { let mut fmt = mem::uninitialized(); - ffi::gst_query_parse_position(self.as_mut_ptr(), &mut fmt, ptr::null_mut()); + ffi::gst_query_parse_position(self.0.as_ptr(), &mut fmt, ptr::null_mut()); from_glib(fmt) } } } -impl<'a> Position<&'a mut QueryRef> { +impl Position { pub fn set>(&mut self, pos: V) { let pos = pos.into(); assert_eq!(pos.get_format(), self.get_format()); unsafe { ffi::gst_query_set_position( - self.as_mut_ptr(), + self.0.as_mut_ptr(), pos.get_format().to_glib(), pos.get_value(), ); @@ -317,13 +425,13 @@ impl<'a> Position<&'a mut QueryRef> { } declare_concrete_query!(Duration, T); -impl<'a> Duration<&'a QueryRef> { +impl Duration { pub fn get_result(&self) -> GenericFormattedValue { unsafe { let mut fmt = mem::uninitialized(); let mut pos = mem::uninitialized(); - ffi::gst_query_parse_duration(self.as_mut_ptr(), &mut fmt, &mut pos); + ffi::gst_query_parse_duration(self.0.as_ptr(), &mut fmt, &mut pos); GenericFormattedValue::new(from_glib(fmt), pos) } @@ -333,20 +441,20 @@ impl<'a> Duration<&'a QueryRef> { unsafe { let mut fmt = mem::uninitialized(); - ffi::gst_query_parse_duration(self.as_mut_ptr(), &mut fmt, ptr::null_mut()); + ffi::gst_query_parse_duration(self.0.as_ptr(), &mut fmt, ptr::null_mut()); from_glib(fmt) } } } -impl<'a> Duration<&'a mut QueryRef> { +impl Duration { pub fn set>(&mut self, dur: V) { let dur = dur.into(); assert_eq!(dur.get_format(), self.get_format()); unsafe { ffi::gst_query_set_duration( - self.as_mut_ptr(), + self.0.as_mut_ptr(), dur.get_format().to_glib(), dur.get_value(), ); @@ -355,25 +463,25 @@ impl<'a> Duration<&'a mut QueryRef> { } declare_concrete_query!(Latency, T); -impl<'a> Latency<&'a QueryRef> { +impl Latency { pub fn get_result(&self) -> (bool, ::ClockTime, ::ClockTime) { unsafe { let mut live = mem::uninitialized(); let mut min = mem::uninitialized(); let mut max = mem::uninitialized(); - ffi::gst_query_parse_latency(self.as_mut_ptr(), &mut live, &mut min, &mut max); + ffi::gst_query_parse_latency(self.0.as_ptr(), &mut live, &mut min, &mut max); (from_glib(live), from_glib(min), from_glib(max)) } } } -impl<'a> Latency<&'a mut QueryRef> { +impl Latency { pub fn set(&mut self, live: bool, min: ::ClockTime, max: ::ClockTime) { unsafe { ffi::gst_query_set_latency( - self.as_mut_ptr(), + self.0.as_mut_ptr(), live.to_glib(), min.to_glib(), max.to_glib(), @@ -386,7 +494,7 @@ declare_concrete_query!(Jitter, T); declare_concrete_query!(Rate, T); declare_concrete_query!(Seeking, T); -impl<'a> Seeking<&'a QueryRef> { +impl Seeking { pub fn get_result(&self) -> (bool, GenericFormattedValue, GenericFormattedValue) { unsafe { let mut fmt = mem::uninitialized(); @@ -394,7 +502,7 @@ impl<'a> Seeking<&'a QueryRef> { let mut start = mem::uninitialized(); let mut end = mem::uninitialized(); ffi::gst_query_parse_seeking( - self.as_mut_ptr(), + self.0.as_ptr(), &mut fmt, &mut seekable, &mut start, @@ -413,7 +521,7 @@ impl<'a> Seeking<&'a QueryRef> { unsafe { let mut fmt = mem::uninitialized(); ffi::gst_query_parse_seeking( - self.as_mut_ptr(), + self.0.as_ptr(), &mut fmt, ptr::null_mut(), ptr::null_mut(), @@ -425,7 +533,7 @@ impl<'a> Seeking<&'a QueryRef> { } } -impl<'a> Seeking<&'a mut QueryRef> { +impl Seeking { pub fn set>(&mut self, seekable: bool, start: V, end: V) { let start = start.into(); let end = end.into(); @@ -435,7 +543,7 @@ impl<'a> Seeking<&'a mut QueryRef> { unsafe { ffi::gst_query_set_seeking( - self.as_mut_ptr(), + self.0.as_mut_ptr(), start.get_format().to_glib(), seekable.to_glib(), start.get_value(), @@ -446,7 +554,7 @@ impl<'a> Seeking<&'a mut QueryRef> { } declare_concrete_query!(Segment, T); -impl<'a> Segment<&'a QueryRef> { +impl Segment { pub fn get_result(&self) -> (f64, GenericFormattedValue, GenericFormattedValue) { unsafe { let mut rate = mem::uninitialized(); @@ -455,7 +563,7 @@ impl<'a> Segment<&'a QueryRef> { let mut stop = mem::uninitialized(); ffi::gst_query_parse_segment( - self.as_mut_ptr(), + self.0.as_ptr(), &mut rate, &mut fmt, &mut start, @@ -474,7 +582,7 @@ impl<'a> Segment<&'a QueryRef> { let mut fmt = mem::uninitialized(); ffi::gst_query_parse_segment( - self.as_mut_ptr(), + self.0.as_ptr(), ptr::null_mut(), &mut fmt, ptr::null_mut(), @@ -485,7 +593,7 @@ impl<'a> Segment<&'a QueryRef> { } } -impl<'a> Segment<&'a mut QueryRef> { +impl Segment { pub fn set>(&mut self, rate: f64, start: V, stop: V) { let start = start.into(); let stop = stop.into(); @@ -494,7 +602,7 @@ impl<'a> Segment<&'a mut QueryRef> { unsafe { ffi::gst_query_set_segment( - self.as_mut_ptr(), + self.0.as_mut_ptr(), rate, start.get_format().to_glib(), start.get_value(), @@ -505,7 +613,7 @@ impl<'a> Segment<&'a mut QueryRef> { } declare_concrete_query!(Convert, T); -impl<'a> Convert<&'a QueryRef> { +impl Convert { pub fn get_result(&self) -> (GenericFormattedValue, GenericFormattedValue) { unsafe { let mut src_fmt = mem::uninitialized(); @@ -514,7 +622,7 @@ impl<'a> Convert<&'a QueryRef> { let mut dest = mem::uninitialized(); ffi::gst_query_parse_convert( - self.as_mut_ptr(), + self.0.as_ptr(), &mut src_fmt, &mut src, &mut dest_fmt, @@ -534,7 +642,7 @@ impl<'a> Convert<&'a QueryRef> { let mut dest_fmt = mem::uninitialized(); ffi::gst_query_parse_convert( - self.as_mut_ptr(), + self.0.as_ptr(), &mut src_fmt, &mut src, &mut dest_fmt, @@ -548,14 +656,14 @@ impl<'a> Convert<&'a QueryRef> { } } -impl<'a> Convert<&'a mut QueryRef> { +impl Convert { pub fn set>(&mut self, src: V, dest: V) { let src = src.into(); let dest = dest.into(); unsafe { ffi::gst_query_set_convert( - self.as_mut_ptr(), + self.0.as_mut_ptr(), src.get_format().to_glib(), src.get_value(), dest.get_format().to_glib(), @@ -566,16 +674,16 @@ impl<'a> Convert<&'a mut QueryRef> { } declare_concrete_query!(Formats, T); -impl<'a> Formats<&'a QueryRef> { +impl Formats { pub fn get_result(&self) -> Vec<::Format> { unsafe { let mut n = mem::uninitialized(); - ffi::gst_query_parse_n_formats(self.as_mut_ptr(), &mut n); + ffi::gst_query_parse_n_formats(self.0.as_ptr(), &mut n); let mut res = Vec::with_capacity(n as usize); for i in 0..n { let mut fmt = mem::uninitialized(); - ffi::gst_query_parse_nth_format(self.as_mut_ptr(), i, &mut fmt); + ffi::gst_query_parse_nth_format(self.0.as_ptr(), i, &mut fmt); res.push(from_glib(fmt)); } @@ -584,23 +692,23 @@ impl<'a> Formats<&'a QueryRef> { } } -impl<'a> Formats<&'a mut QueryRef> { +impl Formats { pub fn set(&mut self, formats: &[::Format]) { unsafe { let v: Vec<_> = formats.iter().map(|f| f.to_glib()).collect(); - ffi::gst_query_set_formatsv(self.as_mut_ptr(), v.len() as i32, v.as_ptr() as *mut _); + ffi::gst_query_set_formatsv(self.0.as_mut_ptr(), v.len() as i32, v.as_ptr() as *mut _); } } } declare_concrete_query!(Buffering, T); -impl<'a> Buffering<&'a QueryRef> { +impl Buffering { pub fn get_format(&self) -> ::Format { unsafe { let mut fmt = mem::uninitialized(); ffi::gst_query_parse_buffering_range( - self.as_mut_ptr(), + self.0.as_ptr(), &mut fmt, ptr::null_mut(), ptr::null_mut(), @@ -616,7 +724,7 @@ impl<'a> Buffering<&'a QueryRef> { let mut busy = mem::uninitialized(); let mut percent = mem::uninitialized(); - ffi::gst_query_parse_buffering_percent(self.as_mut_ptr(), &mut busy, &mut percent); + ffi::gst_query_parse_buffering_percent(self.0.as_ptr(), &mut busy, &mut percent); (from_glib(busy), percent) } @@ -630,7 +738,7 @@ impl<'a> Buffering<&'a QueryRef> { let mut estimated_total = mem::uninitialized(); ffi::gst_query_parse_buffering_range( - self.as_mut_ptr(), + self.0.as_ptr(), &mut fmt, &mut start, &mut stop, @@ -652,7 +760,7 @@ impl<'a> Buffering<&'a QueryRef> { let mut buffering_left = mem::uninitialized(); ffi::gst_query_parse_buffering_stats( - self.as_mut_ptr(), + self.0.as_ptr(), &mut mode, &mut avg_in, &mut avg_out, @@ -667,7 +775,7 @@ impl<'a> Buffering<&'a QueryRef> { unsafe { let mut fmt = mem::uninitialized(); ffi::gst_query_parse_buffering_range( - self.as_mut_ptr(), + self.0.as_ptr(), &mut fmt, ptr::null_mut(), ptr::null_mut(), @@ -675,13 +783,13 @@ impl<'a> Buffering<&'a QueryRef> { ); let fmt = from_glib(fmt); - let n = ffi::gst_query_get_n_buffering_ranges(self.as_mut_ptr()); + let n = ffi::gst_query_get_n_buffering_ranges(self.0.as_ptr()); let mut res = Vec::with_capacity(n as usize); for i in 0..n { let mut start = mem::uninitialized(); let mut stop = mem::uninitialized(); let s: bool = from_glib(ffi::gst_query_parse_nth_buffering_range( - self.as_mut_ptr(), + self.0.as_ptr(), i, &mut start, &mut stop, @@ -699,10 +807,10 @@ impl<'a> Buffering<&'a QueryRef> { } } -impl<'a> Buffering<&'a mut QueryRef> { +impl Buffering { pub fn set_percent(&mut self, busy: bool, percent: i32) { unsafe { - ffi::gst_query_set_buffering_percent(self.as_mut_ptr(), busy.to_glib(), percent); + ffi::gst_query_set_buffering_percent(self.0.as_mut_ptr(), busy.to_glib(), percent); } } @@ -720,7 +828,7 @@ impl<'a> Buffering<&'a mut QueryRef> { unsafe { ffi::gst_query_set_buffering_range( - self.as_mut_ptr(), + self.0.as_mut_ptr(), start.get_format().to_glib(), start.get_value(), stop.get_value(), @@ -739,7 +847,7 @@ impl<'a> Buffering<&'a mut QueryRef> { skip_assert_initialized!(); unsafe { ffi::gst_query_set_buffering_stats( - self.as_mut_ptr(), + self.0.as_mut_ptr(), mode.to_glib(), avg_in, avg_out, @@ -761,7 +869,7 @@ impl<'a> Buffering<&'a mut QueryRef> { assert_eq!(start.get_format(), fmt); assert_eq!(stop.get_format(), fmt); ffi::gst_query_add_buffering_range( - self.as_mut_ptr(), + self.0.as_mut_ptr(), start.get_value(), stop.get_value(), ); @@ -773,11 +881,11 @@ impl<'a> Buffering<&'a mut QueryRef> { declare_concrete_query!(Custom, T); declare_concrete_query!(Uri, T); -impl<'a> Uri<&'a QueryRef> { +impl Uri { pub fn get_uri(&self) -> Option { unsafe { let mut uri = ptr::null_mut(); - ffi::gst_query_parse_uri(self.as_mut_ptr(), &mut uri); + ffi::gst_query_parse_uri(self.0.as_ptr(), &mut uri); from_glib_full(uri) } } @@ -785,28 +893,28 @@ impl<'a> Uri<&'a QueryRef> { pub fn get_redirection(&self) -> (Option, bool) { unsafe { let mut uri = ptr::null_mut(); - ffi::gst_query_parse_uri_redirection(self.as_mut_ptr(), &mut uri); + ffi::gst_query_parse_uri_redirection(self.0.as_ptr(), &mut uri); let mut permanent = mem::uninitialized(); - ffi::gst_query_parse_uri_redirection_permanent(self.as_mut_ptr(), &mut permanent); + ffi::gst_query_parse_uri_redirection_permanent(self.0.as_ptr(), &mut permanent); (from_glib_full(uri), from_glib(permanent)) } } } -impl<'a> Uri<&'a mut QueryRef> { - pub fn set_uri<'b, T: Into<&'b str>>(&mut self, uri: T) { +impl Uri { + pub fn set_uri<'b, U: Into<&'b str>>(&mut self, uri: U) { let uri = uri.into(); unsafe { - ffi::gst_query_set_uri(self.as_mut_ptr(), uri.to_glib_none().0); + ffi::gst_query_set_uri(self.0.as_mut_ptr(), uri.to_glib_none().0); } } - pub fn set_redirection<'b, T: Into<&'b str>>(&mut self, uri: T, permanent: bool) { + pub fn set_redirection<'b, U: Into<&'b str>>(&mut self, uri: U, permanent: bool) { let uri = uri.into(); unsafe { - ffi::gst_query_set_uri_redirection(self.as_mut_ptr(), uri.to_glib_none().0); - ffi::gst_query_set_uri_redirection_permanent(self.as_mut_ptr(), permanent.to_glib()); + ffi::gst_query_set_uri_redirection(self.0.as_mut_ptr(), uri.to_glib_none().0); + ffi::gst_query_set_uri_redirection_permanent(self.0.as_mut_ptr(), permanent.to_glib()); } } } @@ -815,11 +923,11 @@ impl<'a> Uri<&'a mut QueryRef> { declare_concrete_query!(Allocation, T); declare_concrete_query!(Scheduling, T); -impl<'a> Scheduling<&'a QueryRef> { +impl Scheduling { pub fn has_scheduling_mode(&self, mode: ::PadMode) -> bool { unsafe { from_glib(ffi::gst_query_has_scheduling_mode( - self.as_mut_ptr(), + self.0.as_ptr(), mode.to_glib(), )) } @@ -833,7 +941,7 @@ impl<'a> Scheduling<&'a QueryRef> { skip_assert_initialized!(); unsafe { from_glib(ffi::gst_query_has_scheduling_mode_with_flags( - self.as_mut_ptr(), + self.0.as_ptr(), mode.to_glib(), flags.to_glib(), )) @@ -842,11 +950,11 @@ impl<'a> Scheduling<&'a QueryRef> { pub fn get_scheduling_modes(&self) -> Vec<::PadMode> { unsafe { - let n = ffi::gst_query_get_n_scheduling_modes(self.as_mut_ptr()); + let n = ffi::gst_query_get_n_scheduling_modes(self.0.as_ptr()); let mut res = Vec::with_capacity(n as usize); for i in 0..n { res.push(from_glib(ffi::gst_query_parse_nth_scheduling_mode( - self.as_mut_ptr(), + self.0.as_ptr(), i, ))); } @@ -863,7 +971,7 @@ impl<'a> Scheduling<&'a QueryRef> { let mut align = mem::uninitialized(); ffi::gst_query_parse_scheduling( - self.as_mut_ptr(), + self.0.as_ptr(), &mut flags, &mut minsize, &mut maxsize, @@ -875,11 +983,11 @@ impl<'a> Scheduling<&'a QueryRef> { } } -impl<'a> Scheduling<&'a mut QueryRef> { +impl Scheduling { pub fn add_scheduling_modes(&mut self, modes: &[::PadMode]) { unsafe { for mode in modes { - ffi::gst_query_add_scheduling_mode(self.as_mut_ptr(), mode.to_glib()); + ffi::gst_query_add_scheduling_mode(self.0.as_mut_ptr(), mode.to_glib()); } } } @@ -887,7 +995,7 @@ impl<'a> Scheduling<&'a mut QueryRef> { pub fn set(&mut self, flags: ::SchedulingFlags, minsize: i32, maxsize: i32, align: i32) { unsafe { ffi::gst_query_set_scheduling( - self.as_mut_ptr(), + self.0.as_mut_ptr(), flags.to_glib(), minsize, maxsize, @@ -898,11 +1006,11 @@ impl<'a> Scheduling<&'a mut QueryRef> { } declare_concrete_query!(AcceptCaps, T); -impl<'a> AcceptCaps<&'a QueryRef> { +impl AcceptCaps { pub fn get_caps(&self) -> &::CapsRef { unsafe { let mut caps = ptr::null_mut(); - ffi::gst_query_parse_accept_caps(self.as_mut_ptr(), &mut caps); + ffi::gst_query_parse_accept_caps(self.0.as_ptr(), &mut caps); ::CapsRef::from_ptr(caps) } } @@ -910,26 +1018,26 @@ impl<'a> AcceptCaps<&'a QueryRef> { pub fn get_result(&self) -> bool { unsafe { let mut accepted = mem::uninitialized(); - ffi::gst_query_parse_accept_caps_result(self.as_mut_ptr(), &mut accepted); + ffi::gst_query_parse_accept_caps_result(self.0.as_ptr(), &mut accepted); from_glib(accepted) } } } -impl<'a> AcceptCaps<&'a mut QueryRef> { +impl AcceptCaps { pub fn set_result(&mut self, accepted: bool) { unsafe { - ffi::gst_query_set_accept_caps_result(self.as_mut_ptr(), accepted.to_glib()); + ffi::gst_query_set_accept_caps_result(self.0.as_mut_ptr(), accepted.to_glib()); } } } declare_concrete_query!(Caps, T); -impl<'a> Caps<&'a QueryRef> { +impl Caps { pub fn get_filter(&self) -> Option<&::CapsRef> { unsafe { let mut caps = ptr::null_mut(); - ffi::gst_query_parse_caps(self.as_mut_ptr(), &mut caps); + ffi::gst_query_parse_caps(self.0.as_ptr(), &mut caps); if caps.is_null() { None } else { @@ -941,7 +1049,7 @@ impl<'a> Caps<&'a QueryRef> { pub fn get_result(&self) -> Option<&::CapsRef> { unsafe { let mut caps = ptr::null_mut(); - ffi::gst_query_parse_caps_result(self.as_mut_ptr(), &mut caps); + ffi::gst_query_parse_caps_result(self.0.as_ptr(), &mut caps); if caps.is_null() { None } else { @@ -951,10 +1059,10 @@ impl<'a> Caps<&'a QueryRef> { } } -impl<'a> Caps<&'a mut QueryRef> { +impl Caps { pub fn set_result(&mut self, caps: &::Caps) { unsafe { - ffi::gst_query_set_caps_result(self.as_mut_ptr(), caps.as_mut_ptr()); + ffi::gst_query_set_caps_result(self.0.as_mut_ptr(), caps.as_mut_ptr()); } } } @@ -962,11 +1070,11 @@ impl<'a> Caps<&'a mut QueryRef> { declare_concrete_query!(Drain, T); declare_concrete_query!(Context, T); -impl<'a> Context<&'a QueryRef> { +impl Context { pub fn get_context(&self) -> Option<&::ContextRef> { unsafe { let mut context = ptr::null_mut(); - ffi::gst_query_parse_context(self.as_mut_ptr(), &mut context); + ffi::gst_query_parse_context(self.0.as_ptr(), &mut context); if context.is_null() { None } else { @@ -978,16 +1086,16 @@ impl<'a> Context<&'a QueryRef> { pub fn get_context_type(&self) -> &str { unsafe { let mut context_type = ptr::null(); - ffi::gst_query_parse_context_type(self.as_mut_ptr(), &mut context_type); + ffi::gst_query_parse_context_type(self.0.as_ptr(), &mut context_type); CStr::from_ptr(context_type).to_str().unwrap() } } } -impl<'a> Context<&'a mut QueryRef> { +impl Context { pub fn set_context(&mut self, context: &::Context) { unsafe { - ffi::gst_query_set_context(self.as_mut_ptr(), context.as_mut_ptr()); + ffi::gst_query_set_context(self.0.as_mut_ptr(), context.as_mut_ptr()); } } } @@ -1002,32 +1110,82 @@ mod tests { fn test_writability() { ::init().unwrap(); - let mut q = Query::new_position(::Format::Time); - - match q.view() { - QueryView::Position(ref p) => { - let fmt = p.get_format(); - assert_eq!(fmt, ::Format::Time); - assert!(!p.is_serialized()); + fn check_mut(query: &mut QueryRef) { + match query.view_mut() { + QueryView::Position(ref mut p) => { + let pos = p.get_result(); + assert_eq!(pos.try_into_time(), Ok(::CLOCK_TIME_NONE)); + p.set(3 * ::SECOND); + let pos = p.get_result(); + assert_eq!(pos.try_into_time(), Ok(3 * ::SECOND)); + } + _ => panic!("Wrong concrete Query in Query"), } + } + + fn check_ref(query: &QueryRef) { + match query.view() { + QueryView::Position(ref p) => { + let pos = p.get_result(); + assert_eq!(pos.try_into_time(), Ok(3 * ::SECOND)); + unsafe { assert!(!p.as_mut_ptr().is_null()); } + } + _ => panic!("Wrong concrete Query in Query"), + } + } + + let mut p = Query::new_position(::Format::Time); + let pos = p.get_result(); + assert_eq!(pos.try_into_time(), Ok(::CLOCK_TIME_NONE)); + + p.get_mut_structure().set("check_mut", &true); + + // deref + assert!(!p.is_serialized()); + + { + check_mut(&mut p); + + let structure = p.get_structure(); + structure.unwrap().has_field("check_mut"); + + // Expected: cannot borrow `p` as mutable because it is also borrowed as immutable + //check_mut(&mut p); + } + + check_ref(&p); + } + + #[test] + fn test_into_query() { + ::init().unwrap(); + let d = Query::new_duration(::Format::Time); + + let mut query: Query = d.into(); + assert!(query.is_writable()); + + let query = query.make_mut(); + match query.view_mut() { + QueryView::Duration(ref mut d) => { + d.set(2 * ::SECOND); + }, _ => (), } - match q.get_mut().unwrap().view_mut() { - QueryView::Position(ref mut p) => { - let pos = p.get_result(); - assert_eq!(pos.try_into_time(), Ok(::CLOCK_TIME_NONE)); - p.set(2 * ::SECOND); - } - _ => (), - } - - match q.view() { - QueryView::Position(ref p) => { - let pos = p.get_result(); - assert_eq!(pos.try_into_time(), Ok(2 * ::SECOND)); - } + match query.view() { + QueryView::Duration(ref d) => { + let duration = d.get_result(); + assert_eq!(duration.try_into_time(), Ok(2 * ::SECOND)); + }, _ => (), } } + + #[test] + fn test_concrete_to_ffi() { + ::init().unwrap(); + + let p = Query::new_position(::Format::Time); + unsafe { assert!(!p.as_mut_ptr().is_null()); } + } } diff --git a/tutorials/src/bin/basic-tutorial-4.rs b/tutorials/src/bin/basic-tutorial-4.rs index ecaeaa7a2..6a5f35492 100644 --- a/tutorials/src/bin/basic-tutorial-4.rs +++ b/tutorials/src/bin/basic-tutorial-4.rs @@ -128,19 +128,14 @@ fn handle_message(custom_data: &mut CustomData, msg: &gst::GstRc { - let (seekable, start, end) = seek.get_result(); - custom_data.seek_enabled = seekable; - if seekable { - println!("Seeking is ENABLED from {:?} to {:?}", start, end) - } else { - println!("Seeking is DISABLED for this stream.") - } - } - _ => unreachable!(), + let mut seeking = gst::Query::new_seeking(gst::Format::Time); + if custom_data.playbin.query(&mut seeking) { + let (seekable, start, end) = seeking.get_result(); + custom_data.seek_enabled = seekable; + if seekable { + println!("Seeking is ENABLED from {:?} to {:?}", start, end) + } else { + println!("Seeking is DISABLED for this stream.") } } else { eprintln!("Seeking query failed.")