gstreamer_base/auto/
aggregator.rs

1// This file was generated by gir (https://github.com/gtk-rs/gir)
2// from gir-files (https://github.com/gtk-rs/gir-files)
3// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git)
4// DO NOT EDIT
5
6use crate::ffi;
7#[cfg(feature = "v1_18")]
8#[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
9use crate::{AggregatorPad, AggregatorStartTimeSelection};
10use glib::{
11    prelude::*,
12    signal::{connect_raw, SignalHandlerId},
13    translate::*,
14};
15use std::boxed::Box as Box_;
16
17glib::wrapper! {
18    /// Manages a set of pads with the purpose of aggregating their buffers.
19    /// Control is given to the subclass when all pads have data.
20    ///
21    ///  * Base class for mixers and muxers. Subclasses should at least implement
22    ///  the `GstAggregatorClass::aggregate` virtual method.
23    ///
24    ///  * Installs a `GstPadChainFunction`, a `GstPadEventFullFunction` and a
25    ///  `GstPadQueryFunction` to queue all serialized data packets per sink pad.
26    ///  Subclasses should not overwrite those, but instead implement
27    ///  `GstAggregatorClass::sink_event` and `GstAggregatorClass::sink_query` as
28    ///  needed.
29    ///
30    ///  * When data is queued on all pads, the aggregate vmethod is called.
31    ///
32    ///  * One can peek at the data on any given GstAggregatorPad with the
33    ///  [`AggregatorPadExt::peek_buffer()`][crate::prelude::AggregatorPadExt::peek_buffer()] method, and remove it from the pad
34    ///  with the gst_aggregator_pad_pop_buffer () method. When a buffer
35    ///  has been taken with pop_buffer (), a new buffer can be queued
36    ///  on that pad.
37    ///
38    ///  * When [`AggregatorPadExt::peek_buffer()`][crate::prelude::AggregatorPadExt::peek_buffer()] or [`AggregatorPadExt::has_buffer()`][crate::prelude::AggregatorPadExt::has_buffer()]
39    ///  are called, a reference is taken to the returned buffer, which stays
40    ///  valid until either:
41    ///
42    ///  - [`AggregatorPadExt::pop_buffer()`][crate::prelude::AggregatorPadExt::pop_buffer()] is called, in which case the caller
43    ///  is guaranteed that the buffer they receive is the same as the peeked
44    ///  buffer.
45    ///  - [`AggregatorPadExt::drop_buffer()`][crate::prelude::AggregatorPadExt::drop_buffer()] is called, in which case the caller
46    ///  is guaranteed that the dropped buffer is the one that was peeked.
47    ///  - the subclass implementation of `GstAggregatorClass.aggregate` returns.
48    ///
49    ///  Subsequent calls to [`AggregatorPadExt::peek_buffer()`][crate::prelude::AggregatorPadExt::peek_buffer()] or
50    ///  [`AggregatorPadExt::has_buffer()`][crate::prelude::AggregatorPadExt::has_buffer()] return / check the same buffer that was
51    ///  returned / checked, until one of the conditions listed above is met.
52    ///
53    ///  Subclasses are only allowed to call these methods from the aggregate
54    ///  thread.
55    ///
56    ///  * If the subclass wishes to push a buffer downstream in its aggregate
57    ///  implementation, it should do so through the
58    ///  [`AggregatorExt::finish_buffer()`][crate::prelude::AggregatorExt::finish_buffer()] method. This method will take care
59    ///  of sending and ordering mandatory events such as stream start, caps
60    ///  and segment. Buffer lists can also be pushed out with
61    ///  [`AggregatorExt::finish_buffer_list()`][crate::prelude::AggregatorExt::finish_buffer_list()].
62    ///
63    ///  * Same goes for EOS events, which should not be pushed directly by the
64    ///  subclass, it should instead return GST_FLOW_EOS in its aggregate
65    ///  implementation.
66    ///
67    ///  * Note that the aggregator logic regarding gap event handling is to turn
68    ///  these into gap buffers with matching PTS and duration. It will also
69    ///  flag these buffers with GST_BUFFER_FLAG_GAP and GST_BUFFER_FLAG_DROPPABLE
70    ///  to ease their identification and subsequent processing.
71    ///  In addition, if the gap event was flagged with GST_GAP_FLAG_MISSING_DATA,
72    ///  a custom meta is added to the resulting gap buffer (GstAggregatorMissingDataMeta).
73    ///
74    ///  * Subclasses must use (a subclass of) [`AggregatorPad`][crate::AggregatorPad] for both their
75    ///  sink and source pads.
76    ///  See `gst_element_class_add_static_pad_template_with_gtype()`.
77    ///
78    /// This class used to live in gst-plugins-bad and was moved to core.
79    ///
80    /// This is an Abstract Base Class, you cannot instantiate it.
81    ///
82    /// ## Properties
83    ///
84    ///
85    /// #### `emit-signals`
86    ///  Enables the emission of signals such as [`samples-selected`][struct@crate::Aggregator#samples-selected]
87    ///
88    /// Readable | Writeable
89    ///
90    ///
91    /// #### `latency`
92    ///  Readable | Writeable
93    ///
94    ///
95    /// #### `min-upstream-latency`
96    ///  Force minimum upstream latency (in nanoseconds). When sources with a
97    /// higher latency are expected to be plugged in dynamically after the
98    /// aggregator has started playing, this allows overriding the minimum
99    /// latency reported by the initial source(s). This is only taken into
100    /// account when larger than the actually reported minimum latency.
101    ///
102    /// Readable | Writeable
103    ///
104    ///
105    /// #### `start-time`
106    ///  Readable | Writeable
107    ///
108    ///
109    /// #### `start-time-selection`
110    ///  Readable | Writeable
111    /// <details><summary><h4>Object</h4></summary>
112    ///
113    ///
114    /// #### `name`
115    ///  Readable | Writeable | Construct
116    ///
117    ///
118    /// #### `parent`
119    ///  The parent of the object. Please note, that when changing the 'parent'
120    /// property, we don't emit [`notify`][struct@crate::glib::Object#notify] and [`deep-notify`][struct@crate::gst::Object#deep-notify]
121    /// signals due to locking issues. In some cases one can use
122    /// `GstBin::element-added` or `GstBin::element-removed` signals on the parent to
123    /// achieve a similar effect.
124    ///
125    /// Readable | Writeable
126    /// </details>
127    ///
128    /// ## Signals
129    ///
130    ///
131    /// #### `samples-selected`
132    ///  Signals that the [`Aggregator`][crate::Aggregator] subclass has selected the next set
133    /// of input samples it will aggregate. Handlers may call
134    /// [`AggregatorExt::peek_next_sample()`][crate::prelude::AggregatorExt::peek_next_sample()] at that point.
135    ///
136    ///
137    /// <details><summary><h4>Element</h4></summary>
138    ///
139    ///
140    /// #### `no-more-pads`
141    ///  This signals that the element will not generate more dynamic pads.
142    /// Note that this signal will usually be emitted from the context of
143    /// the streaming thread.
144    ///
145    ///
146    ///
147    ///
148    /// #### `pad-added`
149    ///  a new [`gst::Pad`][crate::gst::Pad] has been added to the element. Note that this signal will
150    /// usually be emitted from the context of the streaming thread. Also keep in
151    /// mind that if you add new elements to the pipeline in the signal handler
152    /// you will need to set them to the desired target state with
153    /// [`ElementExtManual::set_state()`][crate::gst::prelude::ElementExtManual::set_state()] or [`ElementExtManual::sync_state_with_parent()`][crate::gst::prelude::ElementExtManual::sync_state_with_parent()].
154    ///
155    ///
156    ///
157    ///
158    /// #### `pad-removed`
159    ///  a [`gst::Pad`][crate::gst::Pad] has been removed from the element
160    ///
161    ///
162    /// </details>
163    /// <details><summary><h4>Object</h4></summary>
164    ///
165    ///
166    /// #### `deep-notify`
167    ///  The deep notify signal is used to be notified of property changes. It is
168    /// typically attached to the toplevel bin to receive notifications from all
169    /// the elements contained in that bin.
170    ///
171    /// Detailed
172    /// </details>
173    ///
174    /// # Implements
175    ///
176    /// [`AggregatorExt`][trait@crate::prelude::AggregatorExt], [`trait@gst::prelude::ElementExt`], [`trait@gst::prelude::ObjectExt`], [`trait@glib::ObjectExt`], [`AggregatorExtManual`][trait@crate::prelude::AggregatorExtManual]
177    #[doc(alias = "GstAggregator")]
178    pub struct Aggregator(Object<ffi::GstAggregator, ffi::GstAggregatorClass>) @extends gst::Element, gst::Object;
179
180    match fn {
181        type_ => || ffi::gst_aggregator_get_type(),
182    }
183}
184
185impl Aggregator {
186    pub const NONE: Option<&'static Aggregator> = None;
187}
188
189unsafe impl Send for Aggregator {}
190unsafe impl Sync for Aggregator {}
191
192mod sealed {
193    pub trait Sealed {}
194    impl<T: super::IsA<super::Aggregator>> Sealed for T {}
195}
196
197/// Trait containing all [`struct@Aggregator`] methods.
198///
199/// # Implementors
200///
201/// [`Aggregator`][struct@crate::Aggregator]
202pub trait AggregatorExt: IsA<Aggregator> + sealed::Sealed + 'static {
203    /// This method will push the provided output buffer downstream. If needed,
204    /// mandatory events such as stream-start, caps, and segment events will be
205    /// sent before pushing the buffer.
206    /// ## `buffer`
207    /// the [`gst::Buffer`][crate::gst::Buffer] to push.
208    #[doc(alias = "gst_aggregator_finish_buffer")]
209    fn finish_buffer(&self, buffer: gst::Buffer) -> Result<gst::FlowSuccess, gst::FlowError> {
210        unsafe {
211            try_from_glib(ffi::gst_aggregator_finish_buffer(
212                self.as_ref().to_glib_none().0,
213                buffer.into_glib_ptr(),
214            ))
215        }
216    }
217
218    /// This method will push the provided output buffer list downstream. If needed,
219    /// mandatory events such as stream-start, caps, and segment events will be
220    /// sent before pushing the buffer.
221    /// ## `bufferlist`
222    /// the [`gst::BufferList`][crate::gst::BufferList] to push.
223    #[cfg(feature = "v1_18")]
224    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
225    #[doc(alias = "gst_aggregator_finish_buffer_list")]
226    fn finish_buffer_list(
227        &self,
228        bufferlist: gst::BufferList,
229    ) -> Result<gst::FlowSuccess, gst::FlowError> {
230        unsafe {
231            try_from_glib(ffi::gst_aggregator_finish_buffer_list(
232                self.as_ref().to_glib_none().0,
233                bufferlist.into_glib_ptr(),
234            ))
235        }
236    }
237
238    ///
239    /// # Returns
240    ///
241    /// the instance of the [`gst::BufferPool`][crate::gst::BufferPool] used
242    /// by `trans`; free it after use it
243    #[doc(alias = "gst_aggregator_get_buffer_pool")]
244    #[doc(alias = "get_buffer_pool")]
245    fn buffer_pool(&self) -> Option<gst::BufferPool> {
246        unsafe {
247            from_glib_full(ffi::gst_aggregator_get_buffer_pool(
248                self.as_ref().to_glib_none().0,
249            ))
250        }
251    }
252
253    /// Subclasses may use the return value to inform whether they should return
254    /// [`gst::FlowReturn::Eos`][crate::gst::FlowReturn::Eos] from their aggregate implementation.
255    ///
256    /// # Returns
257    ///
258    /// whether live status was forced on `self`.
259    #[cfg(feature = "v1_22")]
260    #[cfg_attr(docsrs, doc(cfg(feature = "v1_22")))]
261    #[doc(alias = "gst_aggregator_get_force_live")]
262    #[doc(alias = "get_force_live")]
263    fn is_force_live(&self) -> bool {
264        unsafe {
265            from_glib(ffi::gst_aggregator_get_force_live(
266                self.as_ref().to_glib_none().0,
267            ))
268        }
269    }
270
271    ///
272    /// # Returns
273    ///
274    /// whether inactive pads will not be waited on
275    #[cfg(feature = "v1_20")]
276    #[cfg_attr(docsrs, doc(cfg(feature = "v1_20")))]
277    #[doc(alias = "gst_aggregator_get_ignore_inactive_pads")]
278    #[doc(alias = "get_ignore_inactive_pads")]
279    fn ignores_inactive_pads(&self) -> bool {
280        unsafe {
281            from_glib(ffi::gst_aggregator_get_ignore_inactive_pads(
282                self.as_ref().to_glib_none().0,
283            ))
284        }
285    }
286
287    /// Retrieves the latency values reported by `self` in response to the latency
288    /// query, or `GST_CLOCK_TIME_NONE` if there is not live source connected and the element
289    /// will not wait for the clock.
290    ///
291    /// Typically only called by subclasses.
292    ///
293    /// # Returns
294    ///
295    /// The latency or `GST_CLOCK_TIME_NONE` if the element does not sync
296    #[doc(alias = "gst_aggregator_get_latency")]
297    #[doc(alias = "get_latency")]
298    fn latency(&self) -> Option<gst::ClockTime> {
299        unsafe {
300            from_glib(ffi::gst_aggregator_get_latency(
301                self.as_ref().to_glib_none().0,
302            ))
303        }
304    }
305
306    /// Negotiates src pad caps with downstream elements.
307    /// Unmarks GST_PAD_FLAG_NEED_RECONFIGURE in any case. But marks it again
308    /// if `GstAggregatorClass::negotiate` fails.
309    ///
310    /// # Returns
311    ///
312    /// [`true`] if the negotiation succeeded, else [`false`].
313    #[cfg(feature = "v1_18")]
314    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
315    #[doc(alias = "gst_aggregator_negotiate")]
316    fn negotiate(&self) -> bool {
317        unsafe {
318            from_glib(ffi::gst_aggregator_negotiate(
319                self.as_ref().to_glib_none().0,
320            ))
321        }
322    }
323
324    /// Use this function to determine what input buffers will be aggregated
325    /// to produce the next output buffer. This should only be called from
326    /// a [`samples-selected`][struct@crate::Aggregator#samples-selected] handler, and can be used to precisely
327    /// control aggregating parameters for a given set of input samples.
328    ///
329    /// # Returns
330    ///
331    /// The sample that is about to be aggregated. It may hold a [`gst::Buffer`][crate::gst::Buffer]
332    ///  or a [`gst::BufferList`][crate::gst::BufferList]. The contents of its info structure is subclass-dependent,
333    ///  and documented on a subclass basis. The buffers held by the sample are
334    ///  not writable.
335    #[cfg(feature = "v1_18")]
336    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
337    #[doc(alias = "gst_aggregator_peek_next_sample")]
338    fn peek_next_sample(&self, pad: &impl IsA<AggregatorPad>) -> Option<gst::Sample> {
339        unsafe {
340            from_glib_full(ffi::gst_aggregator_peek_next_sample(
341                self.as_ref().to_glib_none().0,
342                pad.as_ref().to_glib_none().0,
343            ))
344        }
345    }
346
347    /// This method will push the provided event downstream. If needed, mandatory
348    /// events such as stream-start, caps, and segment events will be sent before
349    /// pushing the event.
350    ///
351    /// This API does not allow pushing stream-start, caps, segment and EOS events.
352    /// Specific API like [`set_src_caps()`][Self::set_src_caps()] should be used for these.
353    /// ## `event`
354    /// the [`gst::Event`][crate::gst::Event] to push.
355    #[cfg(feature = "v1_26")]
356    #[cfg_attr(docsrs, doc(cfg(feature = "v1_26")))]
357    #[doc(alias = "gst_aggregator_push_src_event")]
358    fn push_src_event(&self, event: gst::Event) -> bool {
359        unsafe {
360            from_glib(ffi::gst_aggregator_push_src_event(
361                self.as_ref().to_glib_none().0,
362                event.into_glib_ptr(),
363            ))
364        }
365    }
366
367    /// Subclasses should call this at construction time in order for `self` to
368    /// aggregate on a timeout even when no live source is connected.
369    #[cfg(feature = "v1_22")]
370    #[cfg_attr(docsrs, doc(cfg(feature = "v1_22")))]
371    #[doc(alias = "gst_aggregator_set_force_live")]
372    fn set_force_live(&self, force_live: bool) {
373        unsafe {
374            ffi::gst_aggregator_set_force_live(
375                self.as_ref().to_glib_none().0,
376                force_live.into_glib(),
377            );
378        }
379    }
380
381    /// Subclasses should call this when they don't want to time out
382    /// waiting for a pad that hasn't yet received any buffers in live
383    /// mode.
384    ///
385    /// [`Aggregator`][crate::Aggregator] will still wait once on each newly-added pad, making
386    /// sure upstream has had a fair chance to start up.
387    /// ## `ignore`
388    /// whether inactive pads should not be waited on
389    #[cfg(feature = "v1_20")]
390    #[cfg_attr(docsrs, doc(cfg(feature = "v1_20")))]
391    #[doc(alias = "gst_aggregator_set_ignore_inactive_pads")]
392    fn set_ignore_inactive_pads(&self, ignore: bool) {
393        unsafe {
394            ffi::gst_aggregator_set_ignore_inactive_pads(
395                self.as_ref().to_glib_none().0,
396                ignore.into_glib(),
397            );
398        }
399    }
400
401    /// Lets [`Aggregator`][crate::Aggregator] sub-classes tell the baseclass what their internal
402    /// latency is. Will also post a LATENCY message on the bus so the pipeline
403    /// can reconfigure its global latency if the values changed.
404    /// ## `min_latency`
405    /// minimum latency
406    /// ## `max_latency`
407    /// maximum latency
408    #[doc(alias = "gst_aggregator_set_latency")]
409    #[doc(alias = "latency")]
410    fn set_latency(
411        &self,
412        min_latency: gst::ClockTime,
413        max_latency: impl Into<Option<gst::ClockTime>>,
414    ) {
415        unsafe {
416            ffi::gst_aggregator_set_latency(
417                self.as_ref().to_glib_none().0,
418                min_latency.into_glib(),
419                max_latency.into().into_glib(),
420            );
421        }
422    }
423
424    /// Sets the caps to be used on the src pad.
425    /// ## `caps`
426    /// The [`gst::Caps`][crate::gst::Caps] to set on the src pad.
427    #[doc(alias = "gst_aggregator_set_src_caps")]
428    fn set_src_caps(&self, caps: &gst::Caps) {
429        unsafe {
430            ffi::gst_aggregator_set_src_caps(self.as_ref().to_glib_none().0, caps.to_glib_none().0);
431        }
432    }
433
434    /// This is a simple `GstAggregatorClass::get_next_time` implementation that
435    /// just looks at the [`gst::Segment`][crate::gst::Segment] on the srcpad of the aggregator and bases
436    /// the next time on the running time there.
437    ///
438    /// This is the desired behaviour in most cases where you have a live source
439    /// and you have a dead line based aggregator subclass.
440    ///
441    /// # Returns
442    ///
443    /// The running time based on the position
444    #[cfg(feature = "v1_16")]
445    #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
446    #[doc(alias = "gst_aggregator_simple_get_next_time")]
447    fn simple_get_next_time(&self) -> Option<gst::ClockTime> {
448        unsafe {
449            from_glib(ffi::gst_aggregator_simple_get_next_time(
450                self.as_ref().to_glib_none().0,
451            ))
452        }
453    }
454
455    /// Enables the emission of signals such as [`samples-selected`][struct@crate::Aggregator#samples-selected]
456    #[cfg(feature = "v1_18")]
457    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
458    #[doc(alias = "emit-signals")]
459    fn emits_signals(&self) -> bool {
460        ObjectExt::property(self.as_ref(), "emit-signals")
461    }
462
463    /// Enables the emission of signals such as [`samples-selected`][struct@crate::Aggregator#samples-selected]
464    #[cfg(feature = "v1_18")]
465    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
466    #[doc(alias = "emit-signals")]
467    fn set_emit_signals(&self, emit_signals: bool) {
468        ObjectExt::set_property(self.as_ref(), "emit-signals", emit_signals)
469    }
470
471    #[doc(alias = "start-time")]
472    fn start_time(&self) -> u64 {
473        ObjectExt::property(self.as_ref(), "start-time")
474    }
475
476    #[doc(alias = "start-time")]
477    fn set_start_time(&self, start_time: u64) {
478        ObjectExt::set_property(self.as_ref(), "start-time", start_time)
479    }
480
481    #[cfg(feature = "v1_18")]
482    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
483    #[doc(alias = "start-time-selection")]
484    fn start_time_selection(&self) -> AggregatorStartTimeSelection {
485        ObjectExt::property(self.as_ref(), "start-time-selection")
486    }
487
488    #[cfg(feature = "v1_18")]
489    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
490    #[doc(alias = "start-time-selection")]
491    fn set_start_time_selection(&self, start_time_selection: AggregatorStartTimeSelection) {
492        ObjectExt::set_property(self.as_ref(), "start-time-selection", start_time_selection)
493    }
494
495    #[cfg(feature = "v1_18")]
496    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
497    #[doc(alias = "emit-signals")]
498    fn connect_emit_signals_notify<F: Fn(&Self) + Send + Sync + 'static>(
499        &self,
500        f: F,
501    ) -> SignalHandlerId {
502        unsafe extern "C" fn notify_emit_signals_trampoline<
503            P: IsA<Aggregator>,
504            F: Fn(&P) + Send + Sync + 'static,
505        >(
506            this: *mut ffi::GstAggregator,
507            _param_spec: glib::ffi::gpointer,
508            f: glib::ffi::gpointer,
509        ) {
510            let f: &F = &*(f as *const F);
511            f(Aggregator::from_glib_borrow(this).unsafe_cast_ref())
512        }
513        unsafe {
514            let f: Box_<F> = Box_::new(f);
515            connect_raw(
516                self.as_ptr() as *mut _,
517                b"notify::emit-signals\0".as_ptr() as *const _,
518                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
519                    notify_emit_signals_trampoline::<Self, F> as *const (),
520                )),
521                Box_::into_raw(f),
522            )
523        }
524    }
525
526    #[doc(alias = "latency")]
527    fn connect_latency_notify<F: Fn(&Self) + Send + Sync + 'static>(
528        &self,
529        f: F,
530    ) -> SignalHandlerId {
531        unsafe extern "C" fn notify_latency_trampoline<
532            P: IsA<Aggregator>,
533            F: Fn(&P) + Send + Sync + 'static,
534        >(
535            this: *mut ffi::GstAggregator,
536            _param_spec: glib::ffi::gpointer,
537            f: glib::ffi::gpointer,
538        ) {
539            let f: &F = &*(f as *const F);
540            f(Aggregator::from_glib_borrow(this).unsafe_cast_ref())
541        }
542        unsafe {
543            let f: Box_<F> = Box_::new(f);
544            connect_raw(
545                self.as_ptr() as *mut _,
546                b"notify::latency\0".as_ptr() as *const _,
547                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
548                    notify_latency_trampoline::<Self, F> as *const (),
549                )),
550                Box_::into_raw(f),
551            )
552        }
553    }
554
555    #[doc(alias = "start-time")]
556    fn connect_start_time_notify<F: Fn(&Self) + Send + Sync + 'static>(
557        &self,
558        f: F,
559    ) -> SignalHandlerId {
560        unsafe extern "C" fn notify_start_time_trampoline<
561            P: IsA<Aggregator>,
562            F: Fn(&P) + Send + Sync + 'static,
563        >(
564            this: *mut ffi::GstAggregator,
565            _param_spec: glib::ffi::gpointer,
566            f: glib::ffi::gpointer,
567        ) {
568            let f: &F = &*(f as *const F);
569            f(Aggregator::from_glib_borrow(this).unsafe_cast_ref())
570        }
571        unsafe {
572            let f: Box_<F> = Box_::new(f);
573            connect_raw(
574                self.as_ptr() as *mut _,
575                b"notify::start-time\0".as_ptr() as *const _,
576                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
577                    notify_start_time_trampoline::<Self, F> as *const (),
578                )),
579                Box_::into_raw(f),
580            )
581        }
582    }
583
584    #[cfg(feature = "v1_18")]
585    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
586    #[doc(alias = "start-time-selection")]
587    fn connect_start_time_selection_notify<F: Fn(&Self) + Send + Sync + 'static>(
588        &self,
589        f: F,
590    ) -> SignalHandlerId {
591        unsafe extern "C" fn notify_start_time_selection_trampoline<
592            P: IsA<Aggregator>,
593            F: Fn(&P) + Send + Sync + 'static,
594        >(
595            this: *mut ffi::GstAggregator,
596            _param_spec: glib::ffi::gpointer,
597            f: glib::ffi::gpointer,
598        ) {
599            let f: &F = &*(f as *const F);
600            f(Aggregator::from_glib_borrow(this).unsafe_cast_ref())
601        }
602        unsafe {
603            let f: Box_<F> = Box_::new(f);
604            connect_raw(
605                self.as_ptr() as *mut _,
606                b"notify::start-time-selection\0".as_ptr() as *const _,
607                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
608                    notify_start_time_selection_trampoline::<Self, F> as *const (),
609                )),
610                Box_::into_raw(f),
611            )
612        }
613    }
614}
615
616impl<O: IsA<Aggregator>> AggregatorExt for O {}