1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use glib::{prelude::*, translate::*};
4use gst::subclass::prelude::*;
5
6use crate::{Aggregator, AggregatorPad};
7
8pub trait AggregatorPadImpl: AggregatorPadImplExt + PadImpl {
9 fn flush(&self, aggregator: &Aggregator) -> Result<gst::FlowSuccess, gst::FlowError> {
10 self.parent_flush(aggregator)
11 }
12
13 fn skip_buffer(&self, aggregator: &Aggregator, buffer: &gst::Buffer) -> bool {
14 self.parent_skip_buffer(aggregator, buffer)
15 }
16}
17
18mod sealed {
19 pub trait Sealed {}
20 impl<T: super::AggregatorPadImplExt> Sealed for T {}
21}
22
23pub trait AggregatorPadImplExt: sealed::Sealed + ObjectSubclass {
24 fn parent_flush(&self, aggregator: &Aggregator) -> Result<gst::FlowSuccess, gst::FlowError> {
25 unsafe {
26 let data = Self::type_data();
27 let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorPadClass;
28 (*parent_class)
29 .flush
30 .map(|f| {
31 try_from_glib(f(
32 self.obj()
33 .unsafe_cast_ref::<AggregatorPad>()
34 .to_glib_none()
35 .0,
36 aggregator.to_glib_none().0,
37 ))
38 })
39 .unwrap_or(Ok(gst::FlowSuccess::Ok))
40 }
41 }
42
43 fn parent_skip_buffer(&self, aggregator: &Aggregator, buffer: &gst::Buffer) -> bool {
44 unsafe {
45 let data = Self::type_data();
46 let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorPadClass;
47 (*parent_class)
48 .skip_buffer
49 .map(|f| {
50 from_glib(f(
51 self.obj()
52 .unsafe_cast_ref::<AggregatorPad>()
53 .to_glib_none()
54 .0,
55 aggregator.to_glib_none().0,
56 buffer.to_glib_none().0,
57 ))
58 })
59 .unwrap_or(false)
60 }
61 }
62}
63
64impl<T: AggregatorPadImpl> AggregatorPadImplExt for T {}
65unsafe impl<T: AggregatorPadImpl> IsSubclassable<T> for AggregatorPad {
66 fn class_init(klass: &mut glib::Class<Self>) {
67 Self::parent_class_init::<T>(class:klass);
68 let klass: &mut GstAggregatorPadClass = klass.as_mut();
69 klass.flush = Some(aggregator_pad_flush::<T>);
70 klass.skip_buffer = Some(aggregator_pad_skip_buffer::<T>);
71 }
72}
73
74unsafe extern "C" fn aggregator_pad_flush<T: AggregatorPadImpl>(
75 ptr: *mut ffi::GstAggregatorPad,
76 aggregator: *mut ffi::GstAggregator,
77) -> gst::ffi::GstFlowReturn {
78 let instance: &::Instance = &*(ptr as *mut T::Instance);
79 let imp: &T = instance.imp();
80
81 let res: gst::FlowReturn = imp.flush(&from_glib_borrow(ptr:aggregator)).into();
82 res.into_glib()
83}
84
85unsafe extern "C" fn aggregator_pad_skip_buffer<T: AggregatorPadImpl>(
86 ptr: *mut ffi::GstAggregatorPad,
87 aggregator: *mut ffi::GstAggregator,
88 buffer: *mut gst::ffi::GstBuffer,
89) -> glib::ffi::gboolean {
90 let instance: &::Instance = &*(ptr as *mut T::Instance);
91 let imp: &T = instance.imp();
92
93 impbool.skip_buffer(&from_glib_borrow(aggregator), &from_glib_borrow(ptr:buffer))
94 .into_glib()
95}
96