1use crate::{
7 ffi, Buffer, BufferList, Caps, Element, Event, FlowError, FlowSuccess, Object, PadDirection,
8 PadLinkCheck, PadLinkError, PadLinkSuccess, PadMode, PadTemplate, Stream, TaskState,
9};
10use glib::{
11 object::ObjectType as _,
12 prelude::*,
13 signal::{connect_raw, SignalHandlerId},
14 translate::*,
15};
16use std::boxed::Box as Box_;
17
18glib::wrapper! {
19 #[doc(alias = "GstPad")]
20 pub struct Pad(Object<ffi::GstPad, ffi::GstPadClass>) @extends Object;
21
22 match fn {
23 type_ => || ffi::gst_pad_get_type(),
24 }
25}
26
27impl Pad {
28 pub const NONE: Option<&'static Pad> = None;
29}
30
31unsafe impl Send for Pad {}
32unsafe impl Sync for Pad {}
33
34mod sealed {
35 pub trait Sealed {}
36 impl<T: super::IsA<super::Pad>> Sealed for T {}
37}
38
39pub trait PadExt: IsA<Pad> + sealed::Sealed + 'static {
40 #[doc(alias = "gst_pad_activate_mode")]
41 fn activate_mode(&self, mode: PadMode, active: bool) -> Result<(), glib::error::BoolError> {
42 unsafe {
43 glib::result_from_gboolean!(
44 ffi::gst_pad_activate_mode(
45 self.as_ref().to_glib_none().0,
46 mode.into_glib(),
47 active.into_glib()
48 ),
49 "Failed to activate mode pad"
50 )
51 }
52 }
53
54 #[doc(alias = "gst_pad_can_link")]
55 fn can_link(&self, sinkpad: &impl IsA<Pad>) -> bool {
56 unsafe {
57 from_glib(ffi::gst_pad_can_link(
58 self.as_ref().to_glib_none().0,
59 sinkpad.as_ref().to_glib_none().0,
60 ))
61 }
62 }
63
64 #[doc(alias = "gst_pad_chain")]
65 fn chain(&self, buffer: Buffer) -> Result<FlowSuccess, FlowError> {
66 unsafe {
67 try_from_glib(ffi::gst_pad_chain(
68 self.as_ref().to_glib_none().0,
69 buffer.into_glib_ptr(),
70 ))
71 }
72 }
73
74 #[doc(alias = "gst_pad_chain_list")]
75 fn chain_list(&self, list: BufferList) -> Result<FlowSuccess, FlowError> {
76 unsafe {
77 try_from_glib(ffi::gst_pad_chain_list(
78 self.as_ref().to_glib_none().0,
79 list.into_glib_ptr(),
80 ))
81 }
82 }
83
84 #[doc(alias = "gst_pad_check_reconfigure")]
85 fn check_reconfigure(&self) -> bool {
86 unsafe {
87 from_glib(ffi::gst_pad_check_reconfigure(
88 self.as_ref().to_glib_none().0,
89 ))
90 }
91 }
92
93 #[doc(alias = "gst_pad_create_stream_id")]
94 fn create_stream_id(
95 &self,
96 parent: &impl IsA<Element>,
97 stream_id: Option<&str>,
98 ) -> glib::GString {
99 unsafe {
100 from_glib_full(ffi::gst_pad_create_stream_id(
101 self.as_ref().to_glib_none().0,
102 parent.as_ref().to_glib_none().0,
103 stream_id.to_glib_none().0,
104 ))
105 }
106 }
107
108 #[doc(alias = "gst_pad_forward")]
119 fn forward<P: FnMut(&Pad) -> bool>(&self, forward: P) -> bool {
120 let mut forward_data: P = forward;
121 unsafe extern "C" fn forward_func<P: FnMut(&Pad) -> bool>(
122 pad: *mut ffi::GstPad,
123 user_data: glib::ffi::gpointer,
124 ) -> glib::ffi::gboolean {
125 let pad = from_glib_borrow(pad);
126 let callback = user_data as *mut P;
127 (*callback)(&pad).into_glib()
128 }
129 let forward = Some(forward_func::<P> as _);
130 let super_callback0: &mut P = &mut forward_data;
131 unsafe {
132 from_glib(ffi::gst_pad_forward(
133 self.as_ref().to_glib_none().0,
134 forward,
135 super_callback0 as *mut _ as *mut _,
136 ))
137 }
138 }
139
140 #[doc(alias = "gst_pad_get_allowed_caps")]
141 #[doc(alias = "get_allowed_caps")]
142 fn allowed_caps(&self) -> Option<Caps> {
143 unsafe {
144 from_glib_full(ffi::gst_pad_get_allowed_caps(
145 self.as_ref().to_glib_none().0,
146 ))
147 }
148 }
149
150 #[doc(alias = "gst_pad_get_current_caps")]
151 #[doc(alias = "get_current_caps")]
152 fn current_caps(&self) -> Option<Caps> {
153 unsafe {
154 from_glib_full(ffi::gst_pad_get_current_caps(
155 self.as_ref().to_glib_none().0,
156 ))
157 }
158 }
159
160 #[doc(alias = "gst_pad_get_direction")]
161 #[doc(alias = "get_direction")]
162 fn direction(&self) -> PadDirection {
163 unsafe { from_glib(ffi::gst_pad_get_direction(self.as_ref().to_glib_none().0)) }
164 }
165
166 #[doc(alias = "gst_pad_get_last_flow_return")]
173 #[doc(alias = "get_last_flow_return")]
174 fn last_flow_result(&self) -> Result<FlowSuccess, FlowError> {
175 unsafe {
176 try_from_glib(ffi::gst_pad_get_last_flow_return(
177 self.as_ref().to_glib_none().0,
178 ))
179 }
180 }
181
182 #[doc(alias = "gst_pad_get_offset")]
183 #[doc(alias = "get_offset")]
184 fn offset(&self) -> i64 {
185 unsafe { ffi::gst_pad_get_offset(self.as_ref().to_glib_none().0) }
186 }
187
188 #[doc(alias = "gst_pad_get_pad_template")]
189 #[doc(alias = "get_pad_template")]
190 fn pad_template(&self) -> Option<PadTemplate> {
191 unsafe {
192 from_glib_full(ffi::gst_pad_get_pad_template(
193 self.as_ref().to_glib_none().0,
194 ))
195 }
196 }
197
198 #[doc(alias = "gst_pad_get_pad_template_caps")]
199 #[doc(alias = "get_pad_template_caps")]
200 fn pad_template_caps(&self) -> Caps {
201 unsafe {
202 from_glib_full(ffi::gst_pad_get_pad_template_caps(
203 self.as_ref().to_glib_none().0,
204 ))
205 }
206 }
207
208 #[doc(alias = "gst_pad_get_parent_element")]
209 #[doc(alias = "get_parent_element")]
210 fn parent_element(&self) -> Option<Element> {
211 unsafe {
212 from_glib_full(ffi::gst_pad_get_parent_element(
213 self.as_ref().to_glib_none().0,
214 ))
215 }
216 }
217
218 #[doc(alias = "gst_pad_get_peer")]
219 #[doc(alias = "get_peer")]
220 #[must_use]
221 fn peer(&self) -> Option<Pad> {
222 unsafe { from_glib_full(ffi::gst_pad_get_peer(self.as_ref().to_glib_none().0)) }
223 }
224
225 #[cfg(feature = "v1_18")]
226 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
227 #[doc(alias = "gst_pad_get_single_internal_link")]
228 #[doc(alias = "get_single_internal_link")]
229 #[must_use]
230 fn single_internal_link(&self) -> Option<Pad> {
231 unsafe {
232 from_glib_full(ffi::gst_pad_get_single_internal_link(
233 self.as_ref().to_glib_none().0,
234 ))
235 }
236 }
237
238 #[doc(alias = "gst_pad_get_stream")]
239 #[doc(alias = "get_stream")]
240 fn stream(&self) -> Option<Stream> {
241 unsafe { from_glib_full(ffi::gst_pad_get_stream(self.as_ref().to_glib_none().0)) }
242 }
243
244 #[doc(alias = "gst_pad_get_stream_id")]
245 #[doc(alias = "get_stream_id")]
246 fn stream_id(&self) -> Option<glib::GString> {
247 unsafe { from_glib_full(ffi::gst_pad_get_stream_id(self.as_ref().to_glib_none().0)) }
248 }
249
250 #[doc(alias = "gst_pad_get_task_state")]
251 #[doc(alias = "get_task_state")]
252 fn task_state(&self) -> TaskState {
253 unsafe { from_glib(ffi::gst_pad_get_task_state(self.as_ref().to_glib_none().0)) }
254 }
255
256 #[doc(alias = "gst_pad_has_current_caps")]
257 fn has_current_caps(&self) -> bool {
258 unsafe {
259 from_glib(ffi::gst_pad_has_current_caps(
260 self.as_ref().to_glib_none().0,
261 ))
262 }
263 }
264
265 #[doc(alias = "gst_pad_is_active")]
266 fn is_active(&self) -> bool {
267 unsafe { from_glib(ffi::gst_pad_is_active(self.as_ref().to_glib_none().0)) }
268 }
269
270 #[doc(alias = "gst_pad_is_blocked")]
271 fn is_blocked(&self) -> bool {
272 unsafe { from_glib(ffi::gst_pad_is_blocked(self.as_ref().to_glib_none().0)) }
273 }
274
275 #[doc(alias = "gst_pad_is_blocking")]
276 fn is_blocking(&self) -> bool {
277 unsafe { from_glib(ffi::gst_pad_is_blocking(self.as_ref().to_glib_none().0)) }
278 }
279
280 #[doc(alias = "gst_pad_is_linked")]
281 fn is_linked(&self) -> bool {
282 unsafe { from_glib(ffi::gst_pad_is_linked(self.as_ref().to_glib_none().0)) }
283 }
284
285 #[doc(alias = "gst_pad_link")]
296 fn link(&self, sinkpad: &impl IsA<Pad>) -> Result<PadLinkSuccess, PadLinkError> {
297 unsafe {
298 try_from_glib(ffi::gst_pad_link(
299 self.as_ref().to_glib_none().0,
300 sinkpad.as_ref().to_glib_none().0,
301 ))
302 }
303 }
304
305 #[doc(alias = "gst_pad_link_full")]
306 fn link_full(
307 &self,
308 sinkpad: &impl IsA<Pad>,
309 flags: PadLinkCheck,
310 ) -> Result<PadLinkSuccess, PadLinkError> {
311 unsafe {
312 try_from_glib(ffi::gst_pad_link_full(
313 self.as_ref().to_glib_none().0,
314 sinkpad.as_ref().to_glib_none().0,
315 flags.into_glib(),
316 ))
317 }
318 }
319
320 #[doc(alias = "gst_pad_link_maybe_ghosting")]
321 fn link_maybe_ghosting(&self, sink: &impl IsA<Pad>) -> Result<(), glib::error::BoolError> {
322 unsafe {
323 glib::result_from_gboolean!(
324 ffi::gst_pad_link_maybe_ghosting(
325 self.as_ref().to_glib_none().0,
326 sink.as_ref().to_glib_none().0
327 ),
328 "Failed to link pads, possibly ghosting"
329 )
330 }
331 }
332
333 #[doc(alias = "gst_pad_link_maybe_ghosting_full")]
334 fn link_maybe_ghosting_full(
335 &self,
336 sink: &impl IsA<Pad>,
337 flags: PadLinkCheck,
338 ) -> Result<(), glib::error::BoolError> {
339 unsafe {
340 glib::result_from_gboolean!(
341 ffi::gst_pad_link_maybe_ghosting_full(
342 self.as_ref().to_glib_none().0,
343 sink.as_ref().to_glib_none().0,
344 flags.into_glib()
345 ),
346 "Failed to link pads, possibly ghosting"
347 )
348 }
349 }
350
351 #[doc(alias = "gst_pad_mark_reconfigure")]
352 fn mark_reconfigure(&self) {
353 unsafe {
354 ffi::gst_pad_mark_reconfigure(self.as_ref().to_glib_none().0);
355 }
356 }
357
358 #[doc(alias = "gst_pad_needs_reconfigure")]
359 fn needs_reconfigure(&self) -> bool {
360 unsafe {
361 from_glib(ffi::gst_pad_needs_reconfigure(
362 self.as_ref().to_glib_none().0,
363 ))
364 }
365 }
366
367 #[doc(alias = "gst_pad_pause_task")]
368 fn pause_task(&self) -> Result<(), glib::error::BoolError> {
369 unsafe {
370 glib::result_from_gboolean!(
371 ffi::gst_pad_pause_task(self.as_ref().to_glib_none().0),
372 "Failed to pause pad task"
373 )
374 }
375 }
376
377 #[doc(alias = "gst_pad_peer_query_accept_caps")]
378 fn peer_query_accept_caps(&self, caps: &Caps) -> bool {
379 unsafe {
380 from_glib(ffi::gst_pad_peer_query_accept_caps(
381 self.as_ref().to_glib_none().0,
382 caps.to_glib_none().0,
383 ))
384 }
385 }
386
387 #[doc(alias = "gst_pad_peer_query_caps")]
388 fn peer_query_caps(&self, filter: Option<&Caps>) -> Caps {
389 unsafe {
390 from_glib_full(ffi::gst_pad_peer_query_caps(
391 self.as_ref().to_glib_none().0,
392 filter.to_glib_none().0,
393 ))
394 }
395 }
396
397 #[doc(alias = "gst_pad_push")]
398 fn push(&self, buffer: Buffer) -> Result<FlowSuccess, FlowError> {
399 unsafe {
400 try_from_glib(ffi::gst_pad_push(
401 self.as_ref().to_glib_none().0,
402 buffer.into_glib_ptr(),
403 ))
404 }
405 }
406
407 #[doc(alias = "gst_pad_push_list")]
408 fn push_list(&self, list: BufferList) -> Result<FlowSuccess, FlowError> {
409 unsafe {
410 try_from_glib(ffi::gst_pad_push_list(
411 self.as_ref().to_glib_none().0,
412 list.into_glib_ptr(),
413 ))
414 }
415 }
416
417 #[doc(alias = "gst_pad_query_accept_caps")]
418 fn query_accept_caps(&self, caps: &Caps) -> bool {
419 unsafe {
420 from_glib(ffi::gst_pad_query_accept_caps(
421 self.as_ref().to_glib_none().0,
422 caps.to_glib_none().0,
423 ))
424 }
425 }
426
427 #[doc(alias = "gst_pad_query_caps")]
428 fn query_caps(&self, filter: Option<&Caps>) -> Caps {
429 unsafe {
430 from_glib_full(ffi::gst_pad_query_caps(
431 self.as_ref().to_glib_none().0,
432 filter.to_glib_none().0,
433 ))
434 }
435 }
436
437 #[doc(alias = "gst_pad_set_active")]
438 fn set_active(&self, active: bool) -> Result<(), glib::error::BoolError> {
439 unsafe {
440 glib::result_from_gboolean!(
441 ffi::gst_pad_set_active(self.as_ref().to_glib_none().0, active.into_glib()),
442 "Failed to activate pad"
443 )
444 }
445 }
446
447 #[doc(alias = "gst_pad_set_offset")]
453 #[doc(alias = "offset")]
454 fn set_offset(&self, offset: i64) {
455 unsafe {
456 ffi::gst_pad_set_offset(self.as_ref().to_glib_none().0, offset);
457 }
458 }
459
460 #[doc(alias = "gst_pad_stop_task")]
461 fn stop_task(&self) -> Result<(), glib::error::BoolError> {
462 unsafe {
463 glib::result_from_gboolean!(
464 ffi::gst_pad_stop_task(self.as_ref().to_glib_none().0),
465 "Failed to stop pad task"
466 )
467 }
468 }
469
470 #[doc(alias = "gst_pad_store_sticky_event")]
471 fn store_sticky_event(&self, event: &Event) -> Result<FlowSuccess, FlowError> {
472 unsafe {
473 try_from_glib(ffi::gst_pad_store_sticky_event(
474 self.as_ref().to_glib_none().0,
475 event.to_glib_none().0,
476 ))
477 }
478 }
479
480 #[doc(alias = "gst_pad_unlink")]
481 fn unlink(&self, sinkpad: &impl IsA<Pad>) -> Result<(), glib::error::BoolError> {
482 unsafe {
483 glib::result_from_gboolean!(
484 ffi::gst_pad_unlink(
485 self.as_ref().to_glib_none().0,
486 sinkpad.as_ref().to_glib_none().0
487 ),
488 "Failed to unlink pad"
489 )
490 }
491 }
492
493 #[doc(alias = "gst_pad_use_fixed_caps")]
494 fn use_fixed_caps(&self) {
495 unsafe {
496 ffi::gst_pad_use_fixed_caps(self.as_ref().to_glib_none().0);
497 }
498 }
499
500 #[doc(alias = "linked")]
501 fn connect_linked<F: Fn(&Self, &Pad) + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId {
502 unsafe extern "C" fn linked_trampoline<
503 P: IsA<Pad>,
504 F: Fn(&P, &Pad) + Send + Sync + 'static,
505 >(
506 this: *mut ffi::GstPad,
507 peer: *mut ffi::GstPad,
508 f: glib::ffi::gpointer,
509 ) {
510 let f: &F = &*(f as *const F);
511 f(
512 Pad::from_glib_borrow(this).unsafe_cast_ref(),
513 &from_glib_borrow(peer),
514 )
515 }
516 unsafe {
517 let f: Box_<F> = Box_::new(f);
518 connect_raw(
519 self.as_ptr() as *mut _,
520 b"linked\0".as_ptr() as *const _,
521 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
522 linked_trampoline::<Self, F> as *const (),
523 )),
524 Box_::into_raw(f),
525 )
526 }
527 }
528
529 #[doc(alias = "unlinked")]
530 fn connect_unlinked<F: Fn(&Self, &Pad) + Send + Sync + 'static>(
531 &self,
532 f: F,
533 ) -> SignalHandlerId {
534 unsafe extern "C" fn unlinked_trampoline<
535 P: IsA<Pad>,
536 F: Fn(&P, &Pad) + Send + Sync + 'static,
537 >(
538 this: *mut ffi::GstPad,
539 peer: *mut ffi::GstPad,
540 f: glib::ffi::gpointer,
541 ) {
542 let f: &F = &*(f as *const F);
543 f(
544 Pad::from_glib_borrow(this).unsafe_cast_ref(),
545 &from_glib_borrow(peer),
546 )
547 }
548 unsafe {
549 let f: Box_<F> = Box_::new(f);
550 connect_raw(
551 self.as_ptr() as *mut _,
552 b"unlinked\0".as_ptr() as *const _,
553 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
554 unlinked_trampoline::<Self, F> as *const (),
555 )),
556 Box_::into_raw(f),
557 )
558 }
559 }
560
561 #[doc(alias = "caps")]
562 fn connect_caps_notify<F: Fn(&Self) + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId {
563 unsafe extern "C" fn notify_caps_trampoline<
564 P: IsA<Pad>,
565 F: Fn(&P) + Send + Sync + 'static,
566 >(
567 this: *mut ffi::GstPad,
568 _param_spec: glib::ffi::gpointer,
569 f: glib::ffi::gpointer,
570 ) {
571 let f: &F = &*(f as *const F);
572 f(Pad::from_glib_borrow(this).unsafe_cast_ref())
573 }
574 unsafe {
575 let f: Box_<F> = Box_::new(f);
576 connect_raw(
577 self.as_ptr() as *mut _,
578 b"notify::caps\0".as_ptr() as *const _,
579 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
580 notify_caps_trampoline::<Self, F> as *const (),
581 )),
582 Box_::into_raw(f),
583 )
584 }
585 }
586
587 #[doc(alias = "offset")]
588 fn connect_offset_notify<F: Fn(&Self) + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId {
589 unsafe extern "C" fn notify_offset_trampoline<
590 P: IsA<Pad>,
591 F: Fn(&P) + Send + Sync + 'static,
592 >(
593 this: *mut ffi::GstPad,
594 _param_spec: glib::ffi::gpointer,
595 f: glib::ffi::gpointer,
596 ) {
597 let f: &F = &*(f as *const F);
598 f(Pad::from_glib_borrow(this).unsafe_cast_ref())
599 }
600 unsafe {
601 let f: Box_<F> = Box_::new(f);
602 connect_raw(
603 self.as_ptr() as *mut _,
604 b"notify::offset\0".as_ptr() as *const _,
605 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
606 notify_offset_trampoline::<Self, F> as *const (),
607 )),
608 Box_::into_raw(f),
609 )
610 }
611 }
612}
613
614impl<O: IsA<Pad>> PadExt for O {}