1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
// This file was generated by gir (https://github.com/gtk-rs/gir)
// from gir-files (https://github.com/gtk-rs/gir-files)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git)
// DO NOT EDIT

#[cfg(feature = "v1_20")]
#[cfg_attr(docsrs, doc(cfg(feature = "v1_20")))]
use crate::RTPHeaderExtension;
use glib::{
    prelude::*,
    signal::{connect_raw, SignalHandlerId},
    translate::*,
};
use std::boxed::Box as Box_;

glib::wrapper! {
    /// Provides a base class for RTP depayloaders
    ///
    /// In order to handle RTP header extensions correctly if the
    /// depayloader aggregates multiple RTP packet payloads into one output
    /// buffer this class provides the function
    /// [`RTPBaseDepayloadExt::set_aggregate_hdrext_enabled()`][crate::prelude::RTPBaseDepayloadExt::set_aggregate_hdrext_enabled()]. If the
    /// aggregation is enabled the virtual functions
    /// [`RTPBaseDepayload`][crate::RTPBaseDepayload] or
    /// [`RTPBaseDepayload`][crate::RTPBaseDepayload] must tell the base class
    /// what happens to the current RTP packet. By default the base class
    /// assumes that the packet payload is used with the next output
    /// buffer.
    ///
    /// If the RTP packet will not be used with an output buffer
    /// [`RTPBaseDepayloadExt::dropped()`][crate::prelude::RTPBaseDepayloadExt::dropped()] must be called. A typical
    /// situation would be if we are waiting for a keyframe.
    ///
    /// If the RTP packet will be used but not with the current output
    /// buffer but with the next one [`RTPBaseDepayloadExt::delayed()`][crate::prelude::RTPBaseDepayloadExt::delayed()] must
    /// be called. This may happen if the current RTP packet signals the
    /// start of a new output buffer and the currently processed output
    /// buffer will be pushed first. The undelay happens implicitly once
    /// the current buffer has been pushed or
    /// [`RTPBaseDepayloadExt::flush()`][crate::prelude::RTPBaseDepayloadExt::flush()] has been called.
    ///
    /// If [`RTPBaseDepayloadExt::flush()`][crate::prelude::RTPBaseDepayloadExt::flush()] is called all RTP packets that
    /// have not been dropped since the last output buffer are dropped,
    /// e.g. if an output buffer is discarded due to malformed data. This
    /// may or may not include the current RTP packet depending on the 2nd
    /// parameter `keep_current`.
    ///
    /// Be aware that in case [`RTPBaseDepayloadExt::push_list()`][crate::prelude::RTPBaseDepayloadExt::push_list()] is used
    /// each buffer will see the same list of RTP header extensions.
    ///
    /// This is an Abstract Base Class, you cannot instantiate it.
    ///
    /// ## Properties
    ///
    ///
    /// #### `auto-header-extension`
    ///  If enabled, the depayloader will automatically try to enable all the
    /// RTP header extensions provided in the sink caps, saving the application
    /// the need to handle these extensions manually using the
    /// GstRTPBaseDepayload::request-extension: signal.
    ///
    /// Readable | Writeable
    ///
    ///
    /// #### `extensions`
    ///  A list of already enabled RTP header extensions. This may be useful for finding
    /// out which extensions are already enabled (with add-extension signal) and picking a non-conflicting
    /// ID for a new extension that needs to be added on top of the existing ones.
    ///
    /// Note that the value returned by reading this property is not dynamically updated when the set of
    /// enabled extensions changes by any of existing action signals. Rather, it represents the current state
    /// at the time the property is read.
    ///
    /// Dynamic updates of this property can be received by subscribing to its corresponding "notify" signal, i.e.
    /// "notify::extensions".
    ///
    /// Readable
    ///
    ///
    /// #### `max-reorder`
    ///  Max seqnum reorder before the sender is assumed to have restarted.
    ///
    /// When max-reorder is set to 0 all reordered/duplicate packets are
    /// considered coming from a restarted sender.
    ///
    /// Readable | Writeable
    ///
    ///
    /// #### `source-info`
    ///  Add RTP source information found in RTP header as meta to output buffer.
    ///
    /// Readable | Writeable
    ///
    ///
    /// #### `stats`
    ///  Various depayloader statistics retrieved atomically (and are therefore
    /// synchroized with each other). This property return a GstStructure named
    /// application/x-rtp-depayload-stats containing the following fields relating to
    /// the last processed buffer and current state of the stream being depayloaded:
    ///
    ///  * `clock-rate`: `G_TYPE_UINT`, clock-rate of the stream
    ///  * `npt-start`: `G_TYPE_UINT64`, time of playback start
    ///  * `npt-stop`: `G_TYPE_UINT64`, time of playback stop
    ///  * `play-speed`: `G_TYPE_DOUBLE`, the playback speed
    ///  * `play-scale`: `G_TYPE_DOUBLE`, the playback scale
    ///  * `running-time-dts`: `G_TYPE_UINT64`, the last running-time of the
    ///  last DTS
    ///  * `running-time-pts`: `G_TYPE_UINT64`, the last running-time of the
    ///  last PTS
    ///  * `seqnum`: `G_TYPE_UINT`, the last seen seqnum
    ///  * `timestamp`: `G_TYPE_UINT`, the last seen RTP timestamp
    ///
    /// Readable
    /// <details><summary><h4>Object</h4></summary>
    ///
    ///
    /// #### `name`
    ///  Readable | Writeable | Construct
    ///
    ///
    /// #### `parent`
    ///  The parent of the object. Please note, that when changing the 'parent'
    /// property, we don't emit `GObject::notify` and [`deep-notify`][struct@crate::gst::Object#deep-notify]
    /// signals due to locking issues. In some cases one can use
    /// `GstBin::element-added` or `GstBin::element-removed` signals on the parent to
    /// achieve a similar effect.
    ///
    /// Readable | Writeable
    /// </details>
    ///
    /// ## Signals
    ///
    ///
    /// #### `add-extension`
    ///  Add `ext` as an extension for reading part of an RTP header extension from
    /// incoming RTP packets.
    ///
    /// Action
    ///
    ///
    /// #### `clear-extensions`
    ///  Clear all RTP header extensions used by this depayloader.
    ///
    /// Action
    ///
    ///
    /// #### `request-extension`
    ///  The returned `ext` must be configured with the correct `ext_id` and with the
    /// necessary attributes as required by the extension implementation.
    ///
    ///
    /// <details><summary><h4>Element</h4></summary>
    ///
    ///
    /// #### `no-more-pads`
    ///  This signals that the element will not generate more dynamic pads.
    /// Note that this signal will usually be emitted from the context of
    /// the streaming thread.
    ///
    ///
    ///
    ///
    /// #### `pad-added`
    ///  a new `GstPad` has been added to the element. Note that this signal will
    /// usually be emitted from the context of the streaming thread. Also keep in
    /// mind that if you add new elements to the pipeline in the signal handler
    /// you will need to set them to the desired target state with
    /// [`ElementExtManual::set_state()`][crate::gst::prelude::ElementExtManual::set_state()] or [`ElementExtManual::sync_state_with_parent()`][crate::gst::prelude::ElementExtManual::sync_state_with_parent()].
    ///
    ///
    ///
    ///
    /// #### `pad-removed`
    ///  a `GstPad` has been removed from the element
    ///
    ///
    /// </details>
    /// <details><summary><h4>Object</h4></summary>
    ///
    ///
    /// #### `deep-notify`
    ///  The deep notify signal is used to be notified of property changes. It is
    /// typically attached to the toplevel bin to receive notifications from all
    /// the elements contained in that bin.
    ///
    /// Detailed
    /// </details>
    ///
    /// # Implements
    ///
    /// [`RTPBaseDepayloadExt`][trait@crate::prelude::RTPBaseDepayloadExt], [`trait@gst::prelude::ElementExt`], [`trait@gst::prelude::ObjectExt`], [`RTPBaseDepayloadExtManual`][trait@crate::prelude::RTPBaseDepayloadExtManual]
    #[doc(alias = "GstRTPBaseDepayload")]
    pub struct RTPBaseDepayload(Object<ffi::GstRTPBaseDepayload, ffi::GstRTPBaseDepayloadClass>) @extends gst::Element, gst::Object;

    match fn {
        type_ => || ffi::gst_rtp_base_depayload_get_type(),
    }
}

