1// Take a look at the license at the top of the repository in the LICENSE file.
2
3#[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::Aggregator;
18use crate::AggregatorPad;
19
20mod sealed {
21 pub trait Sealed {}
22 impl<T: super::IsA<super::Aggregator>> Sealed for T {}
23}
24
25pub trait AggregatorExtManual: sealed::Sealed + IsA<Aggregator> + 'static {
26 #[doc(alias = "get_allocator")]
27 #[doc(alias = "gst_aggregator_get_allocator")]
28 fn allocator(&self) -> (Option<gst::Allocator>, gst::AllocationParams) {
29 unsafe {
30 let mut allocator = ptr::null_mut();
31 let mut params = mem::MaybeUninit::uninit();
32 ffi::gst_aggregator_get_allocator(
33 self.as_ref().to_glib_none().0,
34 &mut allocator,
35 params.as_mut_ptr(),
36 );
37 (from_glib_full(allocator), params.assume_init().into())
38 }
39 }
40
41 #[cfg(feature = "v1_16")]
42 #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
43 #[doc(alias = "min-upstream-latency")]
44 fn min_upstream_latency(&self) -> gst::ClockTime {
45 self.as_ref().property("min-upstream-latency")
46 }
47
48 #[cfg(feature = "v1_16")]
49 #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
50 #[doc(alias = "min-upstream-latency")]
51 fn set_min_upstream_latency(&self, min_upstream_latency: gst::ClockTime) {
52 self.as_ref()
53 .set_property("min-upstream-latency", min_upstream_latency);
54 }
55
56 #[cfg(feature = "v1_16")]
57 #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
58 #[doc(alias = "min-upstream-latency")]
59 fn connect_min_upstream_latency_notify<F: Fn(&Self) + Send + Sync + 'static>(
60 &self,
61 f: F,
62 ) -> SignalHandlerId {
63 unsafe {
64 let f: Box_<F> = Box_::new(f);
65 connect_raw(
66 self.as_ptr() as *mut _,
67 b"notify::min-upstream-latency\0".as_ptr() as *const _,
68 Some(transmute::<_, unsafe extern "C" fn()>(
69 notify_min_upstream_latency_trampoline::<Self, F> as *const (),
70 )),
71 Box_::into_raw(f),
72 )
73 }
74 }
75
76 #[cfg(feature = "v1_18")]
77 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
78 #[doc(alias = "gst_aggregator_update_segment")]
79 fn update_segment<F: gst::format::FormattedValueIntrinsic>(
80 &self,
81 segment: &gst::FormattedSegment<F>,
82 ) {
83 unsafe {
84 ffi::gst_aggregator_update_segment(
85 self.as_ref().to_glib_none().0,
86 mut_override(segment.to_glib_none().0),
87 )
88 }
89 }
90
91 fn set_position(&self, position: impl FormattedValue) {
92 unsafe {
93 let ptr: *mut ffi::GstAggregator = self.as_ref().to_glib_none().0;
94 let ptr = &mut *ptr;
95 let _guard = self.as_ref().object_lock();
96
97 // gstaggregator.c asserts that the src pad is always of type GST_TYPE_AGGREGATOR_PAD,
98 // so the pointer cast here should be safe.
99 let srcpad = &mut *(ptr.srcpad as *mut ffi::GstAggregatorPad);
100
101 assert_eq!(srcpad.segment.format, position.format().into_glib());
102 srcpad.segment.position = position.into_raw_value() as u64;
103 }
104 }
105
106 #[cfg(feature = "v1_18")]
107 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
108 #[doc(alias = "gst_aggregator_selected_samples")]
109 fn selected_samples(
110 &self,
111 pts: impl Into<Option<gst::ClockTime>>,
112 dts: impl Into<Option<gst::ClockTime>>,
113 duration: impl Into<Option<gst::ClockTime>>,
114 info: Option<&gst::StructureRef>,
115 ) {
116 unsafe {
117 ffi::gst_aggregator_selected_samples(
118 self.as_ref().to_glib_none().0,
119 pts.into().into_glib(),
120 dts.into().into_glib(),
121 duration.into().into_glib(),
122 info.as_ref()
123 .map(|s| s.as_ptr() as *mut _)
124 .unwrap_or(ptr::null_mut()),
125 );
126 }
127 }
128
129 #[cfg(feature = "v1_18")]
130 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
131 fn connect_samples_selected<
132 F: Fn(
133 &Self,
134 &gst::Segment,
135 Option<gst::ClockTime>,
136 Option<gst::ClockTime>,
137 Option<gst::ClockTime>,
138 Option<&gst::StructureRef>,
139 ) + Send
140 + 'static,
141 >(
142 &self,
143 f: F,
144 ) -> SignalHandlerId {
145 unsafe extern "C" fn samples_selected_trampoline<
146 P,
147 F: Fn(
148 &P,
149 &gst::Segment,
150 Option<gst::ClockTime>,
151 Option<gst::ClockTime>,
152 Option<gst::ClockTime>,
153 Option<&gst::StructureRef>,
154 ) + Send
155 + 'static,
156 >(
157 this: *mut ffi::GstAggregator,
158 segment: *mut gst::ffi::GstSegment,
159 pts: gst::ffi::GstClockTime,
160 dts: gst::ffi::GstClockTime,
161 duration: gst::ffi::GstClockTime,
162 info: *mut gst::ffi::GstStructure,
163 f: glib::ffi::gpointer,
164 ) where
165 P: IsA<Aggregator>,
166 {
167 let f: &F = &*(f as *const F);
168 f(
169 Aggregator::from_glib_borrow(this).unsafe_cast_ref(),
170 gst::Segment::from_glib_ptr_borrow(segment),
171 from_glib(pts),
172 from_glib(dts),
173 from_glib(duration),
174 if info.is_null() {
175 None
176 } else {
177 Some(gst::StructureRef::from_glib_borrow(info))
178 },
179 )
180 }
181
182 unsafe {
183 let f: Box_<F> = Box_::new(f);
184 connect_raw(
185 self.as_ptr() as *mut _,
186 b"samples-selected\0".as_ptr() as *const _,
187 Some(transmute::<_, unsafe extern "C" fn()>(
188 samples_selected_trampoline::<Self, F> as *const (),
189 )),
190 Box_::into_raw(f),
191 )
192 }
193 }
194
195 fn src_pad(&self) -> &AggregatorPad {
196 unsafe {
197 let elt = &*(self.as_ptr() as *const ffi::GstAggregator);
198 &*(&elt.srcpad as *const *mut gst::ffi::GstPad as *const AggregatorPad)
199 }
200 }
201}
202
203impl<O: IsA<Aggregator>> AggregatorExtManual for O {}
204
205#[cfg(feature = "v1_16")]
206#[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
207unsafe extern "C" fn notify_min_upstream_latency_trampoline<P, F: Fn(&P) + Send + Sync + 'static>(
208 this: *mut ffi::GstAggregator,
209 _param_spec: glib::ffi::gpointer,
210 f: glib::ffi::gpointer,
211) where
212 P: IsA<Aggregator>,
213{
214 let f: &F = &*(f as *const F);
215 f(Aggregator::from_glib_borrow(this).unsafe_cast_ref())
216}
217