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::{connect_raw, SignalHandlerId};
14use glib::{prelude::*, translate::*};
15use gst::{format::FormattedValue, prelude::*};
16
17use crate::{ffi, Aggregator, AggregatorPad};
18
19mod sealed {
20 pub trait Sealed {}
21 impl<T: super::IsA<super::Aggregator>> Sealed for T {}
22}
23
24pub trait AggregatorExtManual: sealed::Sealed + IsA<Aggregator> + 'static {
25 #[doc(alias = "get_allocator")]
41 #[doc(alias = "gst_aggregator_get_allocator")]
42 fn allocator(&self) -> (Option<gst::Allocator>, gst::AllocationParams) {
43 unsafe {
44 let mut allocator = ptr::null_mut();
45 let mut params = mem::MaybeUninit::uninit();
46 ffi::gst_aggregator_get_allocator(
47 self.as_ref().to_glib_none().0,
48 &mut allocator,
49 params.as_mut_ptr(),
50 );
51 (from_glib_full(allocator), params.assume_init().into())
52 }
53 }
54
55 #[cfg(feature = "v1_16")]
56 #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
57 #[doc(alias = "min-upstream-latency")]
58 fn min_upstream_latency(&self) -> gst::ClockTime {
59 self.as_ref().property("min-upstream-latency")
60 }
61
62 #[cfg(feature = "v1_16")]
63 #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
64 #[doc(alias = "min-upstream-latency")]
65 fn set_min_upstream_latency(&self, min_upstream_latency: gst::ClockTime) {
66 self.as_ref()
67 .set_property("min-upstream-latency", min_upstream_latency);
68 }
69
70 #[cfg(feature = "v1_16")]
71 #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
72 #[doc(alias = "min-upstream-latency")]
73 fn connect_min_upstream_latency_notify<F: Fn(&Self) + Send + Sync + 'static>(
74 &self,
75 f: F,
76 ) -> SignalHandlerId {
77 unsafe {
78 let f: Box_<F> = Box_::new(f);
79 connect_raw(
80 self.as_ptr() as *mut _,
81 b"notify::min-upstream-latency\0".as_ptr() as *const _,
82 Some(transmute::<*const (), unsafe extern "C" fn()>(
83 notify_min_upstream_latency_trampoline::<Self, F> as *const (),
84 )),
85 Box_::into_raw(f),
86 )
87 }
88 }
89
90 #[cfg(feature = "v1_18")]
97 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
98 #[doc(alias = "gst_aggregator_update_segment")]
99 fn update_segment<F: gst::format::FormattedValueIntrinsic>(
100 &self,
101 segment: &gst::FormattedSegment<F>,
102 ) {
103 unsafe {
104 ffi::gst_aggregator_update_segment(
105 self.as_ref().to_glib_none().0,
106 mut_override(segment.to_glib_none().0),
107 )
108 }
109 }
110
111 fn set_position(&self, position: impl FormattedValue) {
112 unsafe {
113 let ptr: *mut ffi::GstAggregator = self.as_ref().to_glib_none().0;
114 let ptr = &mut *ptr;
115 let _guard = self.as_ref().object_lock();
116
117 let srcpad = &mut *(ptr.srcpad as *mut ffi::GstAggregatorPad);
120
121 assert_eq!(srcpad.segment.format, position.format().into_glib());
122 srcpad.segment.position = position.into_raw_value() as u64;
123 }
124 }
125
126 #[cfg(feature = "v1_18")]
146 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
147 #[doc(alias = "gst_aggregator_selected_samples")]
148 fn selected_samples(
149 &self,
150 pts: impl Into<Option<gst::ClockTime>>,
151 dts: impl Into<Option<gst::ClockTime>>,
152 duration: impl Into<Option<gst::ClockTime>>,
153 info: Option<&gst::StructureRef>,
154 ) {
155 unsafe {
156 ffi::gst_aggregator_selected_samples(
157 self.as_ref().to_glib_none().0,
158 pts.into().into_glib(),
159 dts.into().into_glib(),
160 duration.into().into_glib(),
161 info.as_ref()
162 .map(|s| s.as_ptr() as *mut _)
163 .unwrap_or(ptr::null_mut()),
164 );
165 }
166 }
167
168 #[cfg(feature = "v1_18")]
169 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
170 fn connect_samples_selected<
171 F: Fn(
172 &Self,
173 &gst::Segment,
174 Option<gst::ClockTime>,
175 Option<gst::ClockTime>,
176 Option<gst::ClockTime>,
177 Option<&gst::StructureRef>,
178 ) + Send
179 + 'static,
180 >(
181 &self,
182 f: F,
183 ) -> SignalHandlerId {
184 unsafe extern "C" fn samples_selected_trampoline<
185 P,
186 F: Fn(
187 &P,
188 &gst::Segment,
189 Option<gst::ClockTime>,
190 Option<gst::ClockTime>,
191 Option<gst::ClockTime>,
192 Option<&gst::StructureRef>,
193 ) + Send
194 + 'static,
195 >(
196 this: *mut ffi::GstAggregator,
197 segment: *mut gst::ffi::GstSegment,
198 pts: gst::ffi::GstClockTime,
199 dts: gst::ffi::GstClockTime,
200 duration: gst::ffi::GstClockTime,
201 info: *mut gst::ffi::GstStructure,
202 f: glib::ffi::gpointer,
203 ) where
204 P: IsA<Aggregator>,
205 {
206 let f: &F = &*(f as *const F);
207 f(
208 Aggregator::from_glib_borrow(this).unsafe_cast_ref(),
209 gst::Segment::from_glib_ptr_borrow(segment),
210 from_glib(pts),
211 from_glib(dts),
212 from_glib(duration),
213 if info.is_null() {
214 None
215 } else {
216 Some(gst::StructureRef::from_glib_borrow(info))
217 },
218 )
219 }
220
221 unsafe {
222 let f: Box_<F> = Box_::new(f);
223 connect_raw(
224 self.as_ptr() as *mut _,
225 b"samples-selected\0".as_ptr() as *const _,
226 Some(transmute::<*const (), unsafe extern "C" fn()>(
227 samples_selected_trampoline::<Self, F> as *const (),
228 )),
229 Box_::into_raw(f),
230 )
231 }
232 }
233
234 fn src_pad(&self) -> &AggregatorPad {
235 unsafe {
236 let elt = &*(self.as_ptr() as *const ffi::GstAggregator);
237 &*(&elt.srcpad as *const *mut gst::ffi::GstPad as *const AggregatorPad)
238 }
239 }
240}
241
242impl<O: IsA<Aggregator>> AggregatorExtManual for O {}
243
244#[cfg(feature = "v1_16")]
245#[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
246unsafe extern "C" fn notify_min_upstream_latency_trampoline<P, F: Fn(&P) + Send + Sync + 'static>(
247 this: *mut ffi::GstAggregator,
248 _param_spec: glib::ffi::gpointer,
249 f: glib::ffi::gpointer,
250) where
251 P: IsA<Aggregator>,
252{
253 let f: &F = &*(f as *const F);
254 f(Aggregator::from_glib_borrow(this).unsafe_cast_ref())
255}