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