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
use glib::{object::IsA, translate::*};

use crate::{ffi, RTPHeaderExtension, RTPHeaderExtensionFlags};

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

pub trait RTPHeaderExtensionExtManual: sealed::Sealed + IsA<RTPHeaderExtension> + 'static {
    /// Read the RTP header extension from `data`.
    /// ## `read_flags`
    /// [`RTPHeaderExtensionFlags`][crate::RTPHeaderExtensionFlags] for how the extension should
    ///  be written
    /// ## `data`
    /// location to read the rtp header extension from
    /// ## `buffer`
    /// a [`gst::Buffer`][crate::gst::Buffer] to modify if necessary
    ///
    /// # Returns
    ///
    /// whether the extension could be read from `data`
    #[doc(alias = "gst_rtp_header_extension_read")]
    fn read(
        &self,
        read_flags: RTPHeaderExtensionFlags,
        data: &[u8],
        buffer: &mut gst::BufferRef,
    ) -> bool {
        let size = data.len();
        unsafe {
            from_glib(ffi::gst_rtp_header_extension_read(
                self.as_ref().to_glib_none().0,
                read_flags.into_glib(),
                data.to_glib_none().0,
                size,
                buffer.as_mut_ptr(),
            ))
        }
    }

    /// Writes the RTP header extension to `data` using information available from
    /// the `input_meta`. `data` will be sized to be at least the value returned
    /// from [`RTPHeaderExtensionExt::max_size()`][crate::prelude::RTPHeaderExtensionExt::max_size()].
    /// ## `input_meta`
    /// the input [`gst::Buffer`][crate::gst::Buffer] to read information from if necessary
    /// ## `write_flags`
    /// [`RTPHeaderExtensionFlags`][crate::RTPHeaderExtensionFlags] for how the extension should
    ///  be written
    /// ## `output`
    /// output RTP [`gst::Buffer`][crate::gst::Buffer]
    /// ## `data`
    /// location to write the rtp header extension into
    ///
    /// # Returns
    ///
    /// the size of the data written, < 0 on failure
    #[doc(alias = "gst_rtp_header_extension_write")]
    fn write(
        &self,
        input_meta: &gst::Buffer,
        write_flags: RTPHeaderExtensionFlags,
        output: &gst::BufferRef,
        data: &mut [u8],
    ) -> Result<usize, glib::BoolError> {
        let size = data.len();
        unsafe {
            let res = ffi::gst_rtp_header_extension_write(
                self.as_ref().to_glib_none().0,
                input_meta.to_glib_none().0,
                write_flags.into_glib(),
                mut_override(output.as_ptr()),
                data.to_glib_none().0,
                size,
            );

            if res < 0 {
                Err(glib::bool_error!("Failed to write header extension"))
            } else {
                Ok(res as usize)
            }
        }
    }

    /// [`RTPHeaderExtensionExt::set_id()`][crate::prelude::RTPHeaderExtensionExt::set_id()] must have been called with a valid
    /// extension id that is contained in these caps.
    ///
    /// The only current known caps format is based on the SDP standard as produced
    /// by `gst_sdp_media_attributes_to_caps()`.
    /// ## `caps`
    /// writable [`gst::Caps`][crate::gst::Caps] to modify
    ///
    /// # Returns
    ///
    /// whether the configured attributes on `self` can successfully be set on
    ///     `caps`
    #[doc(alias = "gst_rtp_header_extension_set_caps_from_attributes")]
    fn set_caps_from_attributes(&self, caps: &mut gst::CapsRef) -> bool {
        unsafe {
            from_glib(ffi::gst_rtp_header_extension_set_caps_from_attributes(
                self.as_ref().to_glib_none().0,
                caps.as_mut_ptr(),
            ))
        }
    }

    /// Helper implementation for GstRTPExtensionClass::set_caps_from_attributes
    /// that sets the `self` uri on caps with the specified extension id as required
    /// for sdp [`gst::Caps`][crate::gst::Caps].
    ///
    /// Requires that the extension does not have any attributes or direction
    /// advertised in `caps`.
    /// ## `caps`
    /// [`gst::Caps`][crate::gst::Caps] to write fields into
    ///
    /// # Returns
    ///
    /// whether the `self` attributes could be set on `caps`.
    #[doc(alias = "gst_rtp_header_extension_set_caps_from_attributes_helper")]
    fn set_caps_from_attributes_helper(&self, caps: &mut gst::CapsRef, attributes: &str) -> bool {
        unsafe {
            from_glib(
                ffi::gst_rtp_header_extension_set_caps_from_attributes_helper(
                    self.as_ref().to_glib_none().0,
                    caps.as_mut_ptr(),
                    attributes.to_glib_none().0,
                ),
            )
        }
    }

    /// Updates depayloader src caps based on the information received in RTP header.
    /// `caps` must be writable as this function may modify them.
    /// ## `caps`
    /// src [`gst::Caps`][crate::gst::Caps] to modify
    ///
    /// # Returns
    ///
    /// whether `caps` were modified successfully
    #[doc(alias = "gst_rtp_header_extension_update_non_rtp_src_caps")]
    fn update_non_rtp_src_caps(&self, caps: &mut gst::CapsRef) -> bool {
        unsafe {
            from_glib(ffi::gst_rtp_header_extension_update_non_rtp_src_caps(
                self.as_ref().to_glib_none().0,
                caps.as_mut_ptr(),
            ))
        }
    }
}

impl<O: IsA<RTPHeaderExtension>> RTPHeaderExtensionExtManual for O {}