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