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 {}