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