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