gstreamer_rtp/subclass/
rtp_base_payload.rs1use glib::translate::*;
4use gst::subclass::prelude::*;
5
6use crate::{ffi, prelude::*, RTPBasePayload};
7
8pub trait RTPBasePayloadImpl: RTPBasePayloadImplExt + ElementImpl {
9 fn caps(&self, pad: &gst::Pad, filter: Option<&gst::Caps>) -> gst::Caps {
11 self.parent_caps(pad, filter)
12 }
13
14 fn set_caps(&self, caps: &gst::Caps) -> Result<(), gst::LoggableError> {
16 self.parent_set_caps(caps)
17 }
18
19 fn handle_buffer(&self, buffer: gst::Buffer) -> Result<gst::FlowSuccess, gst::FlowError> {
21 self.parent_handle_buffer(buffer)
22 }
23
24 fn query(&self, pad: &gst::Pad, query: &mut gst::QueryRef) -> bool {
26 RTPBasePayloadImplExt::parent_query(self, pad, query)
27 }
28
29 fn sink_event(&self, event: gst::Event) -> bool {
31 self.parent_sink_event(event)
32 }
33
34 fn src_event(&self, event: gst::Event) -> bool {
36 self.parent_src_event(event)
37 }
38}
39
40mod sealed {
41 pub trait Sealed {}
42 impl<T: super::RTPBasePayloadImplExt> Sealed for T {}
43}
44
45pub trait RTPBasePayloadImplExt: sealed::Sealed + ObjectSubclass {
46 fn parent_caps(&self, pad: &gst::Pad, filter: Option<&gst::Caps>) -> gst::Caps {
47 unsafe {
48 let data = Self::type_data();
49 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPBasePayloadClass;
50 let f = (*parent_class)
51 .get_caps
52 .expect("Missing parent function `get_caps`");
53 from_glib_full(f(
54 self.obj()
55 .unsafe_cast_ref::<RTPBasePayload>()
56 .to_glib_none()
57 .0,
58 pad.to_glib_none().0,
59 filter.to_glib_none().0,
60 ))
61 }
62 }
63
64 fn parent_set_caps(&self, caps: &gst::Caps) -> Result<(), gst::LoggableError> {
65 unsafe {
66 let data = Self::type_data();
67 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPBasePayloadClass;
68 (*parent_class)
69 .set_caps
70 .map(|f| {
71 gst::result_from_gboolean!(
72 f(
73 self.obj()
74 .unsafe_cast_ref::<RTPBasePayload>()
75 .to_glib_none()
76 .0,
77 caps.to_glib_none().0
78 ),
79 gst::CAT_RUST,
80 "Parent function `set_caps` failed"
81 )
82 })
83 .unwrap_or_else(|| {
84 self.obj()
86 .unsafe_cast_ref::<RTPBasePayload>()
87 .set_outcaps(None)
88 .map_err(|_| gst::loggable_error!(gst::CAT_RUST, "Failed to negotiate"))
89 })
90 }
91 }
92
93 fn parent_handle_buffer(
94 &self,
95 buffer: gst::Buffer,
96 ) -> Result<gst::FlowSuccess, gst::FlowError> {
97 unsafe {
98 let data = Self::type_data();
99 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPBasePayloadClass;
100 (*parent_class)
101 .handle_buffer
102 .map(|f| {
103 try_from_glib(f(
104 self.obj()
105 .unsafe_cast_ref::<RTPBasePayload>()
106 .to_glib_none()
107 .0,
108 buffer.into_glib_ptr(),
109 ))
110 })
111 .unwrap_or(Err(gst::FlowError::Error))
112 }
113 }
114
115 fn parent_query(&self, pad: &gst::Pad, query: &mut gst::QueryRef) -> bool {
116 unsafe {
117 let data = Self::type_data();
118 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPBasePayloadClass;
119 (*parent_class)
120 .query
121 .map(|f| {
122 from_glib(f(
123 self.obj()
124 .unsafe_cast_ref::<RTPBasePayload>()
125 .to_glib_none()
126 .0,
127 pad.to_glib_none().0,
128 query.as_mut_ptr(),
129 ))
130 })
131 .unwrap_or(false)
132 }
133 }
134
135 fn parent_sink_event(&self, event: gst::Event) -> bool {
136 unsafe {
137 let data = Self::type_data();
138 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPBasePayloadClass;
139 (*parent_class)
140 .sink_event
141 .map(|f| {
142 from_glib(f(
143 self.obj()
144 .unsafe_cast_ref::<RTPBasePayload>()
145 .to_glib_none()
146 .0,
147 event.into_glib_ptr(),
148 ))
149 })
150 .unwrap_or(false)
151 }
152 }
153
154 fn parent_src_event(&self, event: gst::Event) -> bool {
155 unsafe {
156 let data = Self::type_data();
157 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPBasePayloadClass;
158 (*parent_class)
159 .src_event
160 .map(|f| {
161 from_glib(f(
162 self.obj()
163 .unsafe_cast_ref::<RTPBasePayload>()
164 .to_glib_none()
165 .0,
166 event.into_glib_ptr(),
167 ))
168 })
169 .unwrap_or(false)
170 }
171 }
172}
173
174impl<T: RTPBasePayloadImpl> RTPBasePayloadImplExt for T {}
175
176unsafe impl<T: RTPBasePayloadImpl> IsSubclassable<T> for RTPBasePayload {
177 fn class_init(klass: &mut glib::Class<Self>) {
178 Self::parent_class_init::<T>(klass);
179 let klass = klass.as_mut();
180 klass.get_caps = Some(rtp_base_payload_get_caps::<T>);
181 klass.set_caps = Some(rtp_base_payload_set_caps::<T>);
182 klass.handle_buffer = Some(rtp_base_payload_handle_buffer::<T>);
183 klass.query = Some(rtp_base_payload_query::<T>);
184 klass.sink_event = Some(rtp_base_payload_sink_event::<T>);
185 klass.src_event = Some(rtp_base_payload_src_event::<T>);
186 }
187}
188
189unsafe extern "C" fn rtp_base_payload_get_caps<T: RTPBasePayloadImpl>(
190 ptr: *mut ffi::GstRTPBasePayload,
191 pad: *mut gst::ffi::GstPad,
192 filter: *mut gst::ffi::GstCaps,
193) -> *mut gst::ffi::GstCaps {
194 let instance = &*(ptr as *mut T::Instance);
195 let imp = instance.imp();
196
197 gst::panic_to_error!(imp, gst::Caps::new_empty(), {
198 RTPBasePayloadImpl::caps(
199 imp,
200 &from_glib_borrow(pad),
201 Option::<gst::Caps>::from_glib_borrow(filter)
202 .as_ref()
203 .as_ref(),
204 )
205 })
206 .into_glib_ptr()
207}
208
209unsafe extern "C" fn rtp_base_payload_set_caps<T: RTPBasePayloadImpl>(
210 ptr: *mut ffi::GstRTPBasePayload,
211 caps: *mut gst::ffi::GstCaps,
212) -> glib::ffi::gboolean {
213 let instance = &*(ptr as *mut T::Instance);
214 let imp = instance.imp();
215 let caps = from_glib_borrow(caps);
216
217 gst::panic_to_error!(imp, false, {
218 match imp.set_caps(&caps) {
219 Ok(()) => true,
220 Err(err) => {
221 err.log_with_imp(imp);
222 false
223 }
224 }
225 })
226 .into_glib()
227}
228
229unsafe extern "C" fn rtp_base_payload_handle_buffer<T: RTPBasePayloadImpl>(
230 ptr: *mut ffi::GstRTPBasePayload,
231 buffer: *mut gst::ffi::GstBuffer,
232) -> gst::ffi::GstFlowReturn {
233 let instance = &*(ptr as *mut T::Instance);
234 let imp = instance.imp();
235
236 gst::panic_to_error!(imp, gst::FlowReturn::Error, {
237 imp.handle_buffer(from_glib_full(buffer)).into()
238 })
239 .into_glib()
240}
241
242unsafe extern "C" fn rtp_base_payload_query<T: RTPBasePayloadImpl>(
243 ptr: *mut ffi::GstRTPBasePayload,
244 pad: *mut gst::ffi::GstPad,
245 query: *mut gst::ffi::GstQuery,
246) -> glib::ffi::gboolean {
247 let instance = &*(ptr as *mut T::Instance);
248 let imp = instance.imp();
249
250 gst::panic_to_error!(imp, false, {
251 RTPBasePayloadImpl::query(
252 imp,
253 &from_glib_borrow(pad),
254 gst::QueryRef::from_mut_ptr(query),
255 )
256 })
257 .into_glib()
258}
259
260unsafe extern "C" fn rtp_base_payload_sink_event<T: RTPBasePayloadImpl>(
261 ptr: *mut ffi::GstRTPBasePayload,
262 event: *mut gst::ffi::GstEvent,
263) -> glib::ffi::gboolean {
264 let instance = &*(ptr as *mut T::Instance);
265 let imp = instance.imp();
266
267 gst::panic_to_error!(imp, false, { imp.sink_event(from_glib_full(event)) }).into_glib()
268}
269
270unsafe extern "C" fn rtp_base_payload_src_event<T: RTPBasePayloadImpl>(
271 ptr: *mut ffi::GstRTPBasePayload,
272 event: *mut gst::ffi::GstEvent,
273) -> glib::ffi::gboolean {
274 let instance = &*(ptr as *mut T::Instance);
275 let imp = instance.imp();
276
277 gst::panic_to_error!(imp, false, { imp.src_event(from_glib_full(event)) }).into_glib()
278}