1 | // Take a look at the license at the top of the repository in the LICENSE file. |
2 | |
3 | use std::ptr; |
4 | |
5 | use glib::translate::*; |
6 | use gst_base::{prelude::*, subclass::prelude::*}; |
7 | |
8 | use crate::{AudioAggregator, AudioAggregatorPad}; |
9 | |
10 | pub trait AudioAggregatorImpl: AudioAggregatorImplExt + AggregatorImpl { |
11 | fn create_output_buffer(&self, num_frames: u32) -> Option<gst::Buffer> { |
12 | self.parent_create_output_buffer(num_frames) |
13 | } |
14 | |
15 | #[allow (clippy::too_many_arguments)] |
16 | fn aggregate_one_buffer( |
17 | &self, |
18 | pad: &AudioAggregatorPad, |
19 | inbuf: &gst::BufferRef, |
20 | in_offset: u32, |
21 | outbuf: &mut gst::BufferRef, |
22 | out_offset: u32, |
23 | num_frames: u32, |
24 | ) -> bool { |
25 | self.parent_aggregate_one_buffer(pad, inbuf, in_offset, outbuf, out_offset, num_frames) |
26 | } |
27 | } |
28 | |
29 | mod sealed { |
30 | pub trait Sealed {} |
31 | impl<T: super::AudioAggregatorImplExt> Sealed for T {} |
32 | } |
33 | |
34 | pub trait AudioAggregatorImplExt: sealed::Sealed + ObjectSubclass { |
35 | fn parent_create_output_buffer(&self, num_frames: u32) -> Option<gst::Buffer> { |
36 | unsafe { |
37 | let data = Self::type_data(); |
38 | let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioAggregatorClass; |
39 | let f = (*parent_class) |
40 | .create_output_buffer |
41 | .expect("Missing parent function `create_output_buffer`" ); |
42 | |
43 | from_glib_full(f( |
44 | self.obj() |
45 | .unsafe_cast_ref::<AudioAggregator>() |
46 | .to_glib_none() |
47 | .0, |
48 | num_frames, |
49 | )) |
50 | } |
51 | } |
52 | |
53 | fn parent_aggregate_one_buffer( |
54 | &self, |
55 | pad: &AudioAggregatorPad, |
56 | inbuf: &gst::BufferRef, |
57 | in_offset: u32, |
58 | outbuf: &mut gst::BufferRef, |
59 | out_offset: u32, |
60 | num_frames: u32, |
61 | ) -> bool { |
62 | unsafe { |
63 | let data = Self::type_data(); |
64 | let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioAggregatorClass; |
65 | let f = (*parent_class) |
66 | .aggregate_one_buffer |
67 | .expect("Missing parent function `aggregate_one_buffer`" ); |
68 | |
69 | from_glib(f( |
70 | self.obj() |
71 | .unsafe_cast_ref::<AudioAggregator>() |
72 | .to_glib_none() |
73 | .0, |
74 | pad.to_glib_none().0, |
75 | inbuf.as_mut_ptr(), |
76 | in_offset, |
77 | outbuf.as_mut_ptr(), |
78 | out_offset, |
79 | num_frames, |
80 | )) |
81 | } |
82 | } |
83 | } |
84 | |
85 | impl<T: AudioAggregatorImpl> AudioAggregatorImplExt for T {} |
86 | |
87 | unsafe impl<T: AudioAggregatorImpl> IsSubclassable<T> for AudioAggregator { |
88 | fn class_init(klass: &mut glib::Class<Self>) { |
89 | Self::parent_class_init::<T>(class:klass); |
90 | |
91 | let klass: &mut GstAudioAggregatorClass = klass.as_mut(); |
92 | klass.create_output_buffer = Some(audio_aggregator_create_output_buffer::<T>); |
93 | klass.aggregate_one_buffer = Some(audio_aggregator_aggregate_one_buffer::<T>); |
94 | } |
95 | } |
96 | |
97 | unsafe extern "C" fn audio_aggregator_create_output_buffer<T: AudioAggregatorImpl>( |
98 | ptr: *mut ffi::GstAudioAggregator, |
99 | num_frames: u32, |
100 | ) -> *mut gst::ffi::GstBuffer { |
101 | let instance: &::Instance = &*(ptr as *mut T::Instance); |
102 | let imp: &T = instance.imp(); |
103 | |
104 | gst::panic_to_error!(imp, None, { imp.create_output_buffer(num_frames) }) |
105 | .map(|buffer| buffer.into_glib_ptr()) |
106 | .unwrap_or(default:ptr::null_mut()) |
107 | } |
108 | |
109 | unsafe extern "C" fn audio_aggregator_aggregate_one_buffer<T: AudioAggregatorImpl>( |
110 | ptr: *mut ffi::GstAudioAggregator, |
111 | pad: *mut ffi::GstAudioAggregatorPad, |
112 | inbuf: *mut gst::ffi::GstBuffer, |
113 | in_offset: u32, |
114 | outbuf: *mut gst::ffi::GstBuffer, |
115 | out_offset: u32, |
116 | num_frames: u32, |
117 | ) -> glib::ffi::gboolean { |
118 | let instance: &::Instance = &*(ptr as *mut T::Instance); |
119 | let imp: &T = instance.imp(); |
120 | |
121 | gstbool::panic_to_error!(imp, true, { |
122 | imp.aggregate_one_buffer( |
123 | &from_glib_borrow(pad), |
124 | gst::BufferRef::from_ptr(inbuf), |
125 | in_offset, |
126 | gst::BufferRef::from_mut_ptr(outbuf), |
127 | out_offset, |
128 | num_frames, |
129 | ) |
130 | }) |
131 | .into_glib() |
132 | } |
133 | |