1 // Copyright (C) 2016-2017 Sebastian Dröge <sebastian@centricular.com>
2 //
3 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6 // option. This file may not be copied, modified, or distributed
7 // except according to those terms.
8 
9 use gst_sys;
10 use miniobject::*;
11 use structure::*;
12 use GenericFormattedValue;
13 
14 use std::ffi::CStr;
15 use std::fmt;
16 use std::mem;
17 use std::ops::{Deref, DerefMut};
18 use std::ptr;
19 
20 use glib;
21 use glib::translate::*;
22 use glib_sys;
23 
24 gst_define_mini_object_wrapper!(Query, QueryRef, gst_sys::GstQuery, [Debug,], || {
25     gst_sys::gst_query_get_type()
26 });
27 
28 impl Query {
new_position(fmt: ::Format) -> Position<Self>29     pub fn new_position(fmt: ::Format) -> Position<Self> {
30         assert_initialized_main_thread!();
31         unsafe {
32             Position::<Self>(from_glib_full(gst_sys::gst_query_new_position(
33                 fmt.to_glib(),
34             )))
35         }
36     }
37 
new_duration(fmt: ::Format) -> Duration<Self>38     pub fn new_duration(fmt: ::Format) -> Duration<Self> {
39         assert_initialized_main_thread!();
40         unsafe {
41             Duration::<Self>(from_glib_full(gst_sys::gst_query_new_duration(
42                 fmt.to_glib(),
43             )))
44         }
45     }
46 
new_latency() -> Latency<Self>47     pub fn new_latency() -> Latency<Self> {
48         assert_initialized_main_thread!();
49         unsafe { Latency::<Self>(from_glib_full(gst_sys::gst_query_new_latency())) }
50     }
51 
new_seeking(fmt: ::Format) -> Seeking<Self>52     pub fn new_seeking(fmt: ::Format) -> Seeking<Self> {
53         assert_initialized_main_thread!();
54         unsafe {
55             Seeking::<Self>(from_glib_full(gst_sys::gst_query_new_seeking(
56                 fmt.to_glib(),
57             )))
58         }
59     }
60 
new_segment(fmt: ::Format) -> Segment<Self>61     pub fn new_segment(fmt: ::Format) -> Segment<Self> {
62         assert_initialized_main_thread!();
63         unsafe {
64             Segment::<Self>(from_glib_full(gst_sys::gst_query_new_segment(
65                 fmt.to_glib(),
66             )))
67         }
68     }
69 
new_convert<V: Into<GenericFormattedValue>>( value: V, dest_fmt: ::Format, ) -> Convert<Self>70     pub fn new_convert<V: Into<GenericFormattedValue>>(
71         value: V,
72         dest_fmt: ::Format,
73     ) -> Convert<Self> {
74         assert_initialized_main_thread!();
75         let value = value.into();
76         unsafe {
77             Convert::<Self>(from_glib_full(gst_sys::gst_query_new_convert(
78                 value.get_format().to_glib(),
79                 value.get_value(),
80                 dest_fmt.to_glib(),
81             )))
82         }
83     }
84 
new_formats() -> Formats<Self>85     pub fn new_formats() -> Formats<Self> {
86         assert_initialized_main_thread!();
87         unsafe { Formats::<Self>(from_glib_full(gst_sys::gst_query_new_formats())) }
88     }
89 
new_buffering(fmt: ::Format) -> Buffering<Self>90     pub fn new_buffering(fmt: ::Format) -> Buffering<Self> {
91         assert_initialized_main_thread!();
92         unsafe {
93             Buffering::<Self>(from_glib_full(gst_sys::gst_query_new_buffering(
94                 fmt.to_glib(),
95             )))
96         }
97     }
98 
new_custom(structure: ::Structure) -> Custom<Self>99     pub fn new_custom(structure: ::Structure) -> Custom<Self> {
100         assert_initialized_main_thread!();
101         unsafe {
102             Custom::<Self>(from_glib_full(gst_sys::gst_query_new_custom(
103                 gst_sys::GST_QUERY_CUSTOM,
104                 structure.into_ptr(),
105             )))
106         }
107     }
108 
new_uri() -> Uri<Self>109     pub fn new_uri() -> Uri<Self> {
110         assert_initialized_main_thread!();
111         unsafe { Uri::<Self>(from_glib_full(gst_sys::gst_query_new_uri())) }
112     }
113 
new_allocation(caps: &::Caps, need_pool: bool) -> Allocation<Self>114     pub fn new_allocation(caps: &::Caps, need_pool: bool) -> Allocation<Self> {
115         assert_initialized_main_thread!();
116         unsafe {
117             Allocation::<Self>(from_glib_full(gst_sys::gst_query_new_allocation(
118                 caps.as_mut_ptr(),
119                 need_pool.to_glib(),
120             )))
121         }
122     }
123 
new_scheduling() -> Scheduling<Self>124     pub fn new_scheduling() -> Scheduling<Self> {
125         assert_initialized_main_thread!();
126         unsafe { Scheduling::<Self>(from_glib_full(gst_sys::gst_query_new_scheduling())) }
127     }
128 
new_accept_caps(caps: &::Caps) -> AcceptCaps<Self>129     pub fn new_accept_caps(caps: &::Caps) -> AcceptCaps<Self> {
130         assert_initialized_main_thread!();
131         unsafe {
132             AcceptCaps::<Self>(from_glib_full(gst_sys::gst_query_new_accept_caps(
133                 caps.as_mut_ptr(),
134             )))
135         }
136     }
137 
new_caps(filter: Option<&::Caps>) -> Caps<Self>138     pub fn new_caps(filter: Option<&::Caps>) -> Caps<Self> {
139         assert_initialized_main_thread!();
140         unsafe {
141             Caps::<Self>(from_glib_full(gst_sys::gst_query_new_caps(
142                 filter.to_glib_none().0,
143             )))
144         }
145     }
146 
new_drain() -> Drain<Self>147     pub fn new_drain() -> Drain<Self> {
148         assert_initialized_main_thread!();
149         unsafe { Drain::<Self>(from_glib_full(gst_sys::gst_query_new_drain())) }
150     }
151 
new_context(context_type: &str) -> Context<Self>152     pub fn new_context(context_type: &str) -> Context<Self> {
153         assert_initialized_main_thread!();
154         unsafe {
155             Context::<Self>(from_glib_full(gst_sys::gst_query_new_context(
156                 context_type.to_glib_none().0,
157             )))
158         }
159     }
160 
161     #[cfg(any(feature = "v1_16", feature = "dox"))]
new_bitrate() -> Bitrate<Self>162     pub fn new_bitrate() -> Bitrate<Self> {
163         assert_initialized_main_thread!();
164         unsafe { Bitrate::<Self>(from_glib_full(gst_sys::gst_query_new_bitrate())) }
165     }
166 }
167 
168 impl QueryRef {
get_structure(&self) -> Option<&StructureRef>169     pub fn get_structure(&self) -> Option<&StructureRef> {
170         unsafe {
171             let structure = gst_sys::gst_query_get_structure(self.as_mut_ptr());
172             if structure.is_null() {
173                 None
174             } else {
175                 Some(StructureRef::from_glib_borrow(structure))
176             }
177         }
178     }
179 
get_mut_structure(&mut self) -> &mut StructureRef180     pub fn get_mut_structure(&mut self) -> &mut StructureRef {
181         unsafe {
182             let structure = gst_sys::gst_query_writable_structure(self.as_mut_ptr());
183             StructureRef::from_glib_borrow_mut(structure)
184         }
185     }
186 
is_downstream(&self) -> bool187     pub fn is_downstream(&self) -> bool {
188         unsafe { ((*self.as_ptr()).type_ as u32) & gst_sys::GST_QUERY_TYPE_DOWNSTREAM != 0 }
189     }
190 
is_upstream(&self) -> bool191     pub fn is_upstream(&self) -> bool {
192         unsafe { ((*self.as_ptr()).type_ as u32) & gst_sys::GST_QUERY_TYPE_UPSTREAM != 0 }
193     }
194 
is_serialized(&self) -> bool195     pub fn is_serialized(&self) -> bool {
196         unsafe { ((*self.as_ptr()).type_ as u32) & gst_sys::GST_QUERY_TYPE_SERIALIZED != 0 }
197     }
198 
view(&self) -> QueryView<&Self>199     pub fn view(&self) -> QueryView<&Self> {
200         let type_ = unsafe { (*self.as_ptr()).type_ };
201 
202         match type_ {
203             gst_sys::GST_QUERY_POSITION => QueryView::Position(Position(self)),
204             gst_sys::GST_QUERY_DURATION => QueryView::Duration(Duration(self)),
205             gst_sys::GST_QUERY_LATENCY => QueryView::Latency(Latency(self)),
206             gst_sys::GST_QUERY_JITTER => QueryView::Jitter(Jitter(self)),
207             gst_sys::GST_QUERY_RATE => QueryView::Rate(Rate(self)),
208             gst_sys::GST_QUERY_SEEKING => QueryView::Seeking(Seeking(self)),
209             gst_sys::GST_QUERY_SEGMENT => QueryView::Segment(Segment(self)),
210             gst_sys::GST_QUERY_CONVERT => QueryView::Convert(Convert(self)),
211             gst_sys::GST_QUERY_FORMATS => QueryView::Formats(Formats(self)),
212             gst_sys::GST_QUERY_BUFFERING => QueryView::Buffering(Buffering(self)),
213             gst_sys::GST_QUERY_CUSTOM => QueryView::Custom(Custom(self)),
214             gst_sys::GST_QUERY_URI => QueryView::Uri(Uri(self)),
215             gst_sys::GST_QUERY_ALLOCATION => QueryView::Allocation(Allocation(self)),
216             gst_sys::GST_QUERY_SCHEDULING => QueryView::Scheduling(Scheduling(self)),
217             gst_sys::GST_QUERY_ACCEPT_CAPS => QueryView::AcceptCaps(AcceptCaps(self)),
218             gst_sys::GST_QUERY_CAPS => QueryView::Caps(Caps(self)),
219             gst_sys::GST_QUERY_DRAIN => QueryView::Drain(Drain(self)),
220             gst_sys::GST_QUERY_CONTEXT => QueryView::Context(Context(self)),
221             gst_sys::GST_QUERY_BITRATE => QueryView::Bitrate(Bitrate(self)),
222             _ => QueryView::Other(Other(self)),
223         }
224     }
225 
view_mut(&mut self) -> QueryView<&mut Self>226     pub fn view_mut(&mut self) -> QueryView<&mut Self> {
227         unsafe { mem::transmute(self.view()) }
228     }
229 }
230 
231 impl fmt::Debug for QueryRef {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result232     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
233         f.debug_struct("Query")
234             .field("ptr", unsafe { &self.as_ptr() })
235             .field("type", &unsafe {
236                 let type_ = gst_sys::gst_query_type_get_name((*self.as_ptr()).type_);
237                 CStr::from_ptr(type_).to_str().unwrap()
238             })
239             .field("structure", &self.get_structure())
240             .finish()
241     }
242 }
243 
244 pub unsafe trait AsPtr {
as_ptr(&self) -> *mut gst_sys::GstQuery245     unsafe fn as_ptr(&self) -> *mut gst_sys::GstQuery;
246 }
247 
248 pub unsafe trait AsMutPtr: AsPtr {
as_mut_ptr(&self) -> *mut gst_sys::GstQuery249     unsafe fn as_mut_ptr(&self) -> *mut gst_sys::GstQuery;
250 }
251 
252 unsafe impl AsPtr for Query {
as_ptr(&self) -> *mut gst_sys::GstQuery253     unsafe fn as_ptr(&self) -> *mut gst_sys::GstQuery {
254         self.as_ref().as_ptr() as *mut gst_sys::GstQuery
255     }
256 }
257 
258 unsafe impl AsMutPtr for Query {
as_mut_ptr(&self) -> *mut gst_sys::GstQuery259     unsafe fn as_mut_ptr(&self) -> *mut gst_sys::GstQuery {
260         self.as_ref().as_mut_ptr()
261     }
262 }
263 
264 unsafe impl<'a> AsPtr for &'a QueryRef {
as_ptr(&self) -> *mut gst_sys::GstQuery265     unsafe fn as_ptr(&self) -> *mut gst_sys::GstQuery {
266         MiniObject::as_ptr(self as &QueryRef) as *mut gst_sys::GstQuery
267     }
268 }
269 
270 unsafe impl<'a> AsPtr for &'a mut QueryRef {
as_ptr(&self) -> *mut gst_sys::GstQuery271     unsafe fn as_ptr(&self) -> *mut gst_sys::GstQuery {
272         MiniObject::as_ptr(self as &QueryRef) as *mut gst_sys::GstQuery
273     }
274 }
275 
276 unsafe impl<'a> AsMutPtr for &'a mut QueryRef {
as_mut_ptr(&self) -> *mut gst_sys::GstQuery277     unsafe fn as_mut_ptr(&self) -> *mut gst_sys::GstQuery {
278         MiniObject::as_mut_ptr(self as &QueryRef) as *mut gst_sys::GstQuery
279     }
280 }
281 
282 #[derive(Debug)]
283 pub enum QueryView<T> {
284     Position(Position<T>),
285     Duration(Duration<T>),
286     Latency(Latency<T>),
287     Jitter(Jitter<T>),
288     Rate(Rate<T>),
289     Seeking(Seeking<T>),
290     Segment(Segment<T>),
291     Convert(Convert<T>),
292     Formats(Formats<T>),
293     Buffering(Buffering<T>),
294     Custom(Custom<T>),
295     Uri(Uri<T>),
296     Allocation(Allocation<T>),
297     Scheduling(Scheduling<T>),
298     AcceptCaps(AcceptCaps<T>),
299     Caps(Caps<T>),
300     Drain(Drain<T>),
301     Context(Context<T>),
302     Bitrate(Bitrate<T>),
303     Other(Other<T>),
304     __NonExhaustive,
305 }
306 
307 macro_rules! declare_concrete_query(
308     ($name:ident, $param:ident) => {
309         #[derive(Debug)]
310         pub struct $name<$param>($param);
311 
312         impl<'a> $name<&'a QueryRef> {
313             pub fn get_query(&self) -> &QueryRef {
314                 self.0
315             }
316         }
317 
318         impl<'a> Deref for $name<&'a QueryRef> {
319             type Target = QueryRef;
320 
321             fn deref(&self) -> &Self::Target {
322                 self.0
323             }
324         }
325 
326         impl<'a> Deref for $name<&'a mut QueryRef> {
327             type Target = $name<&'a QueryRef>;
328 
329             fn deref(&self) -> &Self::Target {
330                 unsafe {
331                     &*(self as *const $name<&'a mut QueryRef> as *const $name<&'a QueryRef>)
332                 }
333             }
334         }
335 
336         impl<'a> $name<&'a mut QueryRef> {
337             pub fn get_mut_query(&mut self) -> &mut QueryRef {
338                 self.0
339             }
340         }
341 
342         impl Deref for $name<Query> {
343             type Target = QueryRef;
344 
345             fn deref(&self) -> &Self::Target {
346                 &self.0
347             }
348         }
349 
350         impl DerefMut for $name<Query> {
351             fn deref_mut(&mut self) -> &mut Self::Target {
352                 self.0.get_mut().unwrap()
353             }
354         }
355 
356         impl From<$name<Query>> for Query {
357             fn from(concrete: $name<Query>) -> Self {
358                 unsafe { from_glib_none(concrete.0.as_mut_ptr()) }
359             }
360         }
361     }
362 );
363 
364 declare_concrete_query!(Position, T);
365 impl<T: AsPtr> Position<T> {
get_result(&self) -> GenericFormattedValue366     pub fn get_result(&self) -> GenericFormattedValue {
367         unsafe {
368             let mut fmt = mem::MaybeUninit::uninit();
369             let mut pos = mem::MaybeUninit::uninit();
370 
371             gst_sys::gst_query_parse_position(self.0.as_ptr(), fmt.as_mut_ptr(), pos.as_mut_ptr());
372 
373             GenericFormattedValue::new(from_glib(fmt.assume_init()), pos.assume_init())
374         }
375     }
376 
get_format(&self) -> ::Format377     pub fn get_format(&self) -> ::Format {
378         unsafe {
379             let mut fmt = mem::MaybeUninit::uninit();
380 
381             gst_sys::gst_query_parse_position(self.0.as_ptr(), fmt.as_mut_ptr(), ptr::null_mut());
382 
383             from_glib(fmt.assume_init())
384         }
385     }
386 }
387 
388 impl<T: AsMutPtr> Position<T> {
set<V: Into<GenericFormattedValue>>(&mut self, pos: V)389     pub fn set<V: Into<GenericFormattedValue>>(&mut self, pos: V) {
390         let pos = pos.into();
391         assert_eq!(pos.get_format(), self.get_format());
392         unsafe {
393             gst_sys::gst_query_set_position(
394                 self.0.as_mut_ptr(),
395                 pos.get_format().to_glib(),
396                 pos.get_value(),
397             );
398         }
399     }
400 }
401 
402 declare_concrete_query!(Duration, T);
403 impl<T: AsPtr> Duration<T> {
get_result(&self) -> GenericFormattedValue404     pub fn get_result(&self) -> GenericFormattedValue {
405         unsafe {
406             let mut fmt = mem::MaybeUninit::uninit();
407             let mut pos = mem::MaybeUninit::uninit();
408 
409             gst_sys::gst_query_parse_duration(self.0.as_ptr(), fmt.as_mut_ptr(), pos.as_mut_ptr());
410 
411             GenericFormattedValue::new(from_glib(fmt.assume_init()), pos.assume_init())
412         }
413     }
414 
get_format(&self) -> ::Format415     pub fn get_format(&self) -> ::Format {
416         unsafe {
417             let mut fmt = mem::MaybeUninit::uninit();
418 
419             gst_sys::gst_query_parse_duration(self.0.as_ptr(), fmt.as_mut_ptr(), ptr::null_mut());
420 
421             from_glib(fmt.assume_init())
422         }
423     }
424 }
425 
426 impl<T: AsMutPtr> Duration<T> {
set<V: Into<GenericFormattedValue>>(&mut self, dur: V)427     pub fn set<V: Into<GenericFormattedValue>>(&mut self, dur: V) {
428         let dur = dur.into();
429         assert_eq!(dur.get_format(), self.get_format());
430         unsafe {
431             gst_sys::gst_query_set_duration(
432                 self.0.as_mut_ptr(),
433                 dur.get_format().to_glib(),
434                 dur.get_value(),
435             );
436         }
437     }
438 }
439 
440 declare_concrete_query!(Latency, T);
441 impl<T: AsPtr> Latency<T> {
get_result(&self) -> (bool, ::ClockTime, ::ClockTime)442     pub fn get_result(&self) -> (bool, ::ClockTime, ::ClockTime) {
443         unsafe {
444             let mut live = mem::MaybeUninit::uninit();
445             let mut min = mem::MaybeUninit::uninit();
446             let mut max = mem::MaybeUninit::uninit();
447 
448             gst_sys::gst_query_parse_latency(
449                 self.0.as_ptr(),
450                 live.as_mut_ptr(),
451                 min.as_mut_ptr(),
452                 max.as_mut_ptr(),
453             );
454 
455             (
456                 from_glib(live.assume_init()),
457                 from_glib(min.assume_init()),
458                 from_glib(max.assume_init()),
459             )
460         }
461     }
462 }
463 
464 impl<T: AsMutPtr> Latency<T> {
set(&mut self, live: bool, min: ::ClockTime, max: ::ClockTime)465     pub fn set(&mut self, live: bool, min: ::ClockTime, max: ::ClockTime) {
466         unsafe {
467             gst_sys::gst_query_set_latency(
468                 self.0.as_mut_ptr(),
469                 live.to_glib(),
470                 min.to_glib(),
471                 max.to_glib(),
472             );
473         }
474     }
475 }
476 
477 declare_concrete_query!(Jitter, T);
478 declare_concrete_query!(Rate, T);
479 
480 declare_concrete_query!(Seeking, T);
481 impl<T: AsPtr> Seeking<T> {
get_result(&self) -> (bool, GenericFormattedValue, GenericFormattedValue)482     pub fn get_result(&self) -> (bool, GenericFormattedValue, GenericFormattedValue) {
483         unsafe {
484             let mut fmt = mem::MaybeUninit::uninit();
485             let mut seekable = mem::MaybeUninit::uninit();
486             let mut start = mem::MaybeUninit::uninit();
487             let mut end = mem::MaybeUninit::uninit();
488             gst_sys::gst_query_parse_seeking(
489                 self.0.as_ptr(),
490                 fmt.as_mut_ptr(),
491                 seekable.as_mut_ptr(),
492                 start.as_mut_ptr(),
493                 end.as_mut_ptr(),
494             );
495 
496             (
497                 from_glib(seekable.assume_init()),
498                 GenericFormattedValue::new(from_glib(fmt.assume_init()), start.assume_init()),
499                 GenericFormattedValue::new(from_glib(fmt.assume_init()), end.assume_init()),
500             )
501         }
502     }
503 
get_format(&self) -> ::Format504     pub fn get_format(&self) -> ::Format {
505         unsafe {
506             let mut fmt = mem::MaybeUninit::uninit();
507             gst_sys::gst_query_parse_seeking(
508                 self.0.as_ptr(),
509                 fmt.as_mut_ptr(),
510                 ptr::null_mut(),
511                 ptr::null_mut(),
512                 ptr::null_mut(),
513             );
514 
515             from_glib(fmt.assume_init())
516         }
517     }
518 }
519 
520 impl<T: AsMutPtr> Seeking<T> {
set<V: Into<GenericFormattedValue>>(&mut self, seekable: bool, start: V, end: V)521     pub fn set<V: Into<GenericFormattedValue>>(&mut self, seekable: bool, start: V, end: V) {
522         let start = start.into();
523         let end = end.into();
524 
525         assert_eq!(self.get_format(), start.get_format());
526         assert_eq!(start.get_format(), end.get_format());
527 
528         unsafe {
529             gst_sys::gst_query_set_seeking(
530                 self.0.as_mut_ptr(),
531                 start.get_format().to_glib(),
532                 seekable.to_glib(),
533                 start.get_value(),
534                 end.get_value(),
535             );
536         }
537     }
538 }
539 
540 declare_concrete_query!(Segment, T);
541 impl<T: AsPtr> Segment<T> {
get_result(&self) -> (f64, GenericFormattedValue, GenericFormattedValue)542     pub fn get_result(&self) -> (f64, GenericFormattedValue, GenericFormattedValue) {
543         unsafe {
544             let mut rate = mem::MaybeUninit::uninit();
545             let mut fmt = mem::MaybeUninit::uninit();
546             let mut start = mem::MaybeUninit::uninit();
547             let mut stop = mem::MaybeUninit::uninit();
548 
549             gst_sys::gst_query_parse_segment(
550                 self.0.as_ptr(),
551                 rate.as_mut_ptr(),
552                 fmt.as_mut_ptr(),
553                 start.as_mut_ptr(),
554                 stop.as_mut_ptr(),
555             );
556             (
557                 rate.assume_init(),
558                 GenericFormattedValue::new(from_glib(fmt.assume_init()), start.assume_init()),
559                 GenericFormattedValue::new(from_glib(fmt.assume_init()), stop.assume_init()),
560             )
561         }
562     }
563 
get_format(&self) -> ::Format564     pub fn get_format(&self) -> ::Format {
565         unsafe {
566             let mut fmt = mem::MaybeUninit::uninit();
567 
568             gst_sys::gst_query_parse_segment(
569                 self.0.as_ptr(),
570                 ptr::null_mut(),
571                 fmt.as_mut_ptr(),
572                 ptr::null_mut(),
573                 ptr::null_mut(),
574             );
575             from_glib(fmt.assume_init())
576         }
577     }
578 }
579 
580 impl<T: AsMutPtr> Segment<T> {
set<V: Into<GenericFormattedValue>>(&mut self, rate: f64, start: V, stop: V)581     pub fn set<V: Into<GenericFormattedValue>>(&mut self, rate: f64, start: V, stop: V) {
582         let start = start.into();
583         let stop = stop.into();
584 
585         assert_eq!(start.get_format(), stop.get_format());
586 
587         unsafe {
588             gst_sys::gst_query_set_segment(
589                 self.0.as_mut_ptr(),
590                 rate,
591                 start.get_format().to_glib(),
592                 start.get_value(),
593                 stop.get_value(),
594             );
595         }
596     }
597 }
598 
599 declare_concrete_query!(Convert, T);
600 impl<T: AsPtr> Convert<T> {
get_result(&self) -> (GenericFormattedValue, GenericFormattedValue)601     pub fn get_result(&self) -> (GenericFormattedValue, GenericFormattedValue) {
602         unsafe {
603             let mut src_fmt = mem::MaybeUninit::uninit();
604             let mut src = mem::MaybeUninit::uninit();
605             let mut dest_fmt = mem::MaybeUninit::uninit();
606             let mut dest = mem::MaybeUninit::uninit();
607 
608             gst_sys::gst_query_parse_convert(
609                 self.0.as_ptr(),
610                 src_fmt.as_mut_ptr(),
611                 src.as_mut_ptr(),
612                 dest_fmt.as_mut_ptr(),
613                 dest.as_mut_ptr(),
614             );
615             (
616                 GenericFormattedValue::new(from_glib(src_fmt.assume_init()), src.assume_init()),
617                 GenericFormattedValue::new(from_glib(dest_fmt.assume_init()), dest.assume_init()),
618             )
619         }
620     }
621 
get(&self) -> (GenericFormattedValue, ::Format)622     pub fn get(&self) -> (GenericFormattedValue, ::Format) {
623         unsafe {
624             let mut src_fmt = mem::MaybeUninit::uninit();
625             let mut src = mem::MaybeUninit::uninit();
626             let mut dest_fmt = mem::MaybeUninit::uninit();
627 
628             gst_sys::gst_query_parse_convert(
629                 self.0.as_ptr(),
630                 src_fmt.as_mut_ptr(),
631                 src.as_mut_ptr(),
632                 dest_fmt.as_mut_ptr(),
633                 ptr::null_mut(),
634             );
635             (
636                 GenericFormattedValue::new(from_glib(src_fmt.assume_init()), src.assume_init()),
637                 from_glib(dest_fmt.assume_init()),
638             )
639         }
640     }
641 }
642 
643 impl<T: AsMutPtr> Convert<T> {
set<V: Into<GenericFormattedValue>>(&mut self, src: V, dest: V)644     pub fn set<V: Into<GenericFormattedValue>>(&mut self, src: V, dest: V) {
645         let src = src.into();
646         let dest = dest.into();
647 
648         unsafe {
649             gst_sys::gst_query_set_convert(
650                 self.0.as_mut_ptr(),
651                 src.get_format().to_glib(),
652                 src.get_value(),
653                 dest.get_format().to_glib(),
654                 dest.get_value(),
655             );
656         }
657     }
658 }
659 
660 declare_concrete_query!(Formats, T);
661 impl<T: AsPtr> Formats<T> {
get_result(&self) -> Vec<::Format>662     pub fn get_result(&self) -> Vec<::Format> {
663         unsafe {
664             let mut n = mem::MaybeUninit::uninit();
665             gst_sys::gst_query_parse_n_formats(self.0.as_ptr(), n.as_mut_ptr());
666             let n = n.assume_init();
667             let mut res = Vec::with_capacity(n as usize);
668 
669             for i in 0..n {
670                 let mut fmt = mem::MaybeUninit::uninit();
671                 gst_sys::gst_query_parse_nth_format(self.0.as_ptr(), i, fmt.as_mut_ptr());
672                 res.push(from_glib(fmt.assume_init()));
673             }
674 
675             res
676         }
677     }
678 }
679 
680 impl<T: AsMutPtr> Formats<T> {
set(&mut self, formats: &[::Format])681     pub fn set(&mut self, formats: &[::Format]) {
682         unsafe {
683             let v: Vec<_> = formats.iter().map(|f| f.to_glib()).collect();
684             gst_sys::gst_query_set_formatsv(
685                 self.0.as_mut_ptr(),
686                 v.len() as i32,
687                 v.as_ptr() as *mut _,
688             );
689         }
690     }
691 }
692 
693 declare_concrete_query!(Buffering, T);
694 impl<T: AsPtr> Buffering<T> {
get_format(&self) -> ::Format695     pub fn get_format(&self) -> ::Format {
696         unsafe {
697             let mut fmt = mem::MaybeUninit::uninit();
698 
699             gst_sys::gst_query_parse_buffering_range(
700                 self.0.as_ptr(),
701                 fmt.as_mut_ptr(),
702                 ptr::null_mut(),
703                 ptr::null_mut(),
704                 ptr::null_mut(),
705             );
706 
707             from_glib(fmt.assume_init())
708         }
709     }
710 
get_percent(&self) -> (bool, i32)711     pub fn get_percent(&self) -> (bool, i32) {
712         unsafe {
713             let mut busy = mem::MaybeUninit::uninit();
714             let mut percent = mem::MaybeUninit::uninit();
715 
716             gst_sys::gst_query_parse_buffering_percent(
717                 self.0.as_ptr(),
718                 busy.as_mut_ptr(),
719                 percent.as_mut_ptr(),
720             );
721 
722             (from_glib(busy.assume_init()), percent.assume_init())
723         }
724     }
725 
get_range(&self) -> (GenericFormattedValue, GenericFormattedValue, i64)726     pub fn get_range(&self) -> (GenericFormattedValue, GenericFormattedValue, i64) {
727         unsafe {
728             let mut fmt = mem::MaybeUninit::uninit();
729             let mut start = mem::MaybeUninit::uninit();
730             let mut stop = mem::MaybeUninit::uninit();
731             let mut estimated_total = mem::MaybeUninit::uninit();
732 
733             gst_sys::gst_query_parse_buffering_range(
734                 self.0.as_ptr(),
735                 fmt.as_mut_ptr(),
736                 start.as_mut_ptr(),
737                 stop.as_mut_ptr(),
738                 estimated_total.as_mut_ptr(),
739             );
740             (
741                 GenericFormattedValue::new(from_glib(fmt.assume_init()), start.assume_init()),
742                 GenericFormattedValue::new(from_glib(fmt.assume_init()), stop.assume_init()),
743                 estimated_total.assume_init(),
744             )
745         }
746     }
747 
get_stats(&self) -> (::BufferingMode, i32, i32, i64)748     pub fn get_stats(&self) -> (::BufferingMode, i32, i32, i64) {
749         unsafe {
750             let mut mode = mem::MaybeUninit::uninit();
751             let mut avg_in = mem::MaybeUninit::uninit();
752             let mut avg_out = mem::MaybeUninit::uninit();
753             let mut buffering_left = mem::MaybeUninit::uninit();
754 
755             gst_sys::gst_query_parse_buffering_stats(
756                 self.0.as_ptr(),
757                 mode.as_mut_ptr(),
758                 avg_in.as_mut_ptr(),
759                 avg_out.as_mut_ptr(),
760                 buffering_left.as_mut_ptr(),
761             );
762 
763             (
764                 from_glib(mode.assume_init()),
765                 avg_in.assume_init(),
766                 avg_out.assume_init(),
767                 buffering_left.assume_init(),
768             )
769         }
770     }
771 
get_ranges(&self) -> Vec<(GenericFormattedValue, GenericFormattedValue)>772     pub fn get_ranges(&self) -> Vec<(GenericFormattedValue, GenericFormattedValue)> {
773         unsafe {
774             let mut fmt = mem::MaybeUninit::uninit();
775             gst_sys::gst_query_parse_buffering_range(
776                 self.0.as_ptr(),
777                 fmt.as_mut_ptr(),
778                 ptr::null_mut(),
779                 ptr::null_mut(),
780                 ptr::null_mut(),
781             );
782             let fmt = from_glib(fmt.assume_init());
783 
784             let n = gst_sys::gst_query_get_n_buffering_ranges(self.0.as_ptr());
785             let mut res = Vec::with_capacity(n as usize);
786             for i in 0..n {
787                 let mut start = mem::MaybeUninit::uninit();
788                 let mut stop = mem::MaybeUninit::uninit();
789                 let s: bool = from_glib(gst_sys::gst_query_parse_nth_buffering_range(
790                     self.0.as_ptr(),
791                     i,
792                     start.as_mut_ptr(),
793                     stop.as_mut_ptr(),
794                 ));
795                 if s {
796                     res.push((
797                         GenericFormattedValue::new(fmt, start.assume_init()),
798                         GenericFormattedValue::new(fmt, stop.assume_init()),
799                     ));
800                 }
801             }
802 
803             res
804         }
805     }
806 }
807 
808 impl<T: AsMutPtr> Buffering<T> {
set_percent(&mut self, busy: bool, percent: i32)809     pub fn set_percent(&mut self, busy: bool, percent: i32) {
810         unsafe {
811             gst_sys::gst_query_set_buffering_percent(self.0.as_mut_ptr(), busy.to_glib(), percent);
812         }
813     }
814 
set_range<V: Into<GenericFormattedValue>>( &mut self, start: V, stop: V, estimated_total: i64, )815     pub fn set_range<V: Into<GenericFormattedValue>>(
816         &mut self,
817         start: V,
818         stop: V,
819         estimated_total: i64,
820     ) {
821         let start = start.into();
822         let stop = stop.into();
823 
824         assert_eq!(self.get_format(), start.get_format());
825         assert_eq!(start.get_format(), stop.get_format());
826 
827         unsafe {
828             gst_sys::gst_query_set_buffering_range(
829                 self.0.as_mut_ptr(),
830                 start.get_format().to_glib(),
831                 start.get_value(),
832                 stop.get_value(),
833                 estimated_total,
834             );
835         }
836     }
837 
set_stats( &mut self, mode: ::BufferingMode, avg_in: i32, avg_out: i32, buffering_left: i64, )838     pub fn set_stats(
839         &mut self,
840         mode: ::BufferingMode,
841         avg_in: i32,
842         avg_out: i32,
843         buffering_left: i64,
844     ) {
845         skip_assert_initialized!();
846         unsafe {
847             gst_sys::gst_query_set_buffering_stats(
848                 self.0.as_mut_ptr(),
849                 mode.to_glib(),
850                 avg_in,
851                 avg_out,
852                 buffering_left,
853             );
854         }
855     }
856 
add_buffering_ranges<V: Into<GenericFormattedValue> + Copy>( &mut self, ranges: &[(V, V)], )857     pub fn add_buffering_ranges<V: Into<GenericFormattedValue> + Copy>(
858         &mut self,
859         ranges: &[(V, V)],
860     ) {
861         unsafe {
862             let fmt = self.get_format();
863 
864             for &(start, stop) in ranges {
865                 let start = start.into();
866                 let stop = stop.into();
867                 assert_eq!(start.get_format(), fmt);
868                 assert_eq!(stop.get_format(), fmt);
869                 gst_sys::gst_query_add_buffering_range(
870                     self.0.as_mut_ptr(),
871                     start.get_value(),
872                     stop.get_value(),
873                 );
874             }
875         }
876     }
877 }
878 
879 declare_concrete_query!(Custom, T);
880 
881 declare_concrete_query!(Uri, T);
882 impl<T: AsPtr> Uri<T> {
get_uri(&self) -> Option<String>883     pub fn get_uri(&self) -> Option<String> {
884         unsafe {
885             let mut uri = ptr::null_mut();
886             gst_sys::gst_query_parse_uri(self.0.as_ptr(), &mut uri);
887             from_glib_full(uri)
888         }
889     }
890 
get_redirection(&self) -> (Option<String>, bool)891     pub fn get_redirection(&self) -> (Option<String>, bool) {
892         unsafe {
893             let mut uri = ptr::null_mut();
894             gst_sys::gst_query_parse_uri_redirection(self.0.as_ptr(), &mut uri);
895             let mut permanent = mem::MaybeUninit::uninit();
896             gst_sys::gst_query_parse_uri_redirection_permanent(
897                 self.0.as_ptr(),
898                 permanent.as_mut_ptr(),
899             );
900 
901             (from_glib_full(uri), from_glib(permanent.assume_init()))
902         }
903     }
904 }
905 
906 impl<T: AsMutPtr> Uri<T> {
set_uri<'b, U: Into<&'b str>>(&mut self, uri: U)907     pub fn set_uri<'b, U: Into<&'b str>>(&mut self, uri: U) {
908         let uri = uri.into();
909         unsafe {
910             gst_sys::gst_query_set_uri(self.0.as_mut_ptr(), uri.to_glib_none().0);
911         }
912     }
913 
set_redirection<'b, U: Into<&'b str>>(&mut self, uri: U, permanent: bool)914     pub fn set_redirection<'b, U: Into<&'b str>>(&mut self, uri: U, permanent: bool) {
915         let uri = uri.into();
916         unsafe {
917             gst_sys::gst_query_set_uri_redirection(self.0.as_mut_ptr(), uri.to_glib_none().0);
918             gst_sys::gst_query_set_uri_redirection_permanent(
919                 self.0.as_mut_ptr(),
920                 permanent.to_glib(),
921             );
922         }
923     }
924 }
925 
926 declare_concrete_query!(Allocation, T);
927 impl<T: AsPtr> Allocation<T> {
get(&self) -> (&::CapsRef, bool)928     pub fn get(&self) -> (&::CapsRef, bool) {
929         unsafe {
930             let mut caps = ptr::null_mut();
931             let mut need_pool = mem::MaybeUninit::uninit();
932 
933             gst_sys::gst_query_parse_allocation(self.0.as_ptr(), &mut caps, need_pool.as_mut_ptr());
934             (
935                 ::CapsRef::from_ptr(caps),
936                 from_glib(need_pool.assume_init()),
937             )
938         }
939     }
940 
get_owned(&self) -> (::Caps, bool)941     pub fn get_owned(&self) -> (::Caps, bool) {
942         unsafe {
943             let (caps, need_pool) = self.get();
944             (from_glib_none(caps.as_ptr()), need_pool)
945         }
946     }
947 
get_allocation_pools(&self) -> Vec<(Option<::BufferPool>, u32, u32, u32)>948     pub fn get_allocation_pools(&self) -> Vec<(Option<::BufferPool>, u32, u32, u32)> {
949         unsafe {
950             let n = gst_sys::gst_query_get_n_allocation_pools(self.0.as_ptr());
951             let mut pools = Vec::with_capacity(n as usize);
952             for i in 0..n {
953                 let mut pool = ptr::null_mut();
954                 let mut size = mem::MaybeUninit::uninit();
955                 let mut min_buffers = mem::MaybeUninit::uninit();
956                 let mut max_buffers = mem::MaybeUninit::uninit();
957 
958                 gst_sys::gst_query_parse_nth_allocation_pool(
959                     self.0.as_ptr(),
960                     i,
961                     &mut pool,
962                     size.as_mut_ptr(),
963                     min_buffers.as_mut_ptr(),
964                     max_buffers.as_mut_ptr(),
965                 );
966                 pools.push((
967                     from_glib_full(pool),
968                     size.assume_init(),
969                     min_buffers.assume_init(),
970                     max_buffers.assume_init(),
971                 ));
972             }
973 
974             pools
975         }
976     }
977 
get_allocation_metas(&self) -> Vec<(glib::Type, Option<&::StructureRef>)>978     pub fn get_allocation_metas(&self) -> Vec<(glib::Type, Option<&::StructureRef>)> {
979         unsafe {
980             let n = gst_sys::gst_query_get_n_allocation_metas(self.0.as_ptr());
981             let mut metas = Vec::with_capacity(n as usize);
982             for i in 0..n {
983                 let mut structure = ptr::null();
984 
985                 let api = gst_sys::gst_query_parse_nth_allocation_meta(
986                     self.0.as_ptr(),
987                     i,
988                     &mut structure,
989                 );
990                 metas.push((
991                     from_glib(api),
992                     if structure.is_null() {
993                         None
994                     } else {
995                         Some(::StructureRef::from_glib_borrow(structure))
996                     },
997                 ));
998             }
999 
1000             metas
1001         }
1002     }
1003 
find_allocation_meta<U: ::MetaAPI>(&self) -> Option<u32>1004     pub fn find_allocation_meta<U: ::MetaAPI>(&self) -> Option<u32> {
1005         unsafe {
1006             let mut idx = mem::MaybeUninit::uninit();
1007             if gst_sys::gst_query_find_allocation_meta(
1008                 self.0.as_ptr(),
1009                 U::get_meta_api().to_glib(),
1010                 idx.as_mut_ptr(),
1011             ) != glib_sys::GFALSE
1012             {
1013                 Some(idx.assume_init())
1014             } else {
1015                 None
1016             }
1017         }
1018     }
1019 }
1020 
1021 impl<T: AsMutPtr> Allocation<T> {
add_allocation_pool( &mut self, pool: Option<&::BufferPool>, size: u32, min_buffers: u32, max_buffers: u32, )1022     pub fn add_allocation_pool(
1023         &mut self,
1024         pool: Option<&::BufferPool>,
1025         size: u32,
1026         min_buffers: u32,
1027         max_buffers: u32,
1028     ) {
1029         unsafe {
1030             gst_sys::gst_query_add_allocation_pool(
1031                 self.0.as_mut_ptr(),
1032                 pool.to_glib_none().0,
1033                 size,
1034                 min_buffers,
1035                 max_buffers,
1036             );
1037         }
1038     }
1039 
set_nth_allocation_pool( &mut self, idx: u32, pool: Option<&::BufferPool>, size: u32, min_buffers: u32, max_buffers: u32, )1040     pub fn set_nth_allocation_pool(
1041         &mut self,
1042         idx: u32,
1043         pool: Option<&::BufferPool>,
1044         size: u32,
1045         min_buffers: u32,
1046         max_buffers: u32,
1047     ) {
1048         unsafe {
1049             gst_sys::gst_query_set_nth_allocation_pool(
1050                 self.0.as_mut_ptr(),
1051                 idx,
1052                 pool.to_glib_none().0,
1053                 size,
1054                 min_buffers,
1055                 max_buffers,
1056             );
1057         }
1058     }
1059 
remove_nth_allocation_pool(&mut self, idx: u32)1060     pub fn remove_nth_allocation_pool(&mut self, idx: u32) {
1061         unsafe {
1062             gst_sys::gst_query_remove_nth_allocation_pool(self.0.as_mut_ptr(), idx);
1063         }
1064     }
1065 
add_allocation_meta<U: ::MetaAPI>(&mut self, structure: Option<&::StructureRef>)1066     pub fn add_allocation_meta<U: ::MetaAPI>(&mut self, structure: Option<&::StructureRef>) {
1067         unsafe {
1068             gst_sys::gst_query_add_allocation_meta(
1069                 self.0.as_mut_ptr(),
1070                 U::get_meta_api().to_glib(),
1071                 if let Some(structure) = structure {
1072                     structure.as_ptr()
1073                 } else {
1074                     ptr::null()
1075                 },
1076             );
1077         }
1078     }
1079 
remove_nth_allocation_meta(&mut self, idx: u32)1080     pub fn remove_nth_allocation_meta(&mut self, idx: u32) {
1081         unsafe {
1082             gst_sys::gst_query_remove_nth_allocation_meta(self.0.as_mut_ptr(), idx);
1083         }
1084     }
1085 }
1086 
1087 declare_concrete_query!(Scheduling, T);
1088 impl<T: AsPtr> Scheduling<T> {
has_scheduling_mode(&self, mode: ::PadMode) -> bool1089     pub fn has_scheduling_mode(&self, mode: ::PadMode) -> bool {
1090         unsafe {
1091             from_glib(gst_sys::gst_query_has_scheduling_mode(
1092                 self.0.as_ptr(),
1093                 mode.to_glib(),
1094             ))
1095         }
1096     }
1097 
has_scheduling_mode_with_flags( &self, mode: ::PadMode, flags: ::SchedulingFlags, ) -> bool1098     pub fn has_scheduling_mode_with_flags(
1099         &self,
1100         mode: ::PadMode,
1101         flags: ::SchedulingFlags,
1102     ) -> bool {
1103         skip_assert_initialized!();
1104         unsafe {
1105             from_glib(gst_sys::gst_query_has_scheduling_mode_with_flags(
1106                 self.0.as_ptr(),
1107                 mode.to_glib(),
1108                 flags.to_glib(),
1109             ))
1110         }
1111     }
1112 
get_scheduling_modes(&self) -> Vec<::PadMode>1113     pub fn get_scheduling_modes(&self) -> Vec<::PadMode> {
1114         unsafe {
1115             let n = gst_sys::gst_query_get_n_scheduling_modes(self.0.as_ptr());
1116             let mut res = Vec::with_capacity(n as usize);
1117             for i in 0..n {
1118                 res.push(from_glib(gst_sys::gst_query_parse_nth_scheduling_mode(
1119                     self.0.as_ptr(),
1120                     i,
1121                 )));
1122             }
1123 
1124             res
1125         }
1126     }
1127 
get_result(&self) -> (::SchedulingFlags, i32, i32, i32)1128     pub fn get_result(&self) -> (::SchedulingFlags, i32, i32, i32) {
1129         unsafe {
1130             let mut flags = mem::MaybeUninit::uninit();
1131             let mut minsize = mem::MaybeUninit::uninit();
1132             let mut maxsize = mem::MaybeUninit::uninit();
1133             let mut align = mem::MaybeUninit::uninit();
1134 
1135             gst_sys::gst_query_parse_scheduling(
1136                 self.0.as_ptr(),
1137                 flags.as_mut_ptr(),
1138                 minsize.as_mut_ptr(),
1139                 maxsize.as_mut_ptr(),
1140                 align.as_mut_ptr(),
1141             );
1142 
1143             (
1144                 from_glib(flags.assume_init()),
1145                 minsize.assume_init(),
1146                 maxsize.assume_init(),
1147                 align.assume_init(),
1148             )
1149         }
1150     }
1151 }
1152 
1153 impl<T: AsMutPtr> Scheduling<T> {
add_scheduling_modes(&mut self, modes: &[::PadMode])1154     pub fn add_scheduling_modes(&mut self, modes: &[::PadMode]) {
1155         unsafe {
1156             for mode in modes {
1157                 gst_sys::gst_query_add_scheduling_mode(self.0.as_mut_ptr(), mode.to_glib());
1158             }
1159         }
1160     }
1161 
set(&mut self, flags: ::SchedulingFlags, minsize: i32, maxsize: i32, align: i32)1162     pub fn set(&mut self, flags: ::SchedulingFlags, minsize: i32, maxsize: i32, align: i32) {
1163         unsafe {
1164             gst_sys::gst_query_set_scheduling(
1165                 self.0.as_mut_ptr(),
1166                 flags.to_glib(),
1167                 minsize,
1168                 maxsize,
1169                 align,
1170             );
1171         }
1172     }
1173 }
1174 
1175 declare_concrete_query!(AcceptCaps, T);
1176 impl<T: AsPtr> AcceptCaps<T> {
get_caps(&self) -> &::CapsRef1177     pub fn get_caps(&self) -> &::CapsRef {
1178         unsafe {
1179             let mut caps = ptr::null_mut();
1180             gst_sys::gst_query_parse_accept_caps(self.0.as_ptr(), &mut caps);
1181             ::CapsRef::from_ptr(caps)
1182         }
1183     }
1184 
get_caps_owned(&self) -> ::Caps1185     pub fn get_caps_owned(&self) -> ::Caps {
1186         unsafe { from_glib_none(self.get_caps().as_ptr()) }
1187     }
1188 
get_result(&self) -> bool1189     pub fn get_result(&self) -> bool {
1190         unsafe {
1191             let mut accepted = mem::MaybeUninit::uninit();
1192             gst_sys::gst_query_parse_accept_caps_result(self.0.as_ptr(), accepted.as_mut_ptr());
1193             from_glib(accepted.assume_init())
1194         }
1195     }
1196 }
1197 
1198 impl<T: AsMutPtr> AcceptCaps<T> {
set_result(&mut self, accepted: bool)1199     pub fn set_result(&mut self, accepted: bool) {
1200         unsafe {
1201             gst_sys::gst_query_set_accept_caps_result(self.0.as_mut_ptr(), accepted.to_glib());
1202         }
1203     }
1204 }
1205 
1206 declare_concrete_query!(Caps, T);
1207 impl<T: AsPtr> Caps<T> {
get_filter(&self) -> Option<&::CapsRef>1208     pub fn get_filter(&self) -> Option<&::CapsRef> {
1209         unsafe {
1210             let mut caps = ptr::null_mut();
1211             gst_sys::gst_query_parse_caps(self.0.as_ptr(), &mut caps);
1212             if caps.is_null() {
1213                 None
1214             } else {
1215                 Some(::CapsRef::from_ptr(caps))
1216             }
1217         }
1218     }
1219 
get_filter_owned(&self) -> Option<::Caps>1220     pub fn get_filter_owned(&self) -> Option<::Caps> {
1221         unsafe { self.get_filter().map(|caps| from_glib_none(caps.as_ptr())) }
1222     }
1223 
get_result(&self) -> Option<&::CapsRef>1224     pub fn get_result(&self) -> Option<&::CapsRef> {
1225         unsafe {
1226             let mut caps = ptr::null_mut();
1227             gst_sys::gst_query_parse_caps_result(self.0.as_ptr(), &mut caps);
1228             if caps.is_null() {
1229                 None
1230             } else {
1231                 Some(::CapsRef::from_ptr(caps))
1232             }
1233         }
1234     }
1235 
get_result_owned(&self) -> Option<::Caps>1236     pub fn get_result_owned(&self) -> Option<::Caps> {
1237         unsafe { self.get_result().map(|caps| from_glib_none(caps.as_ptr())) }
1238     }
1239 }
1240 
1241 impl<T: AsMutPtr> Caps<T> {
set_result(&mut self, caps: &::Caps)1242     pub fn set_result(&mut self, caps: &::Caps) {
1243         unsafe {
1244             gst_sys::gst_query_set_caps_result(self.0.as_mut_ptr(), caps.as_mut_ptr());
1245         }
1246     }
1247 }
1248 
1249 declare_concrete_query!(Drain, T);
1250 
1251 declare_concrete_query!(Context, T);
1252 impl<T: AsPtr> Context<T> {
get_context(&self) -> Option<&::ContextRef>1253     pub fn get_context(&self) -> Option<&::ContextRef> {
1254         unsafe {
1255             let mut context = ptr::null_mut();
1256             gst_sys::gst_query_parse_context(self.0.as_ptr(), &mut context);
1257             if context.is_null() {
1258                 None
1259             } else {
1260                 Some(::ContextRef::from_ptr(context))
1261             }
1262         }
1263     }
1264 
get_context_owned(&self) -> Option<::Context>1265     pub fn get_context_owned(&self) -> Option<::Context> {
1266         unsafe {
1267             self.get_context()
1268                 .map(|context| from_glib_none(context.as_ptr()))
1269         }
1270     }
1271 
get_context_type(&self) -> &str1272     pub fn get_context_type(&self) -> &str {
1273         unsafe {
1274             let mut context_type = ptr::null();
1275             gst_sys::gst_query_parse_context_type(self.0.as_ptr(), &mut context_type);
1276             CStr::from_ptr(context_type).to_str().unwrap()
1277         }
1278     }
1279 }
1280 
1281 impl<T: AsMutPtr> Context<T> {
set_context(&mut self, context: &::Context)1282     pub fn set_context(&mut self, context: &::Context) {
1283         unsafe {
1284             gst_sys::gst_query_set_context(self.0.as_mut_ptr(), context.as_mut_ptr());
1285         }
1286     }
1287 }
1288 
1289 declare_concrete_query!(Bitrate, T);
1290 impl<T: AsPtr> Bitrate<T> {
1291     #[cfg(any(feature = "v1_16", feature = "dox"))]
get_bitrate(&self) -> u321292     pub fn get_bitrate(&self) -> u32 {
1293         unsafe {
1294             let mut bitrate = mem::MaybeUninit::uninit();
1295             gst_sys::gst_query_parse_bitrate(self.0.as_ptr(), bitrate.as_mut_ptr());
1296             bitrate.assume_init()
1297         }
1298     }
1299 }
1300 
1301 impl<T: AsMutPtr> Bitrate<T> {
1302     #[cfg(any(feature = "v1_16", feature = "dox"))]
set_bitrate(&mut self, bitrate: u32)1303     pub fn set_bitrate(&mut self, bitrate: u32) {
1304         unsafe {
1305             gst_sys::gst_query_set_bitrate(self.0.as_mut_ptr(), bitrate);
1306         }
1307     }
1308 }
1309 
1310 declare_concrete_query!(Other, T);
1311 
1312 #[cfg(test)]
1313 mod tests {
1314     use super::*;
1315     use std::convert::TryInto;
1316 
1317     #[test]
test_writability()1318     fn test_writability() {
1319         ::init().unwrap();
1320 
1321         fn check_mut(query: &mut QueryRef) {
1322             match query.view_mut() {
1323                 QueryView::Position(ref mut p) => {
1324                     let pos = p.get_result();
1325                     assert_eq!(pos.try_into(), Ok(::CLOCK_TIME_NONE));
1326                     p.set(3 * ::SECOND);
1327                     let pos = p.get_result();
1328                     assert_eq!(pos.try_into(), Ok(3 * ::SECOND));
1329                 }
1330                 _ => panic!("Wrong concrete Query in Query"),
1331             }
1332         }
1333 
1334         fn check_ref(query: &QueryRef) {
1335             match query.view() {
1336                 QueryView::Position(ref p) => {
1337                     let pos = p.get_result();
1338                     assert_eq!(pos.try_into(), Ok(3 * ::SECOND));
1339                     unsafe {
1340                         assert!(!p.as_mut_ptr().is_null());
1341                     }
1342                 }
1343                 _ => panic!("Wrong concrete Query in Query"),
1344             }
1345         }
1346 
1347         let mut p = Query::new_position(::Format::Time);
1348         let pos = p.get_result();
1349         assert_eq!(pos.try_into(), Ok(::CLOCK_TIME_NONE));
1350 
1351         p.get_mut_structure().set("check_mut", &true);
1352 
1353         // deref
1354         assert!(!p.is_serialized());
1355 
1356         {
1357             check_mut(&mut p);
1358 
1359             let structure = p.get_structure();
1360             structure.unwrap().has_field("check_mut");
1361 
1362             // Expected: cannot borrow `p` as mutable because it is also borrowed as immutable
1363             //check_mut(&mut p);
1364         }
1365 
1366         check_ref(&p);
1367     }
1368 
1369     #[test]
test_into_query()1370     fn test_into_query() {
1371         ::init().unwrap();
1372         let d = Query::new_duration(::Format::Time);
1373 
1374         let mut query: Query = d.into();
1375         assert!(query.is_writable());
1376 
1377         let query = query.make_mut();
1378         match query.view_mut() {
1379             QueryView::Duration(ref mut d) => {
1380                 d.set(2 * ::SECOND);
1381             }
1382             _ => (),
1383         }
1384 
1385         match query.view() {
1386             QueryView::Duration(ref d) => {
1387                 let duration = d.get_result();
1388                 assert_eq!(duration.try_into(), Ok(2 * ::SECOND));
1389             }
1390             _ => (),
1391         }
1392     }
1393 
1394     #[test]
test_concrete_to_sys()1395     fn test_concrete_to_sys() {
1396         ::init().unwrap();
1397 
1398         let p = Query::new_position(::Format::Time);
1399         unsafe {
1400             assert!(!p.as_mut_ptr().is_null());
1401         }
1402     }
1403 }
1404