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