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
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_16")]
36 #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
37 #[doc(alias = "min-upstream-latency")]
38 fn min_upstream_latency(&self) -> gst::ClockTime {
39 self.as_ref().property("min-upstream-latency")
40 }
41
42 #[cfg(feature = "v1_16")]
43 #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
44 #[doc(alias = "min-upstream-latency")]
45 fn set_min_upstream_latency(&self, min_upstream_latency: gst::ClockTime) {
46 self.as_ref()
47 .set_property("min-upstream-latency", min_upstream_latency);
48 }
49
50 #[cfg(feature = "v1_16")]
51 #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
52 #[doc(alias = "min-upstream-latency")]
53 fn connect_min_upstream_latency_notify<F: Fn(&Self) + Send + Sync + 'static>(
54 &self,
55 f: F,
56 ) -> SignalHandlerId {
57 unsafe {
58 let f: Box_<F> = Box_::new(f);
59 connect_raw(
60 self.as_ptr() as *mut _,
61 b"notify::min-upstream-latency\0".as_ptr() as *const _,
62 Some(transmute::<*const (), unsafe extern "C" fn()>(
63 notify_min_upstream_latency_trampoline::<Self, F> as *const (),
64 )),
65 Box_::into_raw(f),
66 )
67 }
68 }
69
70 #[cfg(feature = "v1_18")]
71 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
72 #[doc(alias = "gst_aggregator_update_segment")]
73 fn update_segment<F: gst::format::FormattedValueIntrinsic>(
74 &self,
75 segment: &gst::FormattedSegment<F>,
76 ) {
77 unsafe {
78 ffi::gst_aggregator_update_segment(
79 self.as_ref().to_glib_none().0,
80 mut_override(segment.to_glib_none().0),
81 )
82 }
83 }
84
85 fn set_position(&self, position: impl FormattedValue) {
86 unsafe {
87 let ptr: *mut ffi::GstAggregator = self.as_ref().to_glib_none().0;
88 let ptr = &mut *ptr;
89 let _guard = self.as_ref().object_lock();
90
91 let srcpad = &mut *(ptr.srcpad as *mut ffi::GstAggregatorPad);
94
95 assert_eq!(srcpad.segment.format, position.format().into_glib());
96 srcpad.segment.position = position.into_raw_value() as u64;
97 }
98 }
99
100 #[cfg(feature = "v1_18")]
101 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
102 #[doc(alias = "gst_aggregator_selected_samples")]
103 fn selected_samples(
104 &self,
105 pts: impl Into<Option<gst::ClockTime>>,
106 dts: impl Into<Option<gst::ClockTime>>,
107 duration: impl Into<Option<gst::ClockTime>>,
108 info: Option<&gst::StructureRef>,
109 ) {
110 unsafe {
111 ffi::gst_aggregator_selected_samples(
112 self.as_ref().to_glib_none().0,
113 pts.into().into_glib(),
114 dts.into().into_glib(),
115 duration.into().into_glib(),
116 info.as_ref()
117 .map(|s| s.as_ptr() as *mut _)
118 .unwrap_or(ptr::null_mut()),
119 );
120 }
121 }
122
123 #[cfg(feature = "v1_18")]
124 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
125 fn connect_samples_selected<
126 F: Fn(
127 &Self,
128 &gst::Segment,
129 Option<gst::ClockTime>,
130 Option<gst::ClockTime>,
131 Option<gst::ClockTime>,
132 Option<&gst::StructureRef>,
133 ) + Send
134 + 'static,
135 >(
136 &self,
137 f: F,
138 ) -> SignalHandlerId {
139 unsafe extern "C" fn samples_selected_trampoline<
140 P,
141 F: Fn(
142 &P,
143 &gst::Segment,
144 Option<gst::ClockTime>,
145 Option<gst::ClockTime>,
146 Option<gst::ClockTime>,
147 Option<&gst::StructureRef>,
148 ) + Send
149 + 'static,
150 >(
151 this: *mut ffi::GstAggregator,
152 segment: *mut gst::ffi::GstSegment,
153 pts: gst::ffi::GstClockTime,
154 dts: gst::ffi::GstClockTime,
155 duration: gst::ffi::GstClockTime,
156 info: *mut gst::ffi::GstStructure,
157 f: glib::ffi::gpointer,
158 ) where
159 P: IsA<Aggregator>,
160 {
161 let f: &F = &*(f as *const F);
162 f(
163 Aggregator::from_glib_borrow(this).unsafe_cast_ref(),
164 gst::Segment::from_glib_ptr_borrow(segment),
165 from_glib(pts),
166 from_glib(dts),
167 from_glib(duration),
168 if info.is_null() {
169 None
170 } else {
171 Some(gst::StructureRef::from_glib_borrow(info))
172 },
173 )
174 }
175
176 unsafe {
177 let f: Box_<F> = Box_::new(f);
178 connect_raw(
179 self.as_ptr() as *mut _,
180 b"samples-selected\0".as_ptr() as *const _,
181 Some(transmute::<*const (), unsafe extern "C" fn()>(
182 samples_selected_trampoline::<Self, F> as *const (),
183 )),
184 Box_::into_raw(f),
185 )
186 }
187 }
188
189 fn src_pad(&self) -> &AggregatorPad {
190 unsafe {
191 let elt = &*(self.as_ptr() as *const ffi::GstAggregator);
192 &*(&elt.srcpad as *const *mut gst::ffi::GstPad as *const AggregatorPad)
193 }
194 }
195}
196
197impl<O: IsA<Aggregator>> AggregatorExtManual for O {}
198
199#[cfg(feature = "v1_16")]
200#[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
201unsafe extern "C" fn notify_min_upstream_latency_trampoline<P, F: Fn(&P) + Send + Sync + 'static>(
202 this: *mut ffi::GstAggregator,
203 _param_spec: glib::ffi::gpointer,
204 f: glib::ffi::gpointer,
205) where
206 P: IsA<Aggregator>,
207{
208 let f: &F = &*(f as *const F);
209 f(Aggregator::from_glib_borrow(this).unsafe_cast_ref())
210}