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")]
21 #[doc(alias = "gst_aggregator_get_allocator")]
22 fn allocator(&self) -> (Option<gst::Allocator>, gst::AllocationParams) {
23 unsafe {
24 let mut allocator = ptr::null_mut();
25 let mut params = mem::MaybeUninit::uninit();
26 ffi::gst_aggregator_get_allocator(
27 self.as_ref().to_glib_none().0,
28 &mut allocator,
29 params.as_mut_ptr(),
30 );
31 (from_glib_full(allocator), params.assume_init().into())
32 }
33 }
34
35 #[cfg(feature = "v1_30")]
36 #[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
37 #[doc(alias = "gst_aggregator_set_allocator")]
38 fn set_allocator(
39 &self,
40 pool: Option<impl IsA<gst::BufferPool>>,
41 allocator: Option<impl IsA<gst::Allocator>>,
42 params: Option<&gst::AllocationParams>,
43 query: Option<gst::query::Allocation<gst::Query>>,
44 ) -> Result<(), gst::LoggableError> {
45 unsafe {
46 gst::result_from_gboolean!(
47 ffi::gst_aggregator_set_allocator(
48 self.as_ref().to_glib_none().0,
49 pool.map(|p| p.upcast()).into_glib_ptr(),
50 allocator.map(|p| p.upcast()).into_glib_ptr(),
51 params.to_glib_none().0,
52 query.map(gst::Query::from).into_glib_ptr(),
53 ),
54 gst::CAT_RUST,
55 "Failed to set allocator"
56 )
57 }
58 }
59
60 #[cfg(feature = "v1_16")]
61 #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
62 #[doc(alias = "min-upstream-latency")]
63 fn min_upstream_latency(&self) -> gst::ClockTime {
64 self.as_ref().property("min-upstream-latency")
65 }
66
67 #[cfg(feature = "v1_16")]
68 #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
69 #[doc(alias = "min-upstream-latency")]
70 fn set_min_upstream_latency(&self, min_upstream_latency: gst::ClockTime) {
71 self.as_ref()
72 .set_property("min-upstream-latency", min_upstream_latency);
73 }
74
75 #[cfg(feature = "v1_16")]
76 #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
77 #[doc(alias = "min-upstream-latency")]
78 fn connect_min_upstream_latency_notify<F: Fn(&Self) + Send + Sync + 'static>(
79 &self,
80 f: F,
81 ) -> SignalHandlerId {
82 unsafe {
83 let f: Box_<F> = Box_::new(f);
84 connect_raw(
85 self.as_ptr() as *mut _,
86 b"notify::min-upstream-latency\0".as_ptr() as *const _,
87 Some(transmute::<*const (), unsafe extern "C" fn()>(
88 notify_min_upstream_latency_trampoline::<Self, F> as *const (),
89 )),
90 Box_::into_raw(f),
91 )
92 }
93 }
94
95 #[cfg(feature = "v1_18")]
96 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
97 #[doc(alias = "gst_aggregator_update_segment")]
98 fn update_segment<F: gst::format::FormattedValueIntrinsic>(
99 &self,
100 segment: &gst::FormattedSegment<F>,
101 ) {
102 unsafe {
103 ffi::gst_aggregator_update_segment(
104 self.as_ref().to_glib_none().0,
105 mut_override(segment.to_glib_none().0),
106 )
107 }
108 }
109
110 fn set_position(&self, position: impl FormattedValue) {
111 unsafe {
112 let ptr: *mut ffi::GstAggregator = self.as_ref().to_glib_none().0;
113 let ptr = &mut *ptr;
114 let _guard = self.as_ref().object_lock();
115
116 let srcpad = &mut *(ptr.srcpad as *mut ffi::GstAggregatorPad);
119
120 assert_eq!(srcpad.segment.format, position.format().into_glib());
121 srcpad.segment.position = position.into_raw_value() as u64;
122 }
123 }
124
125 #[cfg(feature = "v1_18")]
126 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
127 #[doc(alias = "gst_aggregator_selected_samples")]
128 fn selected_samples(
129 &self,
130 pts: impl Into<Option<gst::ClockTime>>,
131 dts: impl Into<Option<gst::ClockTime>>,
132 duration: impl Into<Option<gst::ClockTime>>,
133 info: Option<&gst::StructureRef>,
134 ) {
135 unsafe {
136 ffi::gst_aggregator_selected_samples(
137 self.as_ref().to_glib_none().0,
138 pts.into().into_glib(),
139 dts.into().into_glib(),
140 duration.into().into_glib(),
141 info.as_ref()
142 .map(|s| s.as_ptr() as *mut _)
143 .unwrap_or(ptr::null_mut()),
144 );
145 }
146 }
147
148 #[cfg(feature = "v1_18")]
149 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
150 fn connect_samples_selected<
151 F: Fn(
152 &Self,
153 &gst::Segment,
154 Option<gst::ClockTime>,
155 Option<gst::ClockTime>,
156 Option<gst::ClockTime>,
157 Option<&gst::StructureRef>,
158 ) + Send
159 + 'static,
160 >(
161 &self,
162 f: F,
163 ) -> SignalHandlerId {
164 unsafe extern "C" fn samples_selected_trampoline<
165 P,
166 F: Fn(
167 &P,
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 this: *mut ffi::GstAggregator,
177 segment: *mut gst::ffi::GstSegment,
178 pts: gst::ffi::GstClockTime,
179 dts: gst::ffi::GstClockTime,
180 duration: gst::ffi::GstClockTime,
181 info: *mut gst::ffi::GstStructure,
182 f: glib::ffi::gpointer,
183 ) where
184 P: IsA<Aggregator>,
185 {
186 unsafe {
187 let f: &F = &*(f as *const F);
188 f(
189 Aggregator::from_glib_borrow(this).unsafe_cast_ref(),
190 gst::Segment::from_glib_ptr_borrow(segment),
191 from_glib(pts),
192 from_glib(dts),
193 from_glib(duration),
194 if info.is_null() {
195 None
196 } else {
197 Some(gst::StructureRef::from_glib_borrow(info))
198 },
199 )
200 }
201 }
202
203 unsafe {
204 let f: Box_<F> = Box_::new(f);
205 connect_raw(
206 self.as_ptr() as *mut _,
207 b"samples-selected\0".as_ptr() as *const _,
208 Some(transmute::<*const (), unsafe extern "C" fn()>(
209 samples_selected_trampoline::<Self, F> as *const (),
210 )),
211 Box_::into_raw(f),
212 )
213 }
214 }
215
216 fn src_pad(&self) -> &AggregatorPad {
217 unsafe {
218 let elt = &*(self.as_ptr() as *const ffi::GstAggregator);
219 &*(&elt.srcpad as *const *mut gst::ffi::GstPad as *const AggregatorPad)
220 }
221 }
222}
223
224impl<O: IsA<Aggregator>> AggregatorExtManual for O {}
225
226#[cfg(feature = "v1_16")]
227#[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
228unsafe extern "C" fn notify_min_upstream_latency_trampoline<P, F: Fn(&P) + Send + Sync + 'static>(
229 this: *mut ffi::GstAggregator,
230 _param_spec: glib::ffi::gpointer,
231 f: glib::ffi::gpointer,
232) where
233 P: IsA<Aggregator>,
234{
235 unsafe {
236 let f: &F = &*(f as *const F);
237 f(Aggregator::from_glib_borrow(this).unsafe_cast_ref())
238 }
239}