impl RTPBaseDepayload {
    pub const NONE: Option<&'static RTPBaseDepayload> = None;
}

unsafe impl Send for RTPBaseDepayload {}
unsafe impl Sync for RTPBaseDepayload {}

mod sealed {
    pub trait Sealed {}
    impl<T: super::IsA<super::RTPBaseDepayload>> Sealed for T {}
}

/// Trait containing all [`struct@RTPBaseDepayload`] methods.
///
/// # Implementors
///
/// [`RTPBaseDepayload`][struct@crate::RTPBaseDepayload]
pub trait RTPBaseDepayloadExt: IsA<RTPBaseDepayload> + sealed::Sealed + 'static {
    /// Called from [`RTPBaseDepayload`][crate::RTPBaseDepayload] or
    /// [`RTPBaseDepayload`][crate::RTPBaseDepayload] when the depayloader needs
    /// to keep the current input RTP header for use with the next output
    /// buffer.
    ///
    /// The delayed buffer will remain until the end of processing the
    /// current output buffer and then enqueued for processing with the
    /// next output buffer.
    ///
    /// A typical use-case is when the depayloader implementation will
    /// start a new output buffer for the current input RTP buffer but push
    /// the current output buffer first.
    ///
    /// Must be called with the stream lock held.
    #[cfg(feature = "v1_24")]
    #[cfg_attr(docsrs, doc(cfg(feature = "v1_24")))]
    #[doc(alias = "gst_rtp_base_depayload_delayed")]
    fn delayed(&self) {
        unsafe {
            ffi::gst_rtp_base_depayload_delayed(self.as_ref().to_glib_none().0);
        }
    }

    /// Called from [`RTPBaseDepayload`][crate::RTPBaseDepayload] or
    /// [`RTPBaseDepayload`][crate::RTPBaseDepayload] if the depayloader does not
    /// use the current buffer for the output buffer. This will either drop
    /// the delayed buffer or the last buffer from the header extension
    /// cache.
    ///
    /// A typical use-case is when the depayloader implementation is
    /// dropping an input RTP buffer while waiting for the first keyframe.
    ///
    /// Must be called with the stream lock held.
    #[cfg(feature = "v1_24")]
    #[cfg_attr(docsrs, doc(cfg(feature = "v1_24")))]
    #[doc(alias = "gst_rtp_base_depayload_dropped")]
    fn dropped(&self) {
        unsafe {
            ffi::gst_rtp_base_depayload_dropped(self.as_ref().to_glib_none().0);
        }
    }

    /// If [`RTPBaseDepayload`][crate::RTPBaseDepayload] or
    /// [`RTPBaseDepayload`][crate::RTPBaseDepayload] drop an output buffer this
    /// function tells the base class to flush header extension cache as
    /// well.
    ///
    /// This will not drop an input RTP header marked as delayed from
    /// [`delayed()`][Self::delayed()].
    ///
    /// If `keep_current` is [`true`] the current input RTP header will be kept
    /// and enqueued after flushing the previous input RTP headers.
    ///
    /// A typical use-case for `keep_current` is when the depayloader
    /// implementation invalidates the current output buffer and starts a
    /// new one with the current RTP input buffer.
    ///
    /// Must be called with the stream lock held.
    /// ## `keep_current`
    /// if the current RTP buffer shall be kept
    #[cfg(feature = "v1_24")]
    #[cfg_attr(docsrs, doc(cfg(feature = "v1_24")))]
    #[doc(alias = "gst_rtp_base_depayload_flush")]
    fn flush(&self, keep_current: bool) {
        unsafe {
            ffi::gst_rtp_base_depayload_flush(
                self.as_ref().to_glib_none().0,
                keep_current.into_glib(),
            );
        }
    }

    /// Queries whether header extensions will be aggregated per depayloaded buffers.
    ///
    /// # Returns
    ///
    /// [`true`] if aggregate-header-extension is enabled.
    #[cfg(feature = "v1_24")]
    #[cfg_attr(docsrs, doc(cfg(feature = "v1_24")))]
    #[doc(alias = "gst_rtp_base_depayload_is_aggregate_hdrext_enabled")]
    fn is_aggregate_hdrext_enabled(&self) -> bool {
        unsafe {
            from_glib(ffi::gst_rtp_base_depayload_is_aggregate_hdrext_enabled(
                self.as_ref().to_glib_none().0,
            ))
        }
    }

    /// Queries whether `GstRTPSourceMeta` will be added to depayloaded buffers.
    ///
    /// # Returns
    ///
    /// [`true`] if source-info is enabled.
    #[cfg(feature = "v1_16")]
    #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
    #[doc(alias = "gst_rtp_base_depayload_is_source_info_enabled")]
    fn is_source_info_enabled(&self) -> bool {
        unsafe {
            from_glib(ffi::gst_rtp_base_depayload_is_source_info_enabled(
                self.as_ref().to_glib_none().0,
            ))
        }
    }

    /// Push `out_buf` to the peer of `self`. This function takes ownership of
    /// `out_buf`.
    ///
    /// This function will by default apply the last incoming timestamp on
    /// the outgoing buffer when it didn't have a timestamp already.
    /// ## `out_buf`
    /// a [`gst::Buffer`][crate::gst::Buffer]
    ///
    /// # Returns
    ///
    /// a [`gst::FlowReturn`][crate::gst::FlowReturn].
    #[doc(alias = "gst_rtp_base_depayload_push")]
    fn push(&self, out_buf: gst::Buffer) -> Result<gst::FlowSuccess, gst::FlowError> {
        unsafe {
            try_from_glib(ffi::gst_rtp_base_depayload_push(
                self.as_ref().to_glib_none().0,
                out_buf.into_glib_ptr(),
            ))
        }
    }

    /// Push `out_list` to the peer of `self`. This function takes ownership of
    /// `out_list`.
    /// ## `out_list`
    /// a [`gst::BufferList`][crate::gst::BufferList]
    ///
    /// # Returns
    ///
    /// a [`gst::FlowReturn`][crate::gst::FlowReturn].
    #[doc(alias = "gst_rtp_base_depayload_push_list")]
    fn push_list(&self, out_list: gst::BufferList) -> Result<gst::FlowSuccess, gst::FlowError> {
        unsafe {
            try_from_glib(ffi::gst_rtp_base_depayload_push_list(
                self.as_ref().to_glib_none().0,
                out_list.into_glib_ptr(),
            ))
        }
    }

    /// Enable or disable aggregating header extensions.
    /// ## `enable`
    /// whether to aggregate header extensions per output buffer
    #[cfg(feature = "v1_24")]
    #[cfg_attr(docsrs, doc(cfg(feature = "v1_24")))]
    #[doc(alias = "gst_rtp_base_depayload_set_aggregate_hdrext_enabled")]
    fn set_aggregate_hdrext_enabled(&self, enable: bool) {
        unsafe {
            ffi::gst_rtp_base_depayload_set_aggregate_hdrext_enabled(
                self.as_ref().to_glib_none().0,
                enable.into_glib(),
            );
        }
    }

    /// Enable or disable adding `GstRTPSourceMeta` to depayloaded buffers.
    /// ## `enable`
    /// whether to add meta about RTP sources to buffer
    #[cfg(feature = "v1_16")]
    #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
    #[doc(alias = "gst_rtp_base_depayload_set_source_info_enabled")]
    fn set_source_info_enabled(&self, enable: bool) {
        unsafe {
            ffi::gst_rtp_base_depayload_set_source_info_enabled(
                self.as_ref().to_glib_none().0,
                enable.into_glib(),
            );
        }
    }

    /// If enabled, the depayloader will automatically try to enable all the
    /// RTP header extensions provided in the sink caps, saving the application
    /// the need to handle these extensions manually using the
    /// GstRTPBaseDepayload::request-extension: signal.
    #[cfg(feature = "v1_20")]
    #[cfg_attr(docsrs, doc(cfg(feature = "v1_20")))]
    #[doc(alias = "auto-header-extension")]
    fn is_auto_header_extension(&self) -> bool {
        ObjectExt::property(self.as_ref(), "auto-header-extension")
    }

    /// If enabled, the depayloader will automatically try to enable all the
    /// RTP header extensions provided in the sink caps, saving the application
    /// the need to handle these extensions manually using the
    /// GstRTPBaseDepayload::request-extension: signal.
    #[cfg(feature = "v1_20")]
    #[cfg_attr(docsrs, doc(cfg(feature = "v1_20")))]
    #[doc(alias = "auto-header-extension")]
    fn set_auto_header_extension(&self, auto_header_extension: bool) {
        ObjectExt::set_property(
            self.as_ref(),
            "auto-header-extension",
            auto_header_extension,
        )
    }

    /// Max seqnum reorder before the sender is assumed to have restarted.
    ///
    /// When max-reorder is set to 0 all reordered/duplicate packets are
    /// considered coming from a restarted sender.
    #[cfg(feature = "v1_18")]
    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
    #[doc(alias = "max-reorder")]
    fn max_reorder(&self) -> i32 {
        ObjectExt::property(self.as_ref(), "max-reorder")
    }

    /// Max seqnum reorder before the sender is assumed to have restarted.
    ///
    /// When max-reorder is set to 0 all reordered/duplicate packets are
    /// considered coming from a restarted sender.
    #[cfg(feature = "v1_18")]
    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
    #[doc(alias = "max-reorder")]
    fn set_max_reorder(&self, max_reorder: i32) {
        ObjectExt::set_property(self.as_ref(), "max-reorder", max_reorder)
    }

    /// Add RTP source information found in RTP header as meta to output buffer.
    #[cfg(feature = "v1_16")]
    #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
    #[doc(alias = "source-info")]
    fn is_source_info(&self) -> bool {
        ObjectExt::property(self.as_ref(), "source-info")
    }

    /// Add RTP source information found in RTP header as meta to output buffer.
    #[cfg(feature = "v1_16")]
    #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
    #[doc(alias = "source-info")]
    fn set_source_info(&self, source_info: bool) {
        ObjectExt::set_property(self.as_ref(), "source-info", source_info)
    }

    /// Various depayloader statistics retrieved atomically (and are therefore
    /// synchroized with each other). This property return a GstStructure named
    /// application/x-rtp-depayload-stats containing the following fields relating to
    /// the last processed buffer and current state of the stream being depayloaded:
    ///
    ///  * `clock-rate`: `G_TYPE_UINT`, clock-rate of the stream
    ///  * `npt-start`: `G_TYPE_UINT64`, time of playback start
    ///  * `npt-stop`: `G_TYPE_UINT64`, time of playback stop
    ///  * `play-speed`: `G_TYPE_DOUBLE`, the playback speed
    ///  * `play-scale`: `G_TYPE_DOUBLE`, the playback scale
    ///  * `running-time-dts`: `G_TYPE_UINT64`, the last running-time of the
    ///  last DTS
    ///  * `running-time-pts`: `G_TYPE_UINT64`, the last running-time of the
    ///  last PTS
    ///  * `seqnum`: `G_TYPE_UINT`, the last seen seqnum
    ///  * `timestamp`: `G_TYPE_UINT`, the last seen RTP timestamp
    fn stats(&self) -> Option<gst::Structure> {
        ObjectExt::property(self.as_ref(), "stats")
    }

    /// Add `ext` as an extension for reading part of an RTP header extension from
    /// incoming RTP packets.
    /// ## `ext`
    /// the [`RTPHeaderExtension`][crate::RTPHeaderExtension]
    #[cfg(feature = "v1_20")]
    #[cfg_attr(docsrs, doc(cfg(feature = "v1_20")))]
    #[doc(alias = "add-extension")]
    fn connect_add_extension<F: Fn(&Self, &RTPHeaderExtension) + Send + Sync + 'static>(
        &self,
        f: F,
    ) -> SignalHandlerId {
        unsafe extern "C" fn add_extension_trampoline<
            P: IsA<RTPBaseDepayload>,
            F: Fn(&P, &RTPHeaderExtension) + Send + Sync + 'static,
        >(
            this: *mut ffi::GstRTPBaseDepayload,
            ext: *mut ffi::GstRTPHeaderExtension,
            f: glib::ffi::gpointer,
        ) {
            let f: &F = &*(f as *const F);
            f(
                RTPBaseDepayload::from_glib_borrow(this).unsafe_cast_ref(),
                &from_glib_full(ext),
            )
        }
        unsafe {
            let f: Box_<F> = Box_::new(f);
            connect_raw(
                self.as_ptr() as *mut _,
                b"add-extension\0".as_ptr() as *const _,
                Some(std::mem::transmute::<_, unsafe extern "C" fn()>(
                    add_extension_trampoline::<Self, F> as *const (),
                )),
                Box_::into_raw(f),
            )
        }
    }

    #[cfg(feature = "v1_20")]
    #[cfg_attr(docsrs, doc(cfg(feature = "v1_20")))]
    fn emit_add_extension(&self, ext: &RTPHeaderExtension) {
        self.emit_by_name::<()>("add-extension", &[&ext]);
    }

    /// Clear all RTP header extensions used by this depayloader.
    #[cfg(feature = "v1_20")]
    #[cfg_attr(docsrs, doc(cfg(feature = "v1_20")))]
    #[doc(alias = "clear-extensions")]
    fn connect_clear_extensions<F: Fn(&Self) + Send + Sync + 'static>(
        &self,
        f: F,
    ) -> SignalHandlerId {
        unsafe extern "C" fn clear_extensions_trampoline<
            P: IsA<RTPBaseDepayload>,
            F: Fn(&P) + Send + Sync + 'static,
        >(
            this: *mut ffi::GstRTPBaseDepayload,
            f: glib::ffi::gpointer,
        ) {
            let f: &F = &*(f as *const F);
            f(RTPBaseDepayload::from_glib_borrow(this).unsafe_cast_ref())
        }
        unsafe {
            let f: Box_<F> = Box_::new(f);
            connect_raw(
                self.as_ptr() as *mut _,
                b"clear-extensions\0".as_ptr() as *const _,
                Some(std::mem::transmute::<_, unsafe extern "C" fn()>(
                    clear_extensions_trampoline::<Self, F> as *const (),
                )),
                Box_::into_raw(f),
            )
        }
    }

    #[cfg(feature = "v1_20")]
    #[cfg_attr(docsrs, doc(cfg(feature = "v1_20")))]
    fn emit_clear_extensions(&self) {
        self.emit_by_name::<()>("clear-extensions", &[]);
    }

    /// The returned `ext` must be configured with the correct `ext_id` and with the
    /// necessary attributes as required by the extension implementation.
    /// ## `ext_id`
    /// the extension id being requested
    /// ## `ext_uri`
    /// the extension URI being requested
    ///
    /// # Returns
    ///
    /// the [`RTPHeaderExtension`][crate::RTPHeaderExtension] for `ext_id`, or [`None`]
    #[cfg(feature = "v1_20")]
    #[cfg_attr(docsrs, doc(cfg(feature = "v1_20")))]
    #[doc(alias = "request-extension")]
    fn connect_request_extension<
        F: Fn(&Self, u32, Option<&str>) -> Option<RTPHeaderExtension> + Send + Sync + 'static,
    >(
        &self,
        f: F,
    ) -> SignalHandlerId {
        unsafe extern "C" fn request_extension_trampoline<
            P: IsA<RTPBaseDepayload>,
            F: Fn(&P, u32, Option<&str>) -> Option<RTPHeaderExtension> + Send + Sync + 'static,
        >(
            this: *mut ffi::GstRTPBaseDepayload,
            ext_id: libc::c_uint,
            ext_uri: *mut libc::c_char,
            f: glib::ffi::gpointer,
        ) -> *mut ffi::GstRTPHeaderExtension {
            let f: &F = &*(f as *const F);
            f(
                RTPBaseDepayload::from_glib_borrow(this).unsafe_cast_ref(),
                ext_id,
                Option::<glib::GString>::from_glib_borrow(ext_uri)
                    .as_ref()
                    .as_ref()
                    .map(|s| s.as_str()),
            )
            .to_glib_full()
        }
        unsafe {
            let f: Box_<F> = Box_::new(f);
            connect_raw(
                self.as_ptr() as *mut _,
                b"request-extension\0".as_ptr() as *const _,
                Some(std::mem::transmute::<_, unsafe extern "C" fn()>(
                    request_extension_trampoline::<Self, F> as *const (),
                )),
                Box_::into_raw(f),
            )
        }
    }

    #[cfg(feature = "v1_20")]
    #[cfg_attr(docsrs, doc(cfg(feature = "v1_20")))]
    #[doc(alias = "auto-header-extension")]
    fn connect_auto_header_extension_notify<F: Fn(&Self) + Send + Sync + 'static>(
        &self,
        f: F,
    ) -> SignalHandlerId {
        unsafe extern "C" fn notify_auto_header_extension_trampoline<
            P: IsA<RTPBaseDepayload>,
            F: Fn(&P) + Send + Sync + 'static,
        >(
            this: *mut ffi::GstRTPBaseDepayload,
            _param_spec: glib::ffi::gpointer,
            f: glib::ffi::gpointer,
        ) {
            let f: &F = &*(f as *const F);
            f(RTPBaseDepayload::from_glib_borrow(this).unsafe_cast_ref())
        }
        unsafe {
            let f: Box_<F> = Box_::new(f);
            connect_raw(
                self.as_ptr() as *mut _,
                b"notify::auto-header-extension\0".as_ptr() as *const _,
                Some(std::mem::transmute::<_, unsafe extern "C" fn()>(
                    notify_auto_header_extension_trampoline::<Self, F> as *const (),
                )),
                Box_::into_raw(f),
            )
        }
    }

    #[cfg(feature = "v1_18")]
    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
    #[doc(alias = "max-reorder")]
    fn connect_max_reorder_notify<F: Fn(&Self) + Send + Sync + 'static>(
        &self,
        f: F,
    ) -> SignalHandlerId {
        unsafe extern "C" fn notify_max_reorder_trampoline<
            P: IsA<RTPBaseDepayload>,
            F: Fn(&P) + Send + Sync + 'static,
        >(
            this: *mut ffi::GstRTPBaseDepayload,
            _param_spec: glib::ffi::gpointer,
            f: glib::ffi::gpointer,
        ) {
            let f: &F = &*(f as *const F);
            f(RTPBaseDepayload::from_glib_borrow(this).unsafe_cast_ref())
        }
        unsafe {
            let f: Box_<F> = Box_::new(f);
            connect_raw(
                self.as_ptr() as *mut _,
                b"notify::max-reorder\0".as_ptr() as *const _,
                Some(std::mem::transmute::<_, unsafe extern "C" fn()>(
                    notify_max_reorder_trampoline::<Self, F> as *const (),
                )),
                Box_::into_raw(f),
            )
        }
    }

    #[cfg(feature = "v1_16")]
    #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
    #[doc(alias = "source-info")]
    fn connect_source_info_notify<F: Fn(&Self) + Send + Sync + 'static>(
        &self,
        f: F,
    ) -> SignalHandlerId {
        unsafe extern "C" fn notify_source_info_trampoline<
            P: IsA<RTPBaseDepayload>,
            F: Fn(&P) + Send + Sync + 'static,
        >(
            this: *mut ffi::GstRTPBaseDepayload,
            _param_spec: glib::ffi::gpointer,
            f: glib::ffi::gpointer,
        ) {
            let f: &F = &*(f as *const F);
            f(RTPBaseDepayload::from_glib_borrow(this).unsafe_cast_ref())
        }
        unsafe {
            let f: Box_<F> = Box_::new(f);
            connect_raw(
                self.as_ptr() as *mut _,
                b"notify::source-info\0".as_ptr() as *const _,
                Some(std::mem::transmute::<_, unsafe extern "C" fn()>(
                    notify_source_info_trampoline::<Self, F> as *const (),
                )),
                Box_::into_raw(f),
            )
        }
    }

    #[doc(alias = "stats")]
    fn connect_stats_notify<F: Fn(&Self) + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId {
        unsafe extern "C" fn notify_stats_trampoline<
            P: IsA<RTPBaseDepayload>,
            F: Fn(&P) + Send + Sync + 'static,
        >(
            this: *mut ffi::GstRTPBaseDepayload,
            _param_spec: glib::ffi::gpointer,
            f: glib::ffi::gpointer,
        ) {
            let f: &F = &*(f as *const F);
            f(RTPBaseDepayload::from_glib_borrow(this).unsafe_cast_ref())
        }
        unsafe {
            let f: Box_<F> = Box_::new(f);
            connect_raw(
                self.as_ptr() as *mut _,
                b"notify::stats\0".as_ptr() as *const _,
                Some(std::mem::transmute::<_, unsafe extern "C" fn()>(
                    notify_stats_trampoline::<Self, F> as *const (),
                )),
                Box_::into_raw(f),
            )
        }
    }
}

impl<O: IsA<RTPBaseDepayload>> RTPBaseDepayloadExt for O {}