Skip to main content

gstreamer_base/
aggregator.rs

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::{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            // gstaggregator.c asserts that the src pad is always of type GST_TYPE_AGGREGATOR_PAD,
117            // so the pointer cast here should be safe.
118            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}