1 // Take a look at the license at the top of the repository in the LICENSE file.
2 
3 use crate::Buffer;
4 use crate::BufferList;
5 use crate::Event;
6 use crate::FlowError;
7 use crate::FlowReturn;
8 use crate::FlowSuccess;
9 use crate::Format;
10 use crate::FormattedValue;
11 use crate::GenericFormattedValue;
12 use crate::LoggableError;
13 use crate::Pad;
14 use crate::PadFlags;
15 use crate::PadProbeReturn;
16 use crate::PadProbeType;
17 use crate::Query;
18 use crate::QueryRef;
19 use crate::StaticPadTemplate;
20 use crate::{SpecificFormattedValue, SpecificFormattedValueIntrinsic};
21 
22 use std::cell::RefCell;
23 use std::mem;
24 use std::num::NonZeroU64;
25 use std::ptr;
26 
27 use glib::ffi::gpointer;
28 use glib::prelude::*;
29 use glib::translate::*;
30 
31 #[derive(Debug, PartialEq, Eq)]
32 pub struct PadProbeId(NonZeroU64);
33 
34 impl IntoGlib for PadProbeId {
35     type GlibType = libc::c_ulong;
36 
into_glib(self) -> libc::c_ulong37     fn into_glib(self) -> libc::c_ulong {
38         self.0.get() as libc::c_ulong
39     }
40 }
41 
42 impl FromGlib<libc::c_ulong> for PadProbeId {
from_glib(val: libc::c_ulong) -> PadProbeId43     unsafe fn from_glib(val: libc::c_ulong) -> PadProbeId {
44         skip_assert_initialized!();
45         assert_ne!(val, 0);
46         PadProbeId(NonZeroU64::new_unchecked(val as u64))
47     }
48 }
49 
50 #[derive(Debug)]
51 pub struct PadProbeInfo<'a> {
52     pub mask: PadProbeType,
53     pub id: Option<PadProbeId>,
54     pub offset: u64,
55     pub size: u32,
56     pub data: Option<PadProbeData<'a>>,
57     pub flow_res: Result<FlowSuccess, FlowError>,
58 }
59 
60 #[derive(Debug)]
61 pub enum PadProbeData<'a> {
62     Buffer(Buffer),
63     BufferList(BufferList),
64     Query(&'a mut QueryRef),
65     Event(Event),
66     #[doc(hidden)]
67     __Unknown(*mut ffi::GstMiniObject),
68 }
69 
70 unsafe impl<'a> Send for PadProbeData<'a> {}
71 unsafe impl<'a> Sync for PadProbeData<'a> {}
72 
73 #[derive(Debug)]
74 #[must_use = "if unused the StreamLock will immediately unlock"]
75 pub struct StreamLock<'a>(&'a Pad);
76 impl<'a> Drop for StreamLock<'a> {
drop(&mut self)77     fn drop(&mut self) {
78         unsafe {
79             let pad: *mut ffi::GstPad = self.0.to_glib_none().0;
80             glib::ffi::g_rec_mutex_unlock(&mut (*pad).stream_rec_lock);
81         }
82     }
83 }
84 
85 #[derive(Debug)]
86 pub enum PadGetRangeSuccess {
87     FilledBuffer,
88     NewBuffer(crate::Buffer),
89 }
90 
91 pub trait PadExtManual: 'static {
92     #[doc(alias = "gst_pad_add_probe")]
add_probe<F>(&self, mask: PadProbeType, func: F) -> Option<PadProbeId> where F: Fn(&Self, &mut PadProbeInfo) -> PadProbeReturn + Send + Sync + 'static93     fn add_probe<F>(&self, mask: PadProbeType, func: F) -> Option<PadProbeId>
94     where
95         F: Fn(&Self, &mut PadProbeInfo) -> PadProbeReturn + Send + Sync + 'static;
96     #[doc(alias = "gst_pad_remove_probe")]
remove_probe(&self, id: PadProbeId)97     fn remove_probe(&self, id: PadProbeId);
98 
99     #[doc(alias = "gst_pad_chain")]
chain(&self, buffer: Buffer) -> Result<FlowSuccess, FlowError>100     fn chain(&self, buffer: Buffer) -> Result<FlowSuccess, FlowError>;
101     #[doc(alias = "gst_pad_push")]
push(&self, buffer: Buffer) -> Result<FlowSuccess, FlowError>102     fn push(&self, buffer: Buffer) -> Result<FlowSuccess, FlowError>;
103 
104     #[doc(alias = "gst_pad_chain_list")]
chain_list(&self, list: BufferList) -> Result<FlowSuccess, FlowError>105     fn chain_list(&self, list: BufferList) -> Result<FlowSuccess, FlowError>;
106     #[doc(alias = "gst_pad_push_list")]
push_list(&self, list: BufferList) -> Result<FlowSuccess, FlowError>107     fn push_list(&self, list: BufferList) -> Result<FlowSuccess, FlowError>;
108 
109     #[doc(alias = "gst_pad_pull_range")]
pull_range(&self, offset: u64, size: u32) -> Result<Buffer, FlowError>110     fn pull_range(&self, offset: u64, size: u32) -> Result<Buffer, FlowError>;
pull_range_fill( &self, offset: u64, buffer: &mut crate::BufferRef, size: u32, ) -> Result<(), FlowError>111     fn pull_range_fill(
112         &self,
113         offset: u64,
114         buffer: &mut crate::BufferRef,
115         size: u32,
116     ) -> Result<(), FlowError>;
117     #[doc(alias = "get_range")]
118     #[doc(alias = "gst_pad_get_range")]
range(&self, offset: u64, size: u32) -> Result<Buffer, FlowError>119     fn range(&self, offset: u64, size: u32) -> Result<Buffer, FlowError>;
120     #[doc(alias = "get_range_fill")]
range_fill( &self, offset: u64, buffer: &mut crate::BufferRef, size: u32, ) -> Result<(), FlowError>121     fn range_fill(
122         &self,
123         offset: u64,
124         buffer: &mut crate::BufferRef,
125         size: u32,
126     ) -> Result<(), FlowError>;
127 
128     #[doc(alias = "gst_pad_peer_query")]
peer_query(&self, query: &mut QueryRef) -> bool129     fn peer_query(&self, query: &mut QueryRef) -> bool;
130     #[doc(alias = "gst_pad_query")]
query(&self, query: &mut QueryRef) -> bool131     fn query(&self, query: &mut QueryRef) -> bool;
132     #[doc(alias = "gst_pad_query_default")]
query_default<P: IsA<crate::Object>>( &self, parent: Option<&P>, query: &mut QueryRef, ) -> bool133     fn query_default<P: IsA<crate::Object>>(
134         &self,
135         parent: Option<&P>,
136         query: &mut QueryRef,
137     ) -> bool;
proxy_query_caps(&self, query: &mut QueryRef) -> bool138     fn proxy_query_caps(&self, query: &mut QueryRef) -> bool;
139     #[doc(alias = "gst_pad_proxy_query_accept_caps")]
proxy_query_accept_caps(&self, query: &mut QueryRef) -> bool140     fn proxy_query_accept_caps(&self, query: &mut QueryRef) -> bool;
141 
142     #[doc(alias = "gst_pad_event_default")]
event_default<P: IsA<crate::Object>>(&self, parent: Option<&P>, event: Event) -> bool143     fn event_default<P: IsA<crate::Object>>(&self, parent: Option<&P>, event: Event) -> bool;
144     #[doc(alias = "gst_pad_push_event")]
push_event(&self, event: Event) -> bool145     fn push_event(&self, event: Event) -> bool;
146     #[doc(alias = "gst_pad_send_event")]
send_event(&self, event: Event) -> bool147     fn send_event(&self, event: Event) -> bool;
148 
149     #[doc(alias = "gst_pad_iterate_internal_links")]
iterate_internal_links(&self) -> crate::Iterator<Pad>150     fn iterate_internal_links(&self) -> crate::Iterator<Pad>;
151     #[doc(alias = "gst_pad_iterate_internal_links_default")]
iterate_internal_links_default<P: IsA<crate::Object>>( &self, parent: Option<&P>, ) -> crate::Iterator<Pad>152     fn iterate_internal_links_default<P: IsA<crate::Object>>(
153         &self,
154         parent: Option<&P>,
155     ) -> crate::Iterator<Pad>;
156 
stream_lock(&self) -> StreamLock157     fn stream_lock(&self) -> StreamLock;
158 
set_activate_function<F>(&self, func: F) where F: Fn(&Self, Option<&crate::Object>) -> Result<(), LoggableError> + Send + Sync + 'static159     unsafe fn set_activate_function<F>(&self, func: F)
160     where
161         F: Fn(&Self, Option<&crate::Object>) -> Result<(), LoggableError> + Send + Sync + 'static;
162 
set_activatemode_function<F>(&self, func: F) where F: Fn(&Self, Option<&crate::Object>, crate::PadMode, bool) -> Result<(), LoggableError> + Send + Sync + 'static163     unsafe fn set_activatemode_function<F>(&self, func: F)
164     where
165         F: Fn(&Self, Option<&crate::Object>, crate::PadMode, bool) -> Result<(), LoggableError>
166             + Send
167             + Sync
168             + 'static;
169 
set_chain_function<F>(&self, func: F) where F: Fn(&Self, Option<&crate::Object>, crate::Buffer) -> Result<FlowSuccess, FlowError> + Send + Sync + 'static170     unsafe fn set_chain_function<F>(&self, func: F)
171     where
172         F: Fn(&Self, Option<&crate::Object>, crate::Buffer) -> Result<FlowSuccess, FlowError>
173             + Send
174             + Sync
175             + 'static;
176 
set_chain_list_function<F>(&self, func: F) where F: Fn(&Self, Option<&crate::Object>, crate::BufferList) -> Result<FlowSuccess, FlowError> + Send + Sync + 'static177     unsafe fn set_chain_list_function<F>(&self, func: F)
178     where
179         F: Fn(&Self, Option<&crate::Object>, crate::BufferList) -> Result<FlowSuccess, FlowError>
180             + Send
181             + Sync
182             + 'static;
183 
set_event_function<F>(&self, func: F) where F: Fn(&Self, Option<&crate::Object>, crate::Event) -> bool + Send + Sync + 'static184     unsafe fn set_event_function<F>(&self, func: F)
185     where
186         F: Fn(&Self, Option<&crate::Object>, crate::Event) -> bool + Send + Sync + 'static;
187 
set_event_full_function<F>(&self, func: F) where F: Fn(&Self, Option<&crate::Object>, crate::Event) -> Result<FlowSuccess, FlowError> + Send + Sync + 'static188     unsafe fn set_event_full_function<F>(&self, func: F)
189     where
190         F: Fn(&Self, Option<&crate::Object>, crate::Event) -> Result<FlowSuccess, FlowError>
191             + Send
192             + Sync
193             + 'static;
194 
set_getrange_function<F>(&self, func: F) where F: Fn( &Self, Option<&crate::Object>, u64, Option<&mut crate::BufferRef>, u32, ) -> Result<PadGetRangeSuccess, crate::FlowError> + Send + Sync + 'static195     unsafe fn set_getrange_function<F>(&self, func: F)
196     where
197         F: Fn(
198                 &Self,
199                 Option<&crate::Object>,
200                 u64,
201                 Option<&mut crate::BufferRef>,
202                 u32,
203             ) -> Result<PadGetRangeSuccess, crate::FlowError>
204             + Send
205             + Sync
206             + 'static;
207 
set_iterate_internal_links_function<F>(&self, func: F) where F: Fn(&Self, Option<&crate::Object>) -> crate::Iterator<Pad> + Send + Sync + 'static208     unsafe fn set_iterate_internal_links_function<F>(&self, func: F)
209     where
210         F: Fn(&Self, Option<&crate::Object>) -> crate::Iterator<Pad> + Send + Sync + 'static;
211 
set_link_function<F>(&self, func: F) where F: Fn( &Self, Option<&crate::Object>, &Pad, ) -> Result<crate::PadLinkSuccess, crate::PadLinkError> + Send + Sync + 'static212     unsafe fn set_link_function<F>(&self, func: F)
213     where
214         F: Fn(
215                 &Self,
216                 Option<&crate::Object>,
217                 &Pad,
218             ) -> Result<crate::PadLinkSuccess, crate::PadLinkError>
219             + Send
220             + Sync
221             + 'static;
222 
set_query_function<F>(&self, func: F) where F: Fn(&Self, Option<&crate::Object>, &mut crate::QueryRef) -> bool + Send + Sync + 'static223     unsafe fn set_query_function<F>(&self, func: F)
224     where
225         F: Fn(&Self, Option<&crate::Object>, &mut crate::QueryRef) -> bool + Send + Sync + 'static;
226 
set_unlink_function<F>(&self, func: F) where F: Fn(&Self, Option<&crate::Object>) + Send + Sync + 'static227     unsafe fn set_unlink_function<F>(&self, func: F)
228     where
229         F: Fn(&Self, Option<&crate::Object>) + Send + Sync + 'static;
230 
231     #[doc(alias = "gst_pad_start_task")]
start_task<F: FnMut() + Send + 'static>(&self, func: F) -> Result<(), glib::BoolError>232     fn start_task<F: FnMut() + Send + 'static>(&self, func: F) -> Result<(), glib::BoolError>;
233 
234     #[doc(alias = "gst_pad_peer_query_convert")]
peer_query_convert<V: Into<GenericFormattedValue>, U: SpecificFormattedValue>( &self, src_val: V, ) -> Option<U>235     fn peer_query_convert<V: Into<GenericFormattedValue>, U: SpecificFormattedValue>(
236         &self,
237         src_val: V,
238     ) -> Option<U>;
peer_query_convert_generic<V: Into<GenericFormattedValue>>( &self, src_val: V, dest_format: Format, ) -> Option<GenericFormattedValue>239     fn peer_query_convert_generic<V: Into<GenericFormattedValue>>(
240         &self,
241         src_val: V,
242         dest_format: Format,
243     ) -> Option<GenericFormattedValue>;
244 
245     #[doc(alias = "gst_pad_peer_query_duration")]
peer_query_duration<T: SpecificFormattedValueIntrinsic>(&self) -> Option<T>246     fn peer_query_duration<T: SpecificFormattedValueIntrinsic>(&self) -> Option<T>;
peer_query_duration_generic(&self, format: Format) -> Option<GenericFormattedValue>247     fn peer_query_duration_generic(&self, format: Format) -> Option<GenericFormattedValue>;
248 
249     #[doc(alias = "gst_pad_peer_query_position")]
peer_query_position<T: SpecificFormattedValueIntrinsic>(&self) -> Option<T>250     fn peer_query_position<T: SpecificFormattedValueIntrinsic>(&self) -> Option<T>;
peer_query_position_generic(&self, format: Format) -> Option<GenericFormattedValue>251     fn peer_query_position_generic(&self, format: Format) -> Option<GenericFormattedValue>;
252 
253     #[doc(alias = "gst_pad_query_convert")]
query_convert<V: Into<GenericFormattedValue>, U: SpecificFormattedValue>( &self, src_val: V, ) -> Option<U>254     fn query_convert<V: Into<GenericFormattedValue>, U: SpecificFormattedValue>(
255         &self,
256         src_val: V,
257     ) -> Option<U>;
query_convert_generic<V: Into<GenericFormattedValue>>( &self, src_val: V, dest_format: Format, ) -> Option<GenericFormattedValue>258     fn query_convert_generic<V: Into<GenericFormattedValue>>(
259         &self,
260         src_val: V,
261         dest_format: Format,
262     ) -> Option<GenericFormattedValue>;
263 
264     #[doc(alias = "gst_pad_query_duration")]
query_duration<T: SpecificFormattedValueIntrinsic>(&self) -> Option<T>265     fn query_duration<T: SpecificFormattedValueIntrinsic>(&self) -> Option<T>;
query_duration_generic(&self, format: Format) -> Option<GenericFormattedValue>266     fn query_duration_generic(&self, format: Format) -> Option<GenericFormattedValue>;
267 
268     #[doc(alias = "gst_pad_query_position")]
query_position<T: SpecificFormattedValueIntrinsic>(&self) -> Option<T>269     fn query_position<T: SpecificFormattedValueIntrinsic>(&self) -> Option<T>;
query_position_generic(&self, format: Format) -> Option<GenericFormattedValue>270     fn query_position_generic(&self, format: Format) -> Option<GenericFormattedValue>;
271 
272     #[doc(alias = "get_mode")]
mode(&self) -> crate::PadMode273     fn mode(&self) -> crate::PadMode;
274 
275     #[doc(alias = "gst_pad_sticky_events_foreach")]
sticky_events_foreach<F: FnMut(Event) -> Result<Option<Event>, Option<Event>>>( &self, func: F, )276     fn sticky_events_foreach<F: FnMut(Event) -> Result<Option<Event>, Option<Event>>>(
277         &self,
278         func: F,
279     );
280 
set_pad_flags(&self, flags: PadFlags)281     fn set_pad_flags(&self, flags: PadFlags);
282 
unset_pad_flags(&self, flags: PadFlags)283     fn unset_pad_flags(&self, flags: PadFlags);
284 
285     #[doc(alias = "get_pad_flags")]
pad_flags(&self) -> PadFlags286     fn pad_flags(&self) -> PadFlags;
287 }
288 
289 impl<O: IsA<Pad>> PadExtManual for O {
add_probe<F>(&self, mask: PadProbeType, func: F) -> Option<PadProbeId> where F: Fn(&Self, &mut PadProbeInfo) -> PadProbeReturn + Send + Sync + 'static,290     fn add_probe<F>(&self, mask: PadProbeType, func: F) -> Option<PadProbeId>
291     where
292         F: Fn(&Self, &mut PadProbeInfo) -> PadProbeReturn + Send + Sync + 'static,
293     {
294         unsafe {
295             let func_box: Box<F> = Box::new(func);
296             let id = ffi::gst_pad_add_probe(
297                 self.as_ref().to_glib_none().0,
298                 mask.into_glib(),
299                 Some(trampoline_pad_probe::<Self, F>),
300                 Box::into_raw(func_box) as gpointer,
301                 Some(destroy_closure::<F>),
302             );
303 
304             if id == 0 {
305                 None
306             } else {
307                 Some(from_glib(id))
308             }
309         }
310     }
311 
remove_probe(&self, id: PadProbeId)312     fn remove_probe(&self, id: PadProbeId) {
313         unsafe {
314             ffi::gst_pad_remove_probe(self.as_ref().to_glib_none().0, id.into_glib());
315         }
316     }
317 
chain(&self, buffer: Buffer) -> Result<FlowSuccess, FlowError>318     fn chain(&self, buffer: Buffer) -> Result<FlowSuccess, FlowError> {
319         unsafe {
320             try_from_glib(ffi::gst_pad_chain(
321                 self.as_ref().to_glib_none().0,
322                 buffer.into_ptr(),
323             ))
324         }
325     }
326 
push(&self, buffer: Buffer) -> Result<FlowSuccess, FlowError>327     fn push(&self, buffer: Buffer) -> Result<FlowSuccess, FlowError> {
328         unsafe {
329             try_from_glib(ffi::gst_pad_push(
330                 self.as_ref().to_glib_none().0,
331                 buffer.into_ptr(),
332             ))
333         }
334     }
335 
chain_list(&self, list: BufferList) -> Result<FlowSuccess, FlowError>336     fn chain_list(&self, list: BufferList) -> Result<FlowSuccess, FlowError> {
337         unsafe {
338             try_from_glib(ffi::gst_pad_chain_list(
339                 self.as_ref().to_glib_none().0,
340                 list.into_ptr(),
341             ))
342         }
343     }
344 
push_list(&self, list: BufferList) -> Result<FlowSuccess, FlowError>345     fn push_list(&self, list: BufferList) -> Result<FlowSuccess, FlowError> {
346         unsafe {
347             try_from_glib(ffi::gst_pad_push_list(
348                 self.as_ref().to_glib_none().0,
349                 list.into_ptr(),
350             ))
351         }
352     }
353 
range(&self, offset: u64, size: u32) -> Result<Buffer, FlowError>354     fn range(&self, offset: u64, size: u32) -> Result<Buffer, FlowError> {
355         unsafe {
356             let mut buffer = ptr::null_mut();
357             FlowSuccess::try_from_glib(ffi::gst_pad_get_range(
358                 self.as_ref().to_glib_none().0,
359                 offset,
360                 size,
361                 &mut buffer,
362             ))
363             .map(|_| from_glib_full(buffer))
364         }
365     }
366 
range_fill( &self, offset: u64, buffer: &mut crate::BufferRef, size: u32, ) -> Result<(), FlowError>367     fn range_fill(
368         &self,
369         offset: u64,
370         buffer: &mut crate::BufferRef,
371         size: u32,
372     ) -> Result<(), FlowError> {
373         assert!(buffer.size() >= size as usize);
374 
375         unsafe {
376             let mut buffer_ref = buffer.as_mut_ptr();
377             FlowSuccess::try_from_glib(ffi::gst_pad_get_range(
378                 self.as_ref().to_glib_none().0,
379                 offset,
380                 size,
381                 &mut buffer_ref,
382             ))
383             .and_then(|_| {
384                 if buffer.as_mut_ptr() != buffer_ref {
385                     ffi::gst_mini_object_unref(buffer_ref as *mut _);
386                     Err(crate::FlowError::Error)
387                 } else {
388                     Ok(())
389                 }
390             })
391         }
392     }
393 
pull_range(&self, offset: u64, size: u32) -> Result<Buffer, FlowError>394     fn pull_range(&self, offset: u64, size: u32) -> Result<Buffer, FlowError> {
395         unsafe {
396             let mut buffer = ptr::null_mut();
397             FlowSuccess::try_from_glib(ffi::gst_pad_pull_range(
398                 self.as_ref().to_glib_none().0,
399                 offset,
400                 size,
401                 &mut buffer,
402             ))
403             .map(|_| from_glib_full(buffer))
404         }
405     }
406 
pull_range_fill( &self, offset: u64, buffer: &mut crate::BufferRef, size: u32, ) -> Result<(), FlowError>407     fn pull_range_fill(
408         &self,
409         offset: u64,
410         buffer: &mut crate::BufferRef,
411         size: u32,
412     ) -> Result<(), FlowError> {
413         assert!(buffer.size() >= size as usize);
414 
415         unsafe {
416             let mut buffer_ref = buffer.as_mut_ptr();
417             FlowSuccess::try_from_glib(ffi::gst_pad_pull_range(
418                 self.as_ref().to_glib_none().0,
419                 offset,
420                 size,
421                 &mut buffer_ref,
422             ))
423             .and_then(|_| {
424                 if buffer.as_mut_ptr() != buffer_ref {
425                     ffi::gst_mini_object_unref(buffer_ref as *mut _);
426                     Err(crate::FlowError::Error)
427                 } else {
428                     Ok(())
429                 }
430             })
431         }
432     }
433 
query(&self, query: &mut QueryRef) -> bool434     fn query(&self, query: &mut QueryRef) -> bool {
435         unsafe {
436             from_glib(ffi::gst_pad_query(
437                 self.as_ref().to_glib_none().0,
438                 query.as_mut_ptr(),
439             ))
440         }
441     }
442 
peer_query(&self, query: &mut QueryRef) -> bool443     fn peer_query(&self, query: &mut QueryRef) -> bool {
444         unsafe {
445             from_glib(ffi::gst_pad_peer_query(
446                 self.as_ref().to_glib_none().0,
447                 query.as_mut_ptr(),
448             ))
449         }
450     }
451 
query_default<P: IsA<crate::Object>>( &self, parent: Option<&P>, query: &mut QueryRef, ) -> bool452     fn query_default<P: IsA<crate::Object>>(
453         &self,
454         parent: Option<&P>,
455         query: &mut QueryRef,
456     ) -> bool {
457         skip_assert_initialized!();
458         unsafe {
459             from_glib(ffi::gst_pad_query_default(
460                 self.as_ref().to_glib_none().0,
461                 parent.map(|p| p.as_ref()).to_glib_none().0,
462                 query.as_mut_ptr(),
463             ))
464         }
465     }
466 
proxy_query_accept_caps(&self, query: &mut QueryRef) -> bool467     fn proxy_query_accept_caps(&self, query: &mut QueryRef) -> bool {
468         unsafe {
469             from_glib(ffi::gst_pad_proxy_query_accept_caps(
470                 self.as_ref().to_glib_none().0,
471                 query.as_mut_ptr(),
472             ))
473         }
474     }
475 
proxy_query_caps(&self, query: &mut QueryRef) -> bool476     fn proxy_query_caps(&self, query: &mut QueryRef) -> bool {
477         unsafe {
478             from_glib(ffi::gst_pad_proxy_query_accept_caps(
479                 self.as_ref().to_glib_none().0,
480                 query.as_mut_ptr(),
481             ))
482         }
483     }
484 
event_default<P: IsA<crate::Object>>(&self, parent: Option<&P>, event: Event) -> bool485     fn event_default<P: IsA<crate::Object>>(&self, parent: Option<&P>, event: Event) -> bool {
486         skip_assert_initialized!();
487         unsafe {
488             from_glib(ffi::gst_pad_event_default(
489                 self.as_ref().to_glib_none().0,
490                 parent.map(|p| p.as_ref()).to_glib_none().0,
491                 event.into_ptr(),
492             ))
493         }
494     }
495 
push_event(&self, event: Event) -> bool496     fn push_event(&self, event: Event) -> bool {
497         unsafe {
498             from_glib(ffi::gst_pad_push_event(
499                 self.as_ref().to_glib_none().0,
500                 event.into_ptr(),
501             ))
502         }
503     }
504 
send_event(&self, event: Event) -> bool505     fn send_event(&self, event: Event) -> bool {
506         unsafe {
507             from_glib(ffi::gst_pad_send_event(
508                 self.as_ref().to_glib_none().0,
509                 event.into_ptr(),
510             ))
511         }
512     }
513 
iterate_internal_links(&self) -> crate::Iterator<Pad>514     fn iterate_internal_links(&self) -> crate::Iterator<Pad> {
515         unsafe {
516             from_glib_full(ffi::gst_pad_iterate_internal_links(
517                 self.as_ref().to_glib_none().0,
518             ))
519         }
520     }
521 
iterate_internal_links_default<P: IsA<crate::Object>>( &self, parent: Option<&P>, ) -> crate::Iterator<Pad>522     fn iterate_internal_links_default<P: IsA<crate::Object>>(
523         &self,
524         parent: Option<&P>,
525     ) -> crate::Iterator<Pad> {
526         unsafe {
527             from_glib_full(ffi::gst_pad_iterate_internal_links_default(
528                 self.as_ref().to_glib_none().0,
529                 parent.map(|p| p.as_ref()).to_glib_none().0,
530             ))
531         }
532     }
533 
stream_lock(&self) -> StreamLock534     fn stream_lock(&self) -> StreamLock {
535         unsafe {
536             let ptr: &mut ffi::GstPad = &mut *(self.as_ptr() as *mut _);
537             glib::ffi::g_rec_mutex_lock(&mut ptr.stream_rec_lock);
538             StreamLock(self.upcast_ref())
539         }
540     }
541 
set_activate_function<F>(&self, func: F) where F: Fn(&Self, Option<&crate::Object>) -> Result<(), LoggableError> + Send + Sync + 'static,542     unsafe fn set_activate_function<F>(&self, func: F)
543     where
544         F: Fn(&Self, Option<&crate::Object>) -> Result<(), LoggableError> + Send + Sync + 'static,
545     {
546         let func_box: Box<F> = Box::new(func);
547         ffi::gst_pad_set_activate_function_full(
548             self.as_ref().to_glib_none().0,
549             Some(trampoline_activate_function::<Self, F>),
550             Box::into_raw(func_box) as gpointer,
551             Some(destroy_closure::<F>),
552         );
553     }
554 
set_activatemode_function<F>(&self, func: F) where F: Fn(&Self, Option<&crate::Object>, crate::PadMode, bool) -> Result<(), LoggableError> + Send + Sync + 'static,555     unsafe fn set_activatemode_function<F>(&self, func: F)
556     where
557         F: Fn(&Self, Option<&crate::Object>, crate::PadMode, bool) -> Result<(), LoggableError>
558             + Send
559             + Sync
560             + 'static,
561     {
562         let func_box: Box<F> = Box::new(func);
563         ffi::gst_pad_set_activatemode_function_full(
564             self.as_ref().to_glib_none().0,
565             Some(trampoline_activatemode_function::<Self, F>),
566             Box::into_raw(func_box) as gpointer,
567             Some(destroy_closure::<F>),
568         );
569     }
570 
set_chain_function<F>(&self, func: F) where F: Fn(&Self, Option<&crate::Object>, crate::Buffer) -> Result<FlowSuccess, FlowError> + Send + Sync + 'static,571     unsafe fn set_chain_function<F>(&self, func: F)
572     where
573         F: Fn(&Self, Option<&crate::Object>, crate::Buffer) -> Result<FlowSuccess, FlowError>
574             + Send
575             + Sync
576             + 'static,
577     {
578         let func_box: Box<F> = Box::new(func);
579         ffi::gst_pad_set_chain_function_full(
580             self.as_ref().to_glib_none().0,
581             Some(trampoline_chain_function::<Self, F>),
582             Box::into_raw(func_box) as gpointer,
583             Some(destroy_closure::<F>),
584         );
585     }
586 
set_chain_list_function<F>(&self, func: F) where F: Fn(&Self, Option<&crate::Object>, crate::BufferList) -> Result<FlowSuccess, FlowError> + Send + Sync + 'static,587     unsafe fn set_chain_list_function<F>(&self, func: F)
588     where
589         F: Fn(&Self, Option<&crate::Object>, crate::BufferList) -> Result<FlowSuccess, FlowError>
590             + Send
591             + Sync
592             + 'static,
593     {
594         let func_box: Box<F> = Box::new(func);
595         ffi::gst_pad_set_chain_list_function_full(
596             self.as_ref().to_glib_none().0,
597             Some(trampoline_chain_list_function::<Self, F>),
598             Box::into_raw(func_box) as gpointer,
599             Some(destroy_closure::<F>),
600         );
601     }
602 
set_event_function<F>(&self, func: F) where F: Fn(&Self, Option<&crate::Object>, crate::Event) -> bool + Send + Sync + 'static,603     unsafe fn set_event_function<F>(&self, func: F)
604     where
605         F: Fn(&Self, Option<&crate::Object>, crate::Event) -> bool + Send + Sync + 'static,
606     {
607         let func_box: Box<F> = Box::new(func);
608         ffi::gst_pad_set_event_function_full(
609             self.as_ref().to_glib_none().0,
610             Some(trampoline_event_function::<Self, F>),
611             Box::into_raw(func_box) as gpointer,
612             Some(destroy_closure::<F>),
613         );
614     }
615 
set_event_full_function<F>(&self, func: F) where F: Fn(&Self, Option<&crate::Object>, crate::Event) -> Result<FlowSuccess, FlowError> + Send + Sync + 'static,616     unsafe fn set_event_full_function<F>(&self, func: F)
617     where
618         F: Fn(&Self, Option<&crate::Object>, crate::Event) -> Result<FlowSuccess, FlowError>
619             + Send
620             + Sync
621             + 'static,
622     {
623         let func_box: Box<F> = Box::new(func);
624         ffi::gst_pad_set_event_full_function_full(
625             self.as_ref().to_glib_none().0,
626             Some(trampoline_event_full_function::<Self, F>),
627             Box::into_raw(func_box) as gpointer,
628             Some(destroy_closure::<F>),
629         );
630     }
631 
set_getrange_function<F>(&self, func: F) where F: Fn( &Self, Option<&crate::Object>, u64, Option<&mut crate::BufferRef>, u32, ) -> Result<PadGetRangeSuccess, crate::FlowError> + Send + Sync + 'static,632     unsafe fn set_getrange_function<F>(&self, func: F)
633     where
634         F: Fn(
635                 &Self,
636                 Option<&crate::Object>,
637                 u64,
638                 Option<&mut crate::BufferRef>,
639                 u32,
640             ) -> Result<PadGetRangeSuccess, crate::FlowError>
641             + Send
642             + Sync
643             + 'static,
644     {
645         let func_box: Box<F> = Box::new(func);
646         ffi::gst_pad_set_getrange_function_full(
647             self.as_ref().to_glib_none().0,
648             Some(trampoline_getrange_function::<Self, F>),
649             Box::into_raw(func_box) as gpointer,
650             Some(destroy_closure::<F>),
651         );
652     }
653 
set_iterate_internal_links_function<F>(&self, func: F) where F: Fn(&Self, Option<&crate::Object>) -> crate::Iterator<Pad> + Send + Sync + 'static,654     unsafe fn set_iterate_internal_links_function<F>(&self, func: F)
655     where
656         F: Fn(&Self, Option<&crate::Object>) -> crate::Iterator<Pad> + Send + Sync + 'static,
657     {
658         let func_box: Box<F> = Box::new(func);
659         ffi::gst_pad_set_iterate_internal_links_function_full(
660             self.as_ref().to_glib_none().0,
661             Some(trampoline_iterate_internal_links_function::<Self, F>),
662             Box::into_raw(func_box) as gpointer,
663             Some(destroy_closure::<F>),
664         );
665     }
666 
set_link_function<F>(&self, func: F) where F: Fn( &Self, Option<&crate::Object>, &Pad, ) -> Result<crate::PadLinkSuccess, crate::PadLinkError> + Send + Sync + 'static,667     unsafe fn set_link_function<F>(&self, func: F)
668     where
669         F: Fn(
670                 &Self,
671                 Option<&crate::Object>,
672                 &Pad,
673             ) -> Result<crate::PadLinkSuccess, crate::PadLinkError>
674             + Send
675             + Sync
676             + 'static,
677     {
678         let func_box: Box<F> = Box::new(func);
679         ffi::gst_pad_set_link_function_full(
680             self.as_ref().to_glib_none().0,
681             Some(trampoline_link_function::<Self, F>),
682             Box::into_raw(func_box) as gpointer,
683             Some(destroy_closure::<F>),
684         );
685     }
686 
set_query_function<F>(&self, func: F) where F: Fn(&Self, Option<&crate::Object>, &mut crate::QueryRef) -> bool + Send + Sync + 'static,687     unsafe fn set_query_function<F>(&self, func: F)
688     where
689         F: Fn(&Self, Option<&crate::Object>, &mut crate::QueryRef) -> bool + Send + Sync + 'static,
690     {
691         let func_box: Box<F> = Box::new(func);
692         ffi::gst_pad_set_query_function_full(
693             self.as_ref().to_glib_none().0,
694             Some(trampoline_query_function::<Self, F>),
695             Box::into_raw(func_box) as gpointer,
696             Some(destroy_closure::<F>),
697         );
698     }
699 
set_unlink_function<F>(&self, func: F) where F: Fn(&Self, Option<&crate::Object>) + Send + Sync + 'static,700     unsafe fn set_unlink_function<F>(&self, func: F)
701     where
702         F: Fn(&Self, Option<&crate::Object>) + Send + Sync + 'static,
703     {
704         let func_box: Box<F> = Box::new(func);
705         ffi::gst_pad_set_unlink_function_full(
706             self.as_ref().to_glib_none().0,
707             Some(trampoline_unlink_function::<Self, F>),
708             Box::into_raw(func_box) as gpointer,
709             Some(destroy_closure::<F>),
710         );
711     }
712 
start_task<F: FnMut() + Send + 'static>(&self, func: F) -> Result<(), glib::BoolError>713     fn start_task<F: FnMut() + Send + 'static>(&self, func: F) -> Result<(), glib::BoolError> {
714         unsafe {
715             glib::result_from_gboolean!(
716                 ffi::gst_pad_start_task(
717                     self.as_ref().to_glib_none().0,
718                     Some(trampoline_pad_task::<F>),
719                     into_raw_pad_task(func),
720                     Some(destroy_closure_pad_task::<F>),
721                 ),
722                 "Failed to start pad task",
723             )
724         }
725     }
726 
peer_query_convert<V: Into<GenericFormattedValue>, U: SpecificFormattedValue>( &self, src_val: V, ) -> Option<U>727     fn peer_query_convert<V: Into<GenericFormattedValue>, U: SpecificFormattedValue>(
728         &self,
729         src_val: V,
730     ) -> Option<U> {
731         let src_val = src_val.into();
732         unsafe {
733             let mut dest_val = mem::MaybeUninit::uninit();
734             let ret = from_glib(ffi::gst_pad_peer_query_convert(
735                 self.as_ref().to_glib_none().0,
736                 src_val.format().into_glib(),
737                 src_val.into_raw_value(),
738                 U::default_format().into_glib(),
739                 dest_val.as_mut_ptr(),
740             ));
741             if ret {
742                 Some(U::from_raw(U::default_format(), dest_val.assume_init()))
743             } else {
744                 None
745             }
746         }
747     }
748 
peer_query_convert_generic<V: Into<GenericFormattedValue>>( &self, src_val: V, dest_format: Format, ) -> Option<GenericFormattedValue>749     fn peer_query_convert_generic<V: Into<GenericFormattedValue>>(
750         &self,
751         src_val: V,
752         dest_format: Format,
753     ) -> Option<GenericFormattedValue> {
754         let src_val = src_val.into();
755         unsafe {
756             let mut dest_val = mem::MaybeUninit::uninit();
757             let ret = from_glib(ffi::gst_pad_peer_query_convert(
758                 self.as_ref().to_glib_none().0,
759                 src_val.format().into_glib(),
760                 src_val.into_raw_value(),
761                 dest_format.into_glib(),
762                 dest_val.as_mut_ptr(),
763             ));
764             if ret {
765                 Some(GenericFormattedValue::new(
766                     dest_format,
767                     dest_val.assume_init(),
768                 ))
769             } else {
770                 None
771             }
772         }
773     }
774 
peer_query_duration<T: SpecificFormattedValueIntrinsic>(&self) -> Option<T>775     fn peer_query_duration<T: SpecificFormattedValueIntrinsic>(&self) -> Option<T> {
776         unsafe {
777             let mut duration = mem::MaybeUninit::uninit();
778             let ret = from_glib(ffi::gst_pad_peer_query_duration(
779                 self.as_ref().to_glib_none().0,
780                 T::FormattedValueType::default_format().into_glib(),
781                 duration.as_mut_ptr(),
782             ));
783             if ret {
784                 try_from_glib(duration.assume_init()).ok()
785             } else {
786                 None
787             }
788         }
789     }
790 
peer_query_duration_generic(&self, format: Format) -> Option<GenericFormattedValue>791     fn peer_query_duration_generic(&self, format: Format) -> Option<GenericFormattedValue> {
792         unsafe {
793             let mut duration = mem::MaybeUninit::uninit();
794             let ret = from_glib(ffi::gst_pad_peer_query_duration(
795                 self.as_ref().to_glib_none().0,
796                 format.into_glib(),
797                 duration.as_mut_ptr(),
798             ));
799             if ret {
800                 Some(GenericFormattedValue::new(format, duration.assume_init()))
801             } else {
802                 None
803             }
804         }
805     }
806 
peer_query_position<T: SpecificFormattedValueIntrinsic>(&self) -> Option<T>807     fn peer_query_position<T: SpecificFormattedValueIntrinsic>(&self) -> Option<T> {
808         unsafe {
809             let mut cur = mem::MaybeUninit::uninit();
810             let ret = from_glib(ffi::gst_pad_peer_query_position(
811                 self.as_ref().to_glib_none().0,
812                 T::FormattedValueType::default_format().into_glib(),
813                 cur.as_mut_ptr(),
814             ));
815             if ret {
816                 try_from_glib(cur.assume_init()).ok()
817             } else {
818                 None
819             }
820         }
821     }
822 
peer_query_position_generic(&self, format: Format) -> Option<GenericFormattedValue>823     fn peer_query_position_generic(&self, format: Format) -> Option<GenericFormattedValue> {
824         unsafe {
825             let mut cur = mem::MaybeUninit::uninit();
826             let ret = from_glib(ffi::gst_pad_peer_query_position(
827                 self.as_ref().to_glib_none().0,
828                 format.into_glib(),
829                 cur.as_mut_ptr(),
830             ));
831             if ret {
832                 Some(GenericFormattedValue::new(format, cur.assume_init()))
833             } else {
834                 None
835             }
836         }
837     }
838 
query_convert<V: Into<GenericFormattedValue>, U: SpecificFormattedValue>( &self, src_val: V, ) -> Option<U>839     fn query_convert<V: Into<GenericFormattedValue>, U: SpecificFormattedValue>(
840         &self,
841         src_val: V,
842     ) -> Option<U> {
843         let src_val = src_val.into();
844 
845         unsafe {
846             let mut dest_val = mem::MaybeUninit::uninit();
847             let ret = from_glib(ffi::gst_pad_query_convert(
848                 self.as_ref().to_glib_none().0,
849                 src_val.format().into_glib(),
850                 src_val.into_raw_value(),
851                 U::default_format().into_glib(),
852                 dest_val.as_mut_ptr(),
853             ));
854             if ret {
855                 Some(U::from_raw(U::default_format(), dest_val.assume_init()))
856             } else {
857                 None
858             }
859         }
860     }
861 
query_convert_generic<V: Into<GenericFormattedValue>>( &self, src_val: V, dest_format: Format, ) -> Option<GenericFormattedValue>862     fn query_convert_generic<V: Into<GenericFormattedValue>>(
863         &self,
864         src_val: V,
865         dest_format: Format,
866     ) -> Option<GenericFormattedValue> {
867         let src_val = src_val.into();
868 
869         unsafe {
870             let mut dest_val = mem::MaybeUninit::uninit();
871             let ret = from_glib(ffi::gst_pad_query_convert(
872                 self.as_ref().to_glib_none().0,
873                 src_val.format().into_glib(),
874                 src_val.value(),
875                 dest_format.into_glib(),
876                 dest_val.as_mut_ptr(),
877             ));
878             if ret {
879                 Some(GenericFormattedValue::new(
880                     dest_format,
881                     dest_val.assume_init(),
882                 ))
883             } else {
884                 None
885             }
886         }
887     }
888 
query_duration<T: SpecificFormattedValueIntrinsic>(&self) -> Option<T>889     fn query_duration<T: SpecificFormattedValueIntrinsic>(&self) -> Option<T> {
890         unsafe {
891             let mut duration = mem::MaybeUninit::uninit();
892             let ret = from_glib(ffi::gst_pad_query_duration(
893                 self.as_ref().to_glib_none().0,
894                 T::FormattedValueType::default_format().into_glib(),
895                 duration.as_mut_ptr(),
896             ));
897             if ret {
898                 try_from_glib(duration.assume_init()).ok()
899             } else {
900                 None
901             }
902         }
903     }
904 
query_duration_generic(&self, format: Format) -> Option<GenericFormattedValue>905     fn query_duration_generic(&self, format: Format) -> Option<GenericFormattedValue> {
906         unsafe {
907             let mut duration = mem::MaybeUninit::uninit();
908             let ret = from_glib(ffi::gst_pad_query_duration(
909                 self.as_ref().to_glib_none().0,
910                 format.into_glib(),
911                 duration.as_mut_ptr(),
912             ));
913             if ret {
914                 Some(GenericFormattedValue::new(format, duration.assume_init()))
915             } else {
916                 None
917             }
918         }
919     }
920 
query_position<T: SpecificFormattedValueIntrinsic>(&self) -> Option<T>921     fn query_position<T: SpecificFormattedValueIntrinsic>(&self) -> Option<T> {
922         unsafe {
923             let mut cur = mem::MaybeUninit::uninit();
924             let ret = from_glib(ffi::gst_pad_query_position(
925                 self.as_ref().to_glib_none().0,
926                 T::FormattedValueType::default_format().into_glib(),
927                 cur.as_mut_ptr(),
928             ));
929             if ret {
930                 try_from_glib(cur.assume_init()).ok()
931             } else {
932                 None
933             }
934         }
935     }
936 
query_position_generic(&self, format: Format) -> Option<GenericFormattedValue>937     fn query_position_generic(&self, format: Format) -> Option<GenericFormattedValue> {
938         unsafe {
939             let mut cur = mem::MaybeUninit::uninit();
940             let ret = from_glib(ffi::gst_pad_query_position(
941                 self.as_ref().to_glib_none().0,
942                 format.into_glib(),
943                 cur.as_mut_ptr(),
944             ));
945             if ret {
946                 Some(GenericFormattedValue::new(format, cur.assume_init()))
947             } else {
948                 None
949             }
950         }
951     }
952 
mode(&self) -> crate::PadMode953     fn mode(&self) -> crate::PadMode {
954         unsafe {
955             let ptr: &ffi::GstPad = &*(self.as_ptr() as *const _);
956             from_glib(ptr.mode)
957         }
958     }
959 
sticky_events_foreach<F: FnMut(Event) -> Result<Option<Event>, Option<Event>>>( &self, func: F, )960     fn sticky_events_foreach<F: FnMut(Event) -> Result<Option<Event>, Option<Event>>>(
961         &self,
962         func: F,
963     ) {
964         unsafe extern "C" fn trampoline(
965             _pad: *mut ffi::GstPad,
966             event: *mut *mut ffi::GstEvent,
967             user_data: glib::ffi::gpointer,
968         ) -> glib::ffi::gboolean {
969             let func =
970                 user_data as *mut &mut (dyn FnMut(Event) -> Result<Option<Event>, Option<Event>>);
971             let res = (*func)(from_glib_full(*event));
972 
973             match res {
974                 Ok(Some(ev)) => {
975                     *event = ev.into_ptr();
976                     glib::ffi::GTRUE
977                 }
978                 Err(Some(ev)) => {
979                     *event = ev.into_ptr();
980                     glib::ffi::GFALSE
981                 }
982                 Ok(None) => {
983                     *event = ptr::null_mut();
984                     glib::ffi::GTRUE
985                 }
986                 Err(None) => {
987                     *event = ptr::null_mut();
988                     glib::ffi::GFALSE
989                 }
990             }
991         }
992 
993         unsafe {
994             let mut func = func;
995             let func_obj: &mut (dyn FnMut(Event) -> Result<Option<Event>, Option<Event>>) =
996                 &mut func;
997             let func_ptr = &func_obj
998                 as *const &mut (dyn FnMut(Event) -> Result<Option<Event>, Option<Event>>)
999                 as glib::ffi::gpointer;
1000 
1001             ffi::gst_pad_sticky_events_foreach(
1002                 self.as_ref().to_glib_none().0,
1003                 Some(trampoline),
1004                 func_ptr,
1005             );
1006         }
1007     }
1008 
set_pad_flags(&self, flags: PadFlags)1009     fn set_pad_flags(&self, flags: PadFlags) {
1010         unsafe {
1011             let ptr: *mut ffi::GstObject = self.as_ptr() as *mut _;
1012             let _guard = crate::utils::MutexGuard::lock(&(*ptr).lock);
1013             (*ptr).flags |= flags.into_glib();
1014         }
1015     }
1016 
unset_pad_flags(&self, flags: PadFlags)1017     fn unset_pad_flags(&self, flags: PadFlags) {
1018         unsafe {
1019             let ptr: *mut ffi::GstObject = self.as_ptr() as *mut _;
1020             let _guard = crate::utils::MutexGuard::lock(&(*ptr).lock);
1021             (*ptr).flags &= !flags.into_glib();
1022         }
1023     }
1024 
pad_flags(&self) -> PadFlags1025     fn pad_flags(&self) -> PadFlags {
1026         unsafe {
1027             let ptr: *mut ffi::GstObject = self.as_ptr() as *mut _;
1028             let _guard = crate::utils::MutexGuard::lock(&(*ptr).lock);
1029             from_glib((*ptr).flags)
1030         }
1031     }
1032 }
1033 
create_probe_info<'a>( info: *mut ffi::GstPadProbeInfo, ) -> (PadProbeInfo<'a>, Option<glib::Type>)1034 unsafe fn create_probe_info<'a>(
1035     info: *mut ffi::GstPadProbeInfo,
1036 ) -> (PadProbeInfo<'a>, Option<glib::Type>) {
1037     let mut data_type = None;
1038     let flow_res = try_from_glib((*info).ABI.abi.flow_ret);
1039     let info = PadProbeInfo {
1040         mask: from_glib((*info).type_),
1041         id: Some(PadProbeId(NonZeroU64::new_unchecked((*info).id as u64))),
1042         offset: (*info).offset,
1043         size: (*info).size,
1044         data: if (*info).data.is_null() {
1045             None
1046         } else {
1047             let data = (*info).data as *mut ffi::GstMiniObject;
1048             (*info).data = ptr::null_mut();
1049             if (*data).type_ == Buffer::static_type().into_glib() {
1050                 data_type = Some(Buffer::static_type());
1051                 Some(PadProbeData::Buffer(from_glib_full(
1052                     data as *const ffi::GstBuffer,
1053                 )))
1054             } else if (*data).type_ == BufferList::static_type().into_glib() {
1055                 data_type = Some(BufferList::static_type());
1056                 Some(PadProbeData::BufferList(from_glib_full(
1057                     data as *const ffi::GstBufferList,
1058                 )))
1059             } else if (*data).type_ == Query::static_type().into_glib() {
1060                 data_type = Some(Query::static_type());
1061                 Some(PadProbeData::Query(QueryRef::from_mut_ptr(
1062                     data as *mut ffi::GstQuery,
1063                 )))
1064             } else if (*data).type_ == Event::static_type().into_glib() {
1065                 data_type = Some(Event::static_type());
1066                 Some(PadProbeData::Event(from_glib_full(
1067                     data as *const ffi::GstEvent,
1068                 )))
1069             } else {
1070                 Some(PadProbeData::__Unknown(data))
1071             }
1072         },
1073         flow_res,
1074     };
1075     (info, data_type)
1076 }
1077 
update_probe_info( ret: PadProbeReturn, probe_info: PadProbeInfo, data_type: Option<glib::Type>, info: *mut ffi::GstPadProbeInfo, )1078 unsafe fn update_probe_info(
1079     ret: PadProbeReturn,
1080     probe_info: PadProbeInfo,
1081     data_type: Option<glib::Type>,
1082     info: *mut ffi::GstPadProbeInfo,
1083 ) {
1084     if ret == PadProbeReturn::Handled {
1085         // Handled queries need to be returned
1086         // Handled buffers are consumed
1087         // No other types can safely be used here
1088 
1089         match probe_info.data {
1090             Some(PadProbeData::Query(query)) => {
1091                 assert_eq!(data_type, Some(Query::static_type()));
1092                 (*info).data = query.as_mut_ptr() as *mut libc::c_void;
1093             }
1094             Some(PadProbeData::Buffer(_)) => {
1095                 assert_eq!(data_type, Some(Buffer::static_type()));
1096                 // Buffer not consumed by probe; consume it here
1097             }
1098             Some(PadProbeData::Event(_)) => {
1099                 assert_eq!(data_type, Some(Event::static_type()));
1100                 // Event not consumed by probe; consume it here
1101             }
1102             None if data_type == Some(Buffer::static_type())
1103                 || data_type == Some(Event::static_type()) =>
1104             {
1105                 // Buffer or Event consumed by probe
1106             }
1107             other => panic!(
1108                 "Bad data for {:?} pad probe returning Handled: {:?}",
1109                 data_type, other
1110             ),
1111         }
1112     } else {
1113         match probe_info.data {
1114             Some(PadProbeData::Buffer(buffer)) => {
1115                 assert_eq!(data_type, Some(Buffer::static_type()));
1116                 (*info).data = buffer.into_ptr() as *mut libc::c_void;
1117             }
1118             Some(PadProbeData::BufferList(bufferlist)) => {
1119                 assert_eq!(data_type, Some(BufferList::static_type()));
1120                 (*info).data = bufferlist.into_ptr() as *mut libc::c_void;
1121             }
1122             Some(PadProbeData::Event(event)) => {
1123                 assert_eq!(data_type, Some(Event::static_type()));
1124                 (*info).data = event.into_ptr() as *mut libc::c_void;
1125             }
1126             Some(PadProbeData::Query(query)) => {
1127                 assert_eq!(data_type, Some(Query::static_type()));
1128                 (*info).data = query.as_mut_ptr() as *mut libc::c_void;
1129             }
1130             Some(PadProbeData::__Unknown(ptr)) => {
1131                 assert_eq!(data_type, None);
1132                 (*info).data = ptr as *mut libc::c_void;
1133             }
1134             None => {
1135                 assert_eq!(data_type, None);
1136             }
1137         }
1138     }
1139 
1140     let flow_ret: FlowReturn = probe_info.flow_res.into();
1141     (*info).ABI.abi.flow_ret = flow_ret.into_glib();
1142 }
1143 
trampoline_pad_probe< T, F: Fn(&T, &mut PadProbeInfo) -> PadProbeReturn + Send + Sync + 'static, >( pad: *mut ffi::GstPad, info: *mut ffi::GstPadProbeInfo, func: gpointer, ) -> ffi::GstPadProbeReturn where T: IsA<Pad>,1144 unsafe extern "C" fn trampoline_pad_probe<
1145     T,
1146     F: Fn(&T, &mut PadProbeInfo) -> PadProbeReturn + Send + Sync + 'static,
1147 >(
1148     pad: *mut ffi::GstPad,
1149     info: *mut ffi::GstPadProbeInfo,
1150     func: gpointer,
1151 ) -> ffi::GstPadProbeReturn
1152 where
1153     T: IsA<Pad>,
1154 {
1155     let func: &F = &*(func as *const F);
1156 
1157     let (mut probe_info, data_type) = create_probe_info(info);
1158 
1159     let ret = func(
1160         Pad::from_glib_borrow(pad).unsafe_cast_ref(),
1161         &mut probe_info,
1162     );
1163 
1164     update_probe_info(ret, probe_info, data_type, info);
1165 
1166     ret.into_glib()
1167 }
1168 
trampoline_activate_function< T, F: Fn(&T, Option<&crate::Object>) -> Result<(), LoggableError> + Send + Sync + 'static, >( pad: *mut ffi::GstPad, parent: *mut ffi::GstObject, ) -> glib::ffi::gboolean where T: IsA<Pad>,1169 unsafe extern "C" fn trampoline_activate_function<
1170     T,
1171     F: Fn(&T, Option<&crate::Object>) -> Result<(), LoggableError> + Send + Sync + 'static,
1172 >(
1173     pad: *mut ffi::GstPad,
1174     parent: *mut ffi::GstObject,
1175 ) -> glib::ffi::gboolean
1176 where
1177     T: IsA<Pad>,
1178 {
1179     let func: &F = &*((*pad).activatedata as *const F);
1180 
1181     match func(
1182         Pad::from_glib_borrow(pad).unsafe_cast_ref(),
1183         Option::<crate::Object>::from_glib_borrow(parent)
1184             .as_ref()
1185             .as_ref(),
1186     ) {
1187         Ok(()) => true,
1188         Err(err) => {
1189             err.log_with_object(&*Pad::from_glib_borrow(pad));
1190             false
1191         }
1192     }
1193     .into_glib()
1194 }
1195 
trampoline_activatemode_function< T, F: Fn(&T, Option<&crate::Object>, crate::PadMode, bool) -> Result<(), LoggableError> + Send + Sync + 'static, >( pad: *mut ffi::GstPad, parent: *mut ffi::GstObject, mode: ffi::GstPadMode, active: glib::ffi::gboolean, ) -> glib::ffi::gboolean where T: IsA<Pad>,1196 unsafe extern "C" fn trampoline_activatemode_function<
1197     T,
1198     F: Fn(&T, Option<&crate::Object>, crate::PadMode, bool) -> Result<(), LoggableError>
1199         + Send
1200         + Sync
1201         + 'static,
1202 >(
1203     pad: *mut ffi::GstPad,
1204     parent: *mut ffi::GstObject,
1205     mode: ffi::GstPadMode,
1206     active: glib::ffi::gboolean,
1207 ) -> glib::ffi::gboolean
1208 where
1209     T: IsA<Pad>,
1210 {
1211     let func: &F = &*((*pad).activatemodedata as *const F);
1212 
1213     match func(
1214         Pad::from_glib_borrow(pad).unsafe_cast_ref(),
1215         Option::<crate::Object>::from_glib_borrow(parent)
1216             .as_ref()
1217             .as_ref(),
1218         from_glib(mode),
1219         from_glib(active),
1220     ) {
1221         Ok(()) => true,
1222         Err(err) => {
1223             err.log_with_object(&*Pad::from_glib_borrow(pad));
1224             false
1225         }
1226     }
1227     .into_glib()
1228 }
1229 
trampoline_chain_function< T, F: Fn(&T, Option<&crate::Object>, crate::Buffer) -> Result<FlowSuccess, FlowError> + Send + Sync + 'static, >( pad: *mut ffi::GstPad, parent: *mut ffi::GstObject, buffer: *mut ffi::GstBuffer, ) -> ffi::GstFlowReturn where T: IsA<Pad>,1230 unsafe extern "C" fn trampoline_chain_function<
1231     T,
1232     F: Fn(&T, Option<&crate::Object>, crate::Buffer) -> Result<FlowSuccess, FlowError>
1233         + Send
1234         + Sync
1235         + 'static,
1236 >(
1237     pad: *mut ffi::GstPad,
1238     parent: *mut ffi::GstObject,
1239     buffer: *mut ffi::GstBuffer,
1240 ) -> ffi::GstFlowReturn
1241 where
1242     T: IsA<Pad>,
1243 {
1244     let func: &F = &*((*pad).chaindata as *const F);
1245 
1246     let res: FlowReturn = func(
1247         Pad::from_glib_borrow(pad).unsafe_cast_ref(),
1248         Option::<crate::Object>::from_glib_borrow(parent)
1249             .as_ref()
1250             .as_ref(),
1251         from_glib_full(buffer),
1252     )
1253     .into();
1254     res.into_glib()
1255 }
1256 
trampoline_chain_list_function< T, F: Fn(&T, Option<&crate::Object>, crate::BufferList) -> Result<FlowSuccess, FlowError> + Send + Sync + 'static, >( pad: *mut ffi::GstPad, parent: *mut ffi::GstObject, list: *mut ffi::GstBufferList, ) -> ffi::GstFlowReturn where T: IsA<Pad>,1257 unsafe extern "C" fn trampoline_chain_list_function<
1258     T,
1259     F: Fn(&T, Option<&crate::Object>, crate::BufferList) -> Result<FlowSuccess, FlowError>
1260         + Send
1261         + Sync
1262         + 'static,
1263 >(
1264     pad: *mut ffi::GstPad,
1265     parent: *mut ffi::GstObject,
1266     list: *mut ffi::GstBufferList,
1267 ) -> ffi::GstFlowReturn
1268 where
1269     T: IsA<Pad>,
1270 {
1271     let func: &F = &*((*pad).chainlistdata as *const F);
1272 
1273     let res: FlowReturn = func(
1274         Pad::from_glib_borrow(pad).unsafe_cast_ref(),
1275         Option::<crate::Object>::from_glib_borrow(parent)
1276             .as_ref()
1277             .as_ref(),
1278         from_glib_full(list),
1279     )
1280     .into();
1281     res.into_glib()
1282 }
1283 
trampoline_event_function< T, F: Fn(&T, Option<&crate::Object>, crate::Event) -> bool + Send + Sync + 'static, >( pad: *mut ffi::GstPad, parent: *mut ffi::GstObject, event: *mut ffi::GstEvent, ) -> glib::ffi::gboolean where T: IsA<Pad>,1284 unsafe extern "C" fn trampoline_event_function<
1285     T,
1286     F: Fn(&T, Option<&crate::Object>, crate::Event) -> bool + Send + Sync + 'static,
1287 >(
1288     pad: *mut ffi::GstPad,
1289     parent: *mut ffi::GstObject,
1290     event: *mut ffi::GstEvent,
1291 ) -> glib::ffi::gboolean
1292 where
1293     T: IsA<Pad>,
1294 {
1295     let func: &F = &*((*pad).eventdata as *const F);
1296 
1297     func(
1298         Pad::from_glib_borrow(pad).unsafe_cast_ref(),
1299         Option::<crate::Object>::from_glib_borrow(parent)
1300             .as_ref()
1301             .as_ref(),
1302         from_glib_full(event),
1303     )
1304     .into_glib()
1305 }
1306 
trampoline_event_full_function< T, F: Fn(&T, Option<&crate::Object>, crate::Event) -> Result<FlowSuccess, FlowError> + Send + Sync + 'static, >( pad: *mut ffi::GstPad, parent: *mut ffi::GstObject, event: *mut ffi::GstEvent, ) -> ffi::GstFlowReturn where T: IsA<Pad>,1307 unsafe extern "C" fn trampoline_event_full_function<
1308     T,
1309     F: Fn(&T, Option<&crate::Object>, crate::Event) -> Result<FlowSuccess, FlowError>
1310         + Send
1311         + Sync
1312         + 'static,
1313 >(
1314     pad: *mut ffi::GstPad,
1315     parent: *mut ffi::GstObject,
1316     event: *mut ffi::GstEvent,
1317 ) -> ffi::GstFlowReturn
1318 where
1319     T: IsA<Pad>,
1320 {
1321     let func: &F = &*((*pad).eventdata as *const F);
1322 
1323     let res: FlowReturn = func(
1324         Pad::from_glib_borrow(pad).unsafe_cast_ref(),
1325         Option::<crate::Object>::from_glib_borrow(parent)
1326             .as_ref()
1327             .as_ref(),
1328         from_glib_full(event),
1329     )
1330     .into();
1331     res.into_glib()
1332 }
1333 
trampoline_getrange_function< T, F: Fn( &T, Option<&crate::Object>, u64, Option<&mut crate::BufferRef>, u32, ) -> Result<PadGetRangeSuccess, crate::FlowError> + Send + Sync + 'static, >( pad: *mut ffi::GstPad, parent: *mut ffi::GstObject, offset: u64, length: u32, buffer: *mut *mut ffi::GstBuffer, ) -> ffi::GstFlowReturn where T: IsA<Pad>,1334 unsafe extern "C" fn trampoline_getrange_function<
1335     T,
1336     F: Fn(
1337             &T,
1338             Option<&crate::Object>,
1339             u64,
1340             Option<&mut crate::BufferRef>,
1341             u32,
1342         ) -> Result<PadGetRangeSuccess, crate::FlowError>
1343         + Send
1344         + Sync
1345         + 'static,
1346 >(
1347     pad: *mut ffi::GstPad,
1348     parent: *mut ffi::GstObject,
1349     offset: u64,
1350     length: u32,
1351     buffer: *mut *mut ffi::GstBuffer,
1352 ) -> ffi::GstFlowReturn
1353 where
1354     T: IsA<Pad>,
1355 {
1356     let func: &F = &*((*pad).getrangedata as *const F);
1357 
1358     assert!(!buffer.is_null());
1359 
1360     let pad = Pad::from_glib_borrow(pad);
1361     let pad = pad.unsafe_cast_ref();
1362     let mut passed_buffer = if (*buffer).is_null() {
1363         None
1364     } else {
1365         Some(crate::BufferRef::from_mut_ptr(*buffer))
1366     };
1367 
1368     match func(
1369         pad,
1370         Option::<crate::Object>::from_glib_borrow(parent)
1371             .as_ref()
1372             .as_ref(),
1373         offset,
1374         passed_buffer.as_deref_mut(),
1375         length,
1376     ) {
1377         Ok(PadGetRangeSuccess::NewBuffer(new_buffer)) => {
1378             if let Some(passed_buffer) = passed_buffer {
1379                 gst_debug!(
1380                     crate::CAT_PERFORMANCE,
1381                     obj: pad.unsafe_cast_ref::<glib::Object>(),
1382                     "Returned new buffer from getrange function, copying into passed buffer"
1383                 );
1384 
1385                 let mut map = match passed_buffer.map_writable() {
1386                     Ok(map) => map,
1387                     Err(_) => {
1388                         gst_error!(
1389                             crate::CAT_RUST,
1390                             obj: pad.unsafe_cast_ref::<glib::Object>(),
1391                             "Failed to map passed buffer writable"
1392                         );
1393                         return ffi::GST_FLOW_ERROR;
1394                     }
1395                 };
1396 
1397                 let copied_size = new_buffer.copy_to_slice(0, &mut *map);
1398                 drop(map);
1399 
1400                 if let Err(copied_size) = copied_size {
1401                     passed_buffer.set_size(copied_size);
1402                 }
1403 
1404                 match new_buffer.copy_into(passed_buffer, crate::BUFFER_COPY_METADATA, 0, None) {
1405                     Ok(_) => FlowReturn::Ok.into_glib(),
1406                     Err(_) => {
1407                         gst_error!(
1408                             crate::CAT_RUST,
1409                             obj: pad.unsafe_cast_ref::<glib::Object>(),
1410                             "Failed to copy buffer metadata"
1411                         );
1412 
1413                         FlowReturn::Error.into_glib()
1414                     }
1415                 }
1416             } else {
1417                 *buffer = new_buffer.into_ptr();
1418                 FlowReturn::Ok.into_glib()
1419             }
1420         }
1421         Ok(PadGetRangeSuccess::FilledBuffer) => {
1422             assert!(passed_buffer.is_some());
1423             FlowReturn::Ok.into_glib()
1424         }
1425         Err(ret) => FlowReturn::from_error(ret).into_glib(),
1426     }
1427 }
1428 
trampoline_iterate_internal_links_function< T, F: Fn(&T, Option<&crate::Object>) -> crate::Iterator<Pad> + Send + Sync + 'static, >( pad: *mut ffi::GstPad, parent: *mut ffi::GstObject, ) -> *mut ffi::GstIterator where T: IsA<Pad>,1429 unsafe extern "C" fn trampoline_iterate_internal_links_function<
1430     T,
1431     F: Fn(&T, Option<&crate::Object>) -> crate::Iterator<Pad> + Send + Sync + 'static,
1432 >(
1433     pad: *mut ffi::GstPad,
1434     parent: *mut ffi::GstObject,
1435 ) -> *mut ffi::GstIterator
1436 where
1437     T: IsA<Pad>,
1438 {
1439     let func: &F = &*((*pad).iterintlinkdata as *const F);
1440 
1441     // Steal the iterator and return it
1442     let ret = func(
1443         Pad::from_glib_borrow(pad).unsafe_cast_ref(),
1444         Option::<crate::Object>::from_glib_borrow(parent)
1445             .as_ref()
1446             .as_ref(),
1447     );
1448 
1449     ret.into_ptr()
1450 }
1451 
trampoline_link_function< T, F: Fn( &T, Option<&crate::Object>, &crate::Pad, ) -> Result<crate::PadLinkSuccess, crate::PadLinkError> + Send + Sync + 'static, >( pad: *mut ffi::GstPad, parent: *mut ffi::GstObject, peer: *mut ffi::GstPad, ) -> ffi::GstPadLinkReturn where T: IsA<Pad>,1452 unsafe extern "C" fn trampoline_link_function<
1453     T,
1454     F: Fn(
1455             &T,
1456             Option<&crate::Object>,
1457             &crate::Pad,
1458         ) -> Result<crate::PadLinkSuccess, crate::PadLinkError>
1459         + Send
1460         + Sync
1461         + 'static,
1462 >(
1463     pad: *mut ffi::GstPad,
1464     parent: *mut ffi::GstObject,
1465     peer: *mut ffi::GstPad,
1466 ) -> ffi::GstPadLinkReturn
1467 where
1468     T: IsA<Pad>,
1469 {
1470     let func: &F = &*((*pad).linkdata as *const F);
1471 
1472     let res: crate::PadLinkReturn = func(
1473         Pad::from_glib_borrow(pad).unsafe_cast_ref(),
1474         Option::<crate::Object>::from_glib_borrow(parent)
1475             .as_ref()
1476             .as_ref(),
1477         &from_glib_borrow(peer),
1478     )
1479     .into();
1480     res.into_glib()
1481 }
1482 
trampoline_query_function< T, F: Fn(&T, Option<&crate::Object>, &mut crate::QueryRef) -> bool + Send + Sync + 'static, >( pad: *mut ffi::GstPad, parent: *mut ffi::GstObject, query: *mut ffi::GstQuery, ) -> glib::ffi::gboolean where T: IsA<Pad>,1483 unsafe extern "C" fn trampoline_query_function<
1484     T,
1485     F: Fn(&T, Option<&crate::Object>, &mut crate::QueryRef) -> bool + Send + Sync + 'static,
1486 >(
1487     pad: *mut ffi::GstPad,
1488     parent: *mut ffi::GstObject,
1489     query: *mut ffi::GstQuery,
1490 ) -> glib::ffi::gboolean
1491 where
1492     T: IsA<Pad>,
1493 {
1494     let func: &F = &*((*pad).querydata as *const F);
1495 
1496     func(
1497         Pad::from_glib_borrow(pad).unsafe_cast_ref(),
1498         Option::<crate::Object>::from_glib_borrow(parent)
1499             .as_ref()
1500             .as_ref(),
1501         crate::QueryRef::from_mut_ptr(query),
1502     )
1503     .into_glib()
1504 }
1505 
trampoline_unlink_function< T, F: Fn(&T, Option<&crate::Object>) + Send + Sync + 'static, >( pad: *mut ffi::GstPad, parent: *mut ffi::GstObject, ) where T: IsA<Pad>,1506 unsafe extern "C" fn trampoline_unlink_function<
1507     T,
1508     F: Fn(&T, Option<&crate::Object>) + Send + Sync + 'static,
1509 >(
1510     pad: *mut ffi::GstPad,
1511     parent: *mut ffi::GstObject,
1512 ) where
1513     T: IsA<Pad>,
1514 {
1515     let func: &F = &*((*pad).unlinkdata as *const F);
1516 
1517     func(
1518         Pad::from_glib_borrow(pad).unsafe_cast_ref(),
1519         Option::<crate::Object>::from_glib_borrow(parent)
1520             .as_ref()
1521             .as_ref(),
1522     )
1523 }
1524 
destroy_closure<F>(ptr: gpointer)1525 unsafe extern "C" fn destroy_closure<F>(ptr: gpointer) {
1526     Box::<F>::from_raw(ptr as *mut _);
1527 }
1528 
trampoline_pad_task<F: FnMut() + Send + 'static>(func: gpointer)1529 unsafe extern "C" fn trampoline_pad_task<F: FnMut() + Send + 'static>(func: gpointer) {
1530     let func: &RefCell<F> = &*(func as *const RefCell<F>);
1531     (&mut *func.borrow_mut())()
1532 }
1533 
into_raw_pad_task<F: FnMut() + Send + 'static>(func: F) -> gpointer1534 fn into_raw_pad_task<F: FnMut() + Send + 'static>(func: F) -> gpointer {
1535     #[allow(clippy::type_complexity)]
1536     let func: Box<RefCell<F>> = Box::new(RefCell::new(func));
1537     Box::into_raw(func) as gpointer
1538 }
1539 
destroy_closure_pad_task<F>(ptr: gpointer)1540 unsafe extern "C" fn destroy_closure_pad_task<F>(ptr: gpointer) {
1541     Box::<RefCell<F>>::from_raw(ptr as *mut _);
1542 }
1543 
1544 impl Pad {
new(name: Option<&str>, direction: crate::PadDirection) -> Self1545     pub fn new(name: Option<&str>, direction: crate::PadDirection) -> Self {
1546         skip_assert_initialized!();
1547         Self::builder(name, direction).build()
1548     }
1549 
builder(name: Option<&str>, direction: crate::PadDirection) -> PadBuilder<Self>1550     pub fn builder(name: Option<&str>, direction: crate::PadDirection) -> PadBuilder<Self> {
1551         skip_assert_initialized!();
1552         PadBuilder::new(name, direction)
1553     }
1554 
from_static_template(templ: &StaticPadTemplate, name: Option<&str>) -> Self1555     pub fn from_static_template(templ: &StaticPadTemplate, name: Option<&str>) -> Self {
1556         skip_assert_initialized!();
1557         Self::builder_with_static_template(templ, name).build()
1558     }
1559 
builder_with_static_template( templ: &StaticPadTemplate, name: Option<&str>, ) -> PadBuilder<Self>1560     pub fn builder_with_static_template(
1561         templ: &StaticPadTemplate,
1562         name: Option<&str>,
1563     ) -> PadBuilder<Self> {
1564         skip_assert_initialized!();
1565         PadBuilder::from_static_template(templ, name)
1566     }
1567 
from_template(templ: &crate::PadTemplate, name: Option<&str>) -> Self1568     pub fn from_template(templ: &crate::PadTemplate, name: Option<&str>) -> Self {
1569         skip_assert_initialized!();
1570         Self::builder_with_template(templ, name).build()
1571     }
1572 
builder_with_template( templ: &crate::PadTemplate, name: Option<&str>, ) -> PadBuilder<Self>1573     pub fn builder_with_template(
1574         templ: &crate::PadTemplate,
1575         name: Option<&str>,
1576     ) -> PadBuilder<Self> {
1577         skip_assert_initialized!();
1578         PadBuilder::from_template(templ, name)
1579     }
1580 }
1581 
1582 pub struct PadBuilder<T>(pub(crate) T);
1583 
1584 impl<T: IsA<Pad> + IsA<glib::Object> + glib::object::IsClass> PadBuilder<T> {
new(name: Option<&str>, direction: crate::PadDirection) -> Self1585     pub fn new(name: Option<&str>, direction: crate::PadDirection) -> Self {
1586         assert_initialized_main_thread!();
1587 
1588         let pad = glib::Object::new::<T>(&[("name", &name), ("direction", &direction)])
1589             .expect("Failed to create pad");
1590 
1591         // Ghost pads are a bit special
1592         if let Some(pad) = pad.dynamic_cast_ref::<crate::GhostPad>() {
1593             unsafe {
1594                 let res = ffi::gst_ghost_pad_construct(pad.to_glib_none().0);
1595                 // This can't really fail...
1596                 assert_ne!(res, glib::ffi::GFALSE, "Failed to construct ghost pad");
1597             }
1598         }
1599 
1600         PadBuilder(pad)
1601     }
1602 
from_static_template(templ: &StaticPadTemplate, name: Option<&str>) -> Self1603     pub fn from_static_template(templ: &StaticPadTemplate, name: Option<&str>) -> Self {
1604         assert_initialized_main_thread!();
1605 
1606         let templ = templ.get();
1607         Self::from_template(&templ, name)
1608     }
1609 
from_template(templ: &crate::PadTemplate, name: Option<&str>) -> Self1610     pub fn from_template(templ: &crate::PadTemplate, name: Option<&str>) -> Self {
1611         assert_initialized_main_thread!();
1612 
1613         let mut type_ = T::static_type();
1614 
1615         // Since 1.14 templates can keep a pad GType with them, so we need to do some
1616         // additional checks here now
1617         if templ.has_property("gtype", Some(glib::Type::static_type())) {
1618             let gtype = templ
1619                 .property("gtype")
1620                 .unwrap()
1621                 .get::<glib::Type>()
1622                 .unwrap();
1623 
1624             if gtype == glib::Type::UNIT {
1625                 // Nothing to be done, we can create any kind of pad
1626             } else if gtype.is_a(type_) {
1627                 // We were asked to create a parent type of the template type, e.g. a gst::Pad for
1628                 // a template that wants a gst_base::AggregatorPad. Not a problem: update the type
1629                 type_ = gtype;
1630             } else {
1631                 // Otherwise the requested type must be a subclass of the template pad type
1632                 assert!(type_.is_a(gtype));
1633             }
1634         }
1635 
1636         let pad = glib::Object::with_type(
1637             type_,
1638             &[
1639                 ("name", &name),
1640                 ("direction", &templ.direction()),
1641                 ("template", templ),
1642             ],
1643         )
1644         .expect("Failed to create pad")
1645         .downcast::<T>()
1646         .unwrap();
1647 
1648         // Ghost pads are a bit special
1649         if let Some(pad) = pad.dynamic_cast_ref::<crate::GhostPad>() {
1650             unsafe {
1651                 let res = ffi::gst_ghost_pad_construct(pad.to_glib_none().0);
1652                 // This can't really fail...
1653                 assert_ne!(res, glib::ffi::GFALSE, "Failed to construct ghost pad");
1654             }
1655         }
1656 
1657         PadBuilder(pad)
1658     }
1659 
activate_function<F>(self, func: F) -> Self where F: Fn(&T, Option<&crate::Object>) -> Result<(), LoggableError> + Send + Sync + 'static,1660     pub fn activate_function<F>(self, func: F) -> Self
1661     where
1662         F: Fn(&T, Option<&crate::Object>) -> Result<(), LoggableError> + Send + Sync + 'static,
1663     {
1664         unsafe {
1665             self.0.set_activate_function(func);
1666         }
1667 
1668         self
1669     }
1670 
activatemode_function<F>(self, func: F) -> Self where F: Fn(&T, Option<&crate::Object>, crate::PadMode, bool) -> Result<(), LoggableError> + Send + Sync + 'static,1671     pub fn activatemode_function<F>(self, func: F) -> Self
1672     where
1673         F: Fn(&T, Option<&crate::Object>, crate::PadMode, bool) -> Result<(), LoggableError>
1674             + Send
1675             + Sync
1676             + 'static,
1677     {
1678         unsafe {
1679             self.0.set_activatemode_function(func);
1680         }
1681 
1682         self
1683     }
1684 
chain_function<F>(self, func: F) -> Self where F: Fn(&T, Option<&crate::Object>, crate::Buffer) -> Result<FlowSuccess, FlowError> + Send + Sync + 'static,1685     pub fn chain_function<F>(self, func: F) -> Self
1686     where
1687         F: Fn(&T, Option<&crate::Object>, crate::Buffer) -> Result<FlowSuccess, FlowError>
1688             + Send
1689             + Sync
1690             + 'static,
1691     {
1692         unsafe {
1693             self.0.set_chain_function(func);
1694         }
1695 
1696         self
1697     }
1698 
chain_list_function<F>(self, func: F) -> Self where F: Fn(&T, Option<&crate::Object>, crate::BufferList) -> Result<FlowSuccess, FlowError> + Send + Sync + 'static,1699     pub fn chain_list_function<F>(self, func: F) -> Self
1700     where
1701         F: Fn(&T, Option<&crate::Object>, crate::BufferList) -> Result<FlowSuccess, FlowError>
1702             + Send
1703             + Sync
1704             + 'static,
1705     {
1706         unsafe {
1707             self.0.set_chain_list_function(func);
1708         }
1709 
1710         self
1711     }
1712 
event_function<F>(self, func: F) -> Self where F: Fn(&T, Option<&crate::Object>, crate::Event) -> bool + Send + Sync + 'static,1713     pub fn event_function<F>(self, func: F) -> Self
1714     where
1715         F: Fn(&T, Option<&crate::Object>, crate::Event) -> bool + Send + Sync + 'static,
1716     {
1717         unsafe {
1718             self.0.set_event_function(func);
1719         }
1720 
1721         self
1722     }
1723 
event_full_function<F>(self, func: F) -> Self where F: Fn(&T, Option<&crate::Object>, crate::Event) -> Result<FlowSuccess, FlowError> + Send + Sync + 'static,1724     pub fn event_full_function<F>(self, func: F) -> Self
1725     where
1726         F: Fn(&T, Option<&crate::Object>, crate::Event) -> Result<FlowSuccess, FlowError>
1727             + Send
1728             + Sync
1729             + 'static,
1730     {
1731         unsafe {
1732             self.0.set_event_full_function(func);
1733         }
1734 
1735         self
1736     }
1737 
getrange_function<F>(self, func: F) -> Self where F: Fn( &T, Option<&crate::Object>, u64, Option<&mut crate::BufferRef>, u32, ) -> Result<PadGetRangeSuccess, crate::FlowError> + Send + Sync + 'static,1738     pub fn getrange_function<F>(self, func: F) -> Self
1739     where
1740         F: Fn(
1741                 &T,
1742                 Option<&crate::Object>,
1743                 u64,
1744                 Option<&mut crate::BufferRef>,
1745                 u32,
1746             ) -> Result<PadGetRangeSuccess, crate::FlowError>
1747             + Send
1748             + Sync
1749             + 'static,
1750     {
1751         unsafe {
1752             self.0.set_getrange_function(func);
1753         }
1754 
1755         self
1756     }
1757 
iterate_internal_links_function<F>(self, func: F) -> Self where F: Fn(&T, Option<&crate::Object>) -> crate::Iterator<Pad> + Send + Sync + 'static,1758     pub fn iterate_internal_links_function<F>(self, func: F) -> Self
1759     where
1760         F: Fn(&T, Option<&crate::Object>) -> crate::Iterator<Pad> + Send + Sync + 'static,
1761     {
1762         unsafe {
1763             self.0.set_iterate_internal_links_function(func);
1764         }
1765 
1766         self
1767     }
1768 
link_function<F>(self, func: F) -> Self where F: Fn( &T, Option<&crate::Object>, &Pad, ) -> Result<crate::PadLinkSuccess, crate::PadLinkError> + Send + Sync + 'static,1769     pub fn link_function<F>(self, func: F) -> Self
1770     where
1771         F: Fn(
1772                 &T,
1773                 Option<&crate::Object>,
1774                 &Pad,
1775             ) -> Result<crate::PadLinkSuccess, crate::PadLinkError>
1776             + Send
1777             + Sync
1778             + 'static,
1779     {
1780         unsafe {
1781             self.0.set_link_function(func);
1782         }
1783 
1784         self
1785     }
1786 
query_function<F>(self, func: F) -> Self where F: Fn(&T, Option<&crate::Object>, &mut crate::QueryRef) -> bool + Send + Sync + 'static,1787     pub fn query_function<F>(self, func: F) -> Self
1788     where
1789         F: Fn(&T, Option<&crate::Object>, &mut crate::QueryRef) -> bool + Send + Sync + 'static,
1790     {
1791         unsafe {
1792             self.0.set_query_function(func);
1793         }
1794 
1795         self
1796     }
1797 
unlink_function<F>(self, func: F) -> Self where F: Fn(&T, Option<&crate::Object>) + Send + Sync + 'static,1798     pub fn unlink_function<F>(self, func: F) -> Self
1799     where
1800         F: Fn(&T, Option<&crate::Object>) + Send + Sync + 'static,
1801     {
1802         unsafe {
1803             self.0.set_unlink_function(func);
1804         }
1805 
1806         self
1807     }
1808 
flags(self, flags: PadFlags) -> Self1809     pub fn flags(self, flags: PadFlags) -> Self {
1810         self.0.set_pad_flags(flags);
1811 
1812         self
1813     }
1814 
build(self) -> T1815     pub fn build(self) -> T {
1816         self.0
1817     }
1818 }
1819 
1820 #[cfg(test)]
1821 mod tests {
1822     use super::*;
1823     use crate::prelude::*;
1824     use std::sync::{atomic::AtomicUsize, mpsc::channel};
1825     use std::sync::{Arc, Mutex};
1826 
1827     #[test]
test_event_chain_functions()1828     fn test_event_chain_functions() {
1829         crate::init().unwrap();
1830 
1831         let events = Arc::new(Mutex::new(Vec::new()));
1832         let events_clone = events.clone();
1833         let buffers = Arc::new(Mutex::new(Vec::new()));
1834         let buffers_clone = buffers.clone();
1835         let pad = crate::Pad::builder(Some("sink"), crate::PadDirection::Sink)
1836             .event_function(move |_, _, event| {
1837                 let mut events = events_clone.lock().unwrap();
1838                 events.push(event);
1839 
1840                 true
1841             })
1842             .chain_function(move |_, _, buffer| {
1843                 let mut buffers = buffers_clone.lock().unwrap();
1844                 buffers.push(buffer);
1845 
1846                 Ok(FlowSuccess::Ok)
1847             })
1848             .build();
1849 
1850         pad.set_active(true).unwrap();
1851 
1852         assert!(pad.send_event(crate::event::StreamStart::new("test")));
1853         let segment = crate::FormattedSegment::<crate::ClockTime>::new();
1854         assert!(pad.send_event(crate::event::Segment::new(segment.as_ref())));
1855 
1856         assert_eq!(pad.chain(crate::Buffer::new()), Ok(FlowSuccess::Ok));
1857 
1858         let events = events.lock().unwrap();
1859         let buffers = buffers.lock().unwrap();
1860         assert_eq!(events.len(), 2);
1861         assert_eq!(buffers.len(), 1);
1862 
1863         match events[0].view() {
1864             crate::EventView::StreamStart(..) => (),
1865             _ => unreachable!(),
1866         }
1867 
1868         match events[1].view() {
1869             crate::EventView::Segment(..) => (),
1870             _ => unreachable!(),
1871         }
1872     }
1873 
1874     #[test]
test_getrange_function()1875     fn test_getrange_function() {
1876         crate::init().unwrap();
1877 
1878         let pad = crate::Pad::builder(Some("src"), crate::PadDirection::Src)
1879             .activate_function(|pad, _parent| {
1880                 pad.activate_mode(crate::PadMode::Pull, true)
1881                     .map_err(|err| err.into())
1882             })
1883             .getrange_function(|_pad, _parent, offset, _buffer, size| {
1884                 assert_eq!(offset, 0);
1885                 assert_eq!(size, 5);
1886                 let buffer = crate::Buffer::from_slice(b"abcde");
1887                 Ok(PadGetRangeSuccess::NewBuffer(buffer))
1888             })
1889             .build();
1890         pad.set_active(true).unwrap();
1891 
1892         let buffer = pad.range(0, 5).unwrap();
1893         let map = buffer.map_readable().unwrap();
1894         assert_eq!(&*map, b"abcde");
1895 
1896         let mut buffer = crate::Buffer::with_size(5).unwrap();
1897         pad.range_fill(0, buffer.get_mut().unwrap(), 5).unwrap();
1898         let map = buffer.map_readable().unwrap();
1899         assert_eq!(&*map, b"abcde");
1900 
1901         pad.set_active(false).unwrap();
1902         drop(pad);
1903 
1904         let pad = crate::Pad::builder(Some("src"), crate::PadDirection::Src)
1905             .activate_function(|pad, _parent| {
1906                 pad.activate_mode(crate::PadMode::Pull, true)
1907                     .map_err(|err| err.into())
1908             })
1909             .getrange_function(|_pad, _parent, offset, buffer, size| {
1910                 assert_eq!(offset, 0);
1911                 assert_eq!(size, 5);
1912                 if let Some(buffer) = buffer {
1913                     buffer.copy_from_slice(0, b"fghij").unwrap();
1914                     Ok(PadGetRangeSuccess::FilledBuffer)
1915                 } else {
1916                     let buffer = crate::Buffer::from_slice(b"abcde");
1917                     Ok(PadGetRangeSuccess::NewBuffer(buffer))
1918                 }
1919             })
1920             .build();
1921         pad.set_active(true).unwrap();
1922 
1923         let buffer = pad.range(0, 5).unwrap();
1924         let map = buffer.map_readable().unwrap();
1925         assert_eq!(&*map, b"abcde");
1926 
1927         let mut buffer = crate::Buffer::with_size(5).unwrap();
1928         pad.range_fill(0, buffer.get_mut().unwrap(), 5).unwrap();
1929         let map = buffer.map_readable().unwrap();
1930         assert_eq!(&*map, b"fghij");
1931     }
1932 
1933     #[test]
test_task()1934     fn test_task() {
1935         crate::init().unwrap();
1936 
1937         let pad = crate::Pad::new(Some("sink"), crate::PadDirection::Sink);
1938         let (sender, receiver) = channel();
1939 
1940         let mut i = 0;
1941         let pad_clone = pad.clone();
1942         pad.start_task(move || {
1943             i += 1;
1944             if i == 3 {
1945                 sender.send(i).unwrap();
1946                 pad_clone.pause_task().unwrap();
1947             }
1948         })
1949         .unwrap();
1950 
1951         assert_eq!(receiver.recv().unwrap(), 3);
1952     }
1953 
1954     #[test]
test_remove_probe_from_probe()1955     fn test_remove_probe_from_probe() {
1956         crate::init().unwrap();
1957 
1958         let src_pad = crate::Pad::new(Some("src"), crate::PadDirection::Src);
1959         let sink_pad = crate::Pad::builder(Some("sink"), crate::PadDirection::Sink)
1960             .chain_function(|_pad, _parent, _buffer| Ok(crate::FlowSuccess::Ok))
1961             .build();
1962 
1963         src_pad.link(&sink_pad).unwrap();
1964 
1965         let counter = Arc::new(AtomicUsize::new(0));
1966         let counter_clone = counter.clone();
1967         src_pad.add_probe(crate::PadProbeType::BUFFER, move |pad, info| {
1968             if let Some(PadProbeData::Buffer(_)) = info.data {
1969                 counter_clone.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
1970                 pad.remove_probe(info.id.take().expect("no pad probe id"));
1971             } else {
1972                 unreachable!();
1973             }
1974             crate::PadProbeReturn::Handled
1975         });
1976 
1977         sink_pad.set_active(true).unwrap();
1978         src_pad.set_active(true).unwrap();
1979 
1980         assert!(src_pad.push_event(crate::event::StreamStart::new("test")));
1981         let segment = crate::FormattedSegment::<crate::ClockTime>::new();
1982         assert!(src_pad.push_event(crate::event::Segment::new(segment.as_ref())));
1983 
1984         assert_eq!(src_pad.push(crate::Buffer::new()), Ok(FlowSuccess::Ok));
1985         assert_eq!(src_pad.push(crate::Buffer::new()), Ok(FlowSuccess::Ok));
1986 
1987         assert_eq!(counter.load(std::sync::atomic::Ordering::SeqCst), 1);
1988     }
1989 
1990     #[test]
test_probe()1991     fn test_probe() {
1992         crate::init().unwrap();
1993 
1994         let (major, minor, micro, _) = crate::version();
1995         let pad = crate::Pad::new(Some("src"), crate::PadDirection::Src);
1996         let events = Arc::new(Mutex::new(Vec::new()));
1997         let buffers = Arc::new(Mutex::new(Vec::new()));
1998 
1999         let flow_override = if (major, minor, micro) >= (1, 16, 1) {
2000             Err(FlowError::Eos)
2001         } else {
2002             // Broken on 1.16.0
2003             // https://gitlab.freedesktop.org/gstreamer/gstreamer/merge_requests/151
2004             Ok(FlowSuccess::Ok)
2005         };
2006 
2007         {
2008             let events = events.clone();
2009             pad.add_probe(crate::PadProbeType::EVENT_DOWNSTREAM, move |_, info| {
2010                 if let Some(PadProbeData::Event(event)) = &info.data {
2011                     let mut events = events.lock().unwrap();
2012                     events.push(event.clone());
2013                 } else {
2014                     unreachable!();
2015                 }
2016                 crate::PadProbeReturn::Ok
2017             });
2018         }
2019 
2020         {
2021             let events = events.clone();
2022             pad.add_probe(crate::PadProbeType::EVENT_UPSTREAM, move |_, info| {
2023                 if let Some(PadProbeData::Event(event)) = info.data.take() {
2024                     let mut events = events.lock().unwrap();
2025                     events.push(event);
2026                 } else {
2027                     unreachable!();
2028                 }
2029                 crate::PadProbeReturn::Handled
2030             });
2031         }
2032 
2033         {
2034             let buffers = buffers.clone();
2035             let flow_override = flow_override;
2036             pad.add_probe(crate::PadProbeType::BUFFER, move |_, info| {
2037                 if let Some(PadProbeData::Buffer(buffer)) = info.data.take() {
2038                     let mut buffers = buffers.lock().unwrap();
2039                     info.flow_res = if buffers.is_empty() {
2040                         Ok(FlowSuccess::Ok)
2041                     } else {
2042                         flow_override
2043                     };
2044                     buffers.push(buffer);
2045                 } else {
2046                     unreachable!();
2047                 }
2048                 crate::PadProbeReturn::Handled
2049             });
2050         }
2051 
2052         pad.set_active(true).unwrap();
2053 
2054         assert!(
2055             pad.send_event(crate::event::Latency::new(crate::ClockTime::from_nseconds(
2056                 10
2057             )))
2058         );
2059         assert!(pad.push_event(crate::event::StreamStart::new("test")));
2060         let segment = crate::FormattedSegment::<crate::ClockTime>::new();
2061         assert!(pad.push_event(crate::event::Segment::new(segment.as_ref())));
2062 
2063         assert_eq!(pad.push(crate::Buffer::new()), Ok(FlowSuccess::Ok));
2064         assert_eq!(pad.push(crate::Buffer::new()), flow_override);
2065 
2066         let events = events.lock().unwrap();
2067         let buffers = buffers.lock().unwrap();
2068         assert_eq!(events.len(), 3);
2069         assert_eq!(buffers.len(), 2);
2070 
2071         assert_eq!(events[0].type_(), crate::EventType::Latency);
2072         assert_eq!(events[1].type_(), crate::EventType::StreamStart);
2073         assert_eq!(events[2].type_(), crate::EventType::Segment);
2074 
2075         assert!(
2076             buffers.iter().all(|b| b.is_writable()),
2077             "A buffer ref leaked!"
2078         );
2079 
2080         drop(pad); // Need to drop the pad first to unref sticky events
2081         assert!(
2082             events.iter().all(|e| e.is_writable()),
2083             "An event ref leaked!"
2084         );
2085     }
2086 }
2087