1 // Take a look at the license at the top of the repository in the LICENSE file.
2 
3 use glib::prelude::*;
4 use glib::translate::*;
5 
6 use gst::subclass::prelude::*;
7 
8 use crate::Aggregator;
9 use crate::AggregatorPad;
10 
11 pub trait AggregatorPadImpl: AggregatorPadImplExt + PadImpl {
flush( &self, aggregator_pad: &Self::Type, aggregator: &Aggregator, ) -> Result<gst::FlowSuccess, gst::FlowError>12     fn flush(
13         &self,
14         aggregator_pad: &Self::Type,
15         aggregator: &Aggregator,
16     ) -> Result<gst::FlowSuccess, gst::FlowError> {
17         self.parent_flush(aggregator_pad, aggregator)
18     }
19 
skip_buffer( &self, aggregator_pad: &Self::Type, aggregator: &Aggregator, buffer: &gst::Buffer, ) -> bool20     fn skip_buffer(
21         &self,
22         aggregator_pad: &Self::Type,
23         aggregator: &Aggregator,
24         buffer: &gst::Buffer,
25     ) -> bool {
26         self.parent_skip_buffer(aggregator_pad, aggregator, buffer)
27     }
28 }
29 
30 pub trait AggregatorPadImplExt: ObjectSubclass {
parent_flush( &self, aggregator_pad: &Self::Type, aggregator: &Aggregator, ) -> Result<gst::FlowSuccess, gst::FlowError>31     fn parent_flush(
32         &self,
33         aggregator_pad: &Self::Type,
34         aggregator: &Aggregator,
35     ) -> Result<gst::FlowSuccess, gst::FlowError>;
36 
parent_skip_buffer( &self, aggregator_pad: &Self::Type, aggregator: &Aggregator, buffer: &gst::Buffer, ) -> bool37     fn parent_skip_buffer(
38         &self,
39         aggregator_pad: &Self::Type,
40         aggregator: &Aggregator,
41         buffer: &gst::Buffer,
42     ) -> bool;
43 }
44 
45 impl<T: AggregatorPadImpl> AggregatorPadImplExt for T {
parent_flush( &self, aggregator_pad: &Self::Type, aggregator: &Aggregator, ) -> Result<gst::FlowSuccess, gst::FlowError>46     fn parent_flush(
47         &self,
48         aggregator_pad: &Self::Type,
49         aggregator: &Aggregator,
50     ) -> Result<gst::FlowSuccess, gst::FlowError> {
51         unsafe {
52             let data = Self::type_data();
53             let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorPadClass;
54             (*parent_class)
55                 .flush
56                 .map(|f| {
57                     try_from_glib(f(
58                         aggregator_pad
59                             .unsafe_cast_ref::<AggregatorPad>()
60                             .to_glib_none()
61                             .0,
62                         aggregator.to_glib_none().0,
63                     ))
64                 })
65                 .unwrap_or(Ok(gst::FlowSuccess::Ok))
66         }
67     }
68 
parent_skip_buffer( &self, aggregator_pad: &Self::Type, aggregator: &Aggregator, buffer: &gst::Buffer, ) -> bool69     fn parent_skip_buffer(
70         &self,
71         aggregator_pad: &Self::Type,
72         aggregator: &Aggregator,
73         buffer: &gst::Buffer,
74     ) -> bool {
75         unsafe {
76             let data = Self::type_data();
77             let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorPadClass;
78             (*parent_class)
79                 .skip_buffer
80                 .map(|f| {
81                     from_glib(f(
82                         aggregator_pad
83                             .unsafe_cast_ref::<AggregatorPad>()
84                             .to_glib_none()
85                             .0,
86                         aggregator.to_glib_none().0,
87                         buffer.to_glib_none().0,
88                     ))
89                 })
90                 .unwrap_or(false)
91         }
92     }
93 }
94 unsafe impl<T: AggregatorPadImpl> IsSubclassable<T> for AggregatorPad {
class_init(klass: &mut glib::Class<Self>)95     fn class_init(klass: &mut glib::Class<Self>) {
96         <gst::Pad as IsSubclassable<T>>::class_init(klass);
97         let klass = klass.as_mut();
98         klass.flush = Some(aggregator_pad_flush::<T>);
99         klass.skip_buffer = Some(aggregator_pad_skip_buffer::<T>);
100     }
101 
instance_init(instance: &mut glib::subclass::InitializingObject<T>)102     fn instance_init(instance: &mut glib::subclass::InitializingObject<T>) {
103         <gst::Pad as IsSubclassable<T>>::instance_init(instance);
104     }
105 }
106 
aggregator_pad_flush<T: AggregatorPadImpl>( ptr: *mut ffi::GstAggregatorPad, aggregator: *mut ffi::GstAggregator, ) -> gst::ffi::GstFlowReturn107 unsafe extern "C" fn aggregator_pad_flush<T: AggregatorPadImpl>(
108     ptr: *mut ffi::GstAggregatorPad,
109     aggregator: *mut ffi::GstAggregator,
110 ) -> gst::ffi::GstFlowReturn {
111     let instance = &*(ptr as *mut T::Instance);
112     let imp = instance.impl_();
113     let wrap: Borrowed<AggregatorPad> = from_glib_borrow(ptr);
114 
115     let res: gst::FlowReturn = imp
116         .flush(wrap.unsafe_cast_ref(), &from_glib_borrow(aggregator))
117         .into();
118     res.into_glib()
119 }
120 
aggregator_pad_skip_buffer<T: AggregatorPadImpl>( ptr: *mut ffi::GstAggregatorPad, aggregator: *mut ffi::GstAggregator, buffer: *mut gst::ffi::GstBuffer, ) -> glib::ffi::gboolean121 unsafe extern "C" fn aggregator_pad_skip_buffer<T: AggregatorPadImpl>(
122     ptr: *mut ffi::GstAggregatorPad,
123     aggregator: *mut ffi::GstAggregator,
124     buffer: *mut gst::ffi::GstBuffer,
125 ) -> glib::ffi::gboolean {
126     let instance = &*(ptr as *mut T::Instance);
127     let imp = instance.impl_();
128     let wrap: Borrowed<AggregatorPad> = from_glib_borrow(ptr);
129 
130     imp.skip_buffer(
131         wrap.unsafe_cast_ref(),
132         &from_glib_borrow(aggregator),
133         &from_glib_borrow(buffer),
134     )
135     .into_glib()
136 }
137