1#[cfg(feature = "v1_16")]
4#[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
5use std::boxed::Box as Box_;
6#[cfg(feature = "v1_16")]
7#[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
8use std::mem::transmute;
9use std::{mem, ptr};
10
11#[cfg(feature = "v1_16")]
12#[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
13use glib::signal::{SignalHandlerId, connect_raw};
14use glib::{prelude::*, translate::*};
15use gst::{format::FormattedValue, prelude::*};
16
17use crate::{Aggregator, AggregatorPad, ffi};
18
19pub trait AggregatorExtManual: IsA<Aggregator> + 'static {
20 #[doc(alias = "get_allocator")]
36 #[doc(alias = "gst_aggregator_get_allocator")]
37 fn allocator(&self) -> (Option<gst::Allocator>, gst::AllocationParams) {
38 unsafe {
39 let mut allocator = ptr::null_mut();
40 let mut params = mem::MaybeUninit::uninit();
41 ffi::gst_aggregator_get_allocator(
42 self.as_ref().to_glib_none().0,
43 &mut allocator,
44 params.as_mut_ptr(),
45 );
46 (from_glib_full(allocator), params.assume_init().into())
47 }
48 }
49
50 #[cfg(feature = "v1_30")]
65 #[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
66 #[doc(alias = "gst_aggregator_set_allocator")]
67 fn set_allocator(
68 &self,
69 pool: Option<impl IsA<gst::BufferPool>>,
70 allocator: Option<impl IsA<gst::Allocator>>,
71 params: Option<&gst::AllocationParams>,
72 query: Option<gst::query::Allocation<gst::Query>>,
73 ) -> Result<(), gst::LoggableError> {
74 unsafe {
75 gst::result_from_gboolean!(
76 ffi::gst_aggregator_set_allocator(
77 self.as_ref().to_glib_none().0,
78 pool.map(|p| p.upcast()).into_glib_ptr(),
79 allocator.map(|p| p.upcast()).into_glib_ptr(),
80 params.to_glib_none().0,
81 query.map(gst::Query::from).into_glib_ptr(),
82 ),
83 gst::CAT_RUST,
84 "Failed to set allocator"
85 )
86 }
87 }
88
89 #[cfg(feature = "v1_16")]
90 #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
91 #[doc(alias = "min-upstream-latency")]
92 fn min_upstream_latency(&self) -> gst::ClockTime {
93 self.as_ref().property("min-upstream-latency")
94 }
95
96 #[cfg(feature = "v1_16")]
97 #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
98 #[doc(alias = "min-upstream-latency")]
99 fn set_min_upstream_latency(&self, min_upstream_latency: gst::ClockTime) {
100 self.as_ref()
101 .set_property("min-upstream-latency", min_upstream_latency);
102 }
103
104 #[cfg(feature = "v1_16")]
105 #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
106 #[doc(alias = "min-upstream-latency")]
107 fn connect_min_upstream_latency_notify<F: Fn(&Self) + Send + Sync + 'static>(
108 &self,
109 f: F,
110 ) -> SignalHandlerId {
111 unsafe {
112 let f: Box_<F> = Box_::new(f);
113 connect_raw(
114 self.as_ptr() as *mut _,
115 b"notify::min-upstream-latency\0".as_ptr() as *const _,
116 Some(transmute::<*const (), unsafe extern "C" fn()>(
117 notify_min_upstream_latency_trampoline::<Self, F> as *const (),
118 )),
119 Box_::into_raw(f),
120 )
121 }
122 }
123
124 #[cfg(feature = "v1_18")]
133 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
134 #[doc(alias = "gst_aggregator_update_segment")]
135 fn update_segment<F: gst::format::FormattedValueIntrinsic>(
136 &self,
137 segment: &gst::FormattedSegment<F>,
138 ) {
139 unsafe {
140 ffi::gst_aggregator_update_segment(
141 self.as_ref().to_glib_none().0,
142 mut_override(segment.to_glib_none().0),
143 )
144 }
145 }
146
147 fn set_position(&self, position: impl FormattedValue) {
148 unsafe {
149 let ptr: *mut ffi::GstAggregator = self.as_ref().to_glib_none().0;
150 let ptr = &mut *ptr;
151 let _guard = self.as_ref().object_lock();
152
153 let srcpad = &mut *(ptr.srcpad as *mut ffi::GstAggregatorPad);
156
157 assert_eq!(srcpad.segment.format, position.format().into_glib());
158 srcpad.segment.position = position.into_raw_value() as u64;
159 }
160 }
161
162 #[cfg(feature = "v1_18")]
182 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
183 #[doc(alias = "gst_aggregator_selected_samples")]
184 fn selected_samples(
185 &self,
186 pts: impl Into<Option<gst::ClockTime>>,
187 dts: impl Into<Option<gst::ClockTime>>,
188 duration: impl Into<Option<gst::ClockTime>>,
189 info: Option<&gst::StructureRef>,
190 ) {
191 unsafe {
192 ffi::gst_aggregator_selected_samples(
193 self.as_ref().to_glib_none().0,
194 pts.into().into_glib(),
195 dts.into().into_glib(),
196 duration.into().into_glib(),
197 info.as_ref()
198 .map(|s| s.as_ptr() as *mut _)
199 .unwrap_or(ptr::null_mut()),
200 );
201 }
202 }
203
204 #[cfg(feature = "v1_18")]
205 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
206 fn connect_samples_selected<
207 F: Fn(
208 &Self,
209 &gst::Segment,
210 Option<gst::ClockTime>,
211 Option<gst::ClockTime>,
212 Option<gst::ClockTime>,
213 Option<&gst::StructureRef>,
214 ) + Send
215 + 'static,
216 >(
217 &self,
218 f: F,
219 ) -> SignalHandlerId {
220 unsafe extern "C" fn samples_selected_trampoline<
221 P,
222 F: Fn(
223 &P,
224 &gst::Segment,
225 Option<gst::ClockTime>,
226 Option<gst::ClockTime>,
227 Option<gst::ClockTime>,
228 Option<&gst::StructureRef>,
229 ) + Send
230 + 'static,
231 >(
232 this: *mut ffi::GstAggregator,
233 segment: *mut gst::ffi::GstSegment,
234 pts: gst::ffi::GstClockTime,
235 dts: gst::ffi::GstClockTime,
236 duration: gst::ffi::GstClockTime,
237 info: *mut gst::ffi::GstStructure,
238 f: glib::ffi::gpointer,
239 ) where
240 P: IsA<Aggregator>,
241 {
242 unsafe {
243 let f: &F = &*(f as *const F);
244 f(
245 Aggregator::from_glib_borrow(this).unsafe_cast_ref(),
246 gst::Segment::from_glib_ptr_borrow(segment),
247 from_glib(pts),
248 from_glib(dts),
249 from_glib(duration),
250 if info.is_null() {
251 None
252 } else {
253 Some(gst::StructureRef::from_glib_borrow(info))
254 },
255 )
256 }
257 }
258
259 unsafe {
260 let f: Box_<F> = Box_::new(f);
261 connect_raw(
262 self.as_ptr() as *mut _,
263 b"samples-selected\0".as_ptr() as *const _,
264 Some(transmute::<*const (), unsafe extern "C" fn()>(
265 samples_selected_trampoline::<Self, F> as *const (),
266 )),
267 Box_::into_raw(f),
268 )
269 }
270 }
271
272 fn src_pad(&self) -> &AggregatorPad {
273 unsafe {
274 let elt = &*(self.as_ptr() as *const ffi::GstAggregator);
275 &*(&elt.srcpad as *const *mut gst::ffi::GstPad as *const AggregatorPad)
276 }
277 }
278}
279
280impl<O: IsA<Aggregator>> AggregatorExtManual for O {}
281
282#[cfg(feature = "v1_16")]
283#[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
284unsafe extern "C" fn notify_min_upstream_latency_trampoline<P, F: Fn(&P) + Send + Sync + 'static>(
285 this: *mut ffi::GstAggregator,
286 _param_spec: glib::ffi::gpointer,
287 f: glib::ffi::gpointer,
288) where
289 P: IsA<Aggregator>,
290{
291 unsafe {
292 let f: &F = &*(f as *const F);
293 f(Aggregator::from_glib_borrow(this).unsafe_cast_ref())
294 }
295}