1use glib::{prelude::*, subclass::prelude::*, translate::*};
4
5use super::prelude::*;
6use crate::ffi;
7use crate::RTPHeaderExtension;
8
9pub trait RTPHeaderExtensionImpl:
10 ElementImpl + ObjectSubclass<Type: IsA<RTPHeaderExtension>>
11{
12 const URI: &'static str;
13
14 fn supported_flags(&self) -> crate::RTPHeaderExtensionFlags {
15 self.parent_supported_flags()
16 }
17
18 fn max_size(&self, input: &gst::BufferRef) -> usize {
19 self.parent_max_size(input)
20 }
21
22 fn write(
23 &self,
24 input: &gst::BufferRef,
25 write_flags: crate::RTPHeaderExtensionFlags,
26 output: &gst::BufferRef,
27 output_data: &mut [u8],
28 ) -> Result<usize, gst::LoggableError> {
29 self.parent_write(input, write_flags, output, output_data)
30 }
31
32 fn read(
33 &self,
34 read_flags: crate::RTPHeaderExtensionFlags,
35 input_data: &[u8],
36 output: &mut gst::BufferRef,
37 ) -> Result<(), gst::LoggableError> {
38 self.parent_read(read_flags, input_data, output)
39 }
40
41 fn set_non_rtp_sink_caps(&self, caps: &gst::Caps) -> Result<(), gst::LoggableError> {
42 self.parent_set_non_rtp_sink_caps(caps)
43 }
44
45 fn update_non_rtp_src_caps(&self, caps: &mut gst::CapsRef) -> Result<(), gst::LoggableError> {
46 self.parent_update_non_rtp_src_caps(caps)
47 }
48
49 fn set_attributes(
50 &self,
51 direction: crate::RTPHeaderExtensionDirection,
52 attributes: &str,
53 ) -> Result<(), gst::LoggableError> {
54 self.parent_set_attributes(direction, attributes)
55 }
56
57 fn set_caps_from_attributes(&self, caps: &mut gst::CapsRef) -> Result<(), gst::LoggableError> {
58 self.parent_set_caps_from_attributes(caps)
59 }
60}
61
62pub trait RTPHeaderExtensionImplExt: RTPHeaderExtensionImpl {
63 fn parent_supported_flags(&self) -> crate::RTPHeaderExtensionFlags {
64 unsafe {
65 let data = Self::type_data();
66 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPHeaderExtensionClass;
67 let f = (*parent_class)
68 .get_supported_flags
69 .expect("no parent \"get_supported_flags\" implementation");
70 from_glib(f(self
71 .obj()
72 .unsafe_cast_ref::<RTPHeaderExtension>()
73 .to_glib_none()
74 .0))
75 }
76 }
77
78 fn parent_max_size(&self, input: &gst::BufferRef) -> usize {
79 unsafe {
80 let data = Self::type_data();
81 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPHeaderExtensionClass;
82 let f = (*parent_class)
83 .get_max_size
84 .expect("no parent \"get_max_size\" implementation");
85 f(
86 self.obj()
87 .unsafe_cast_ref::<RTPHeaderExtension>()
88 .to_glib_none()
89 .0,
90 input.as_ptr(),
91 )
92 }
93 }
94
95 fn parent_write(
96 &self,
97 input: &gst::BufferRef,
98 write_flags: crate::RTPHeaderExtensionFlags,
99 output: &gst::BufferRef,
100 output_data: &mut [u8],
101 ) -> Result<usize, gst::LoggableError> {
102 unsafe {
103 let data = Self::type_data();
104 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPHeaderExtensionClass;
105 let f = (*parent_class)
106 .write
107 .expect("no parent \"write\" implementation");
108
109 let res = f(
110 self.obj()
111 .unsafe_cast_ref::<RTPHeaderExtension>()
112 .to_glib_none()
113 .0,
114 input.as_ptr(),
115 write_flags.into_glib(),
116 mut_override(output.as_ptr()),
117 output_data.as_mut_ptr(),
118 output_data.len(),
119 );
120
121 if res < 0 {
122 Err(gst::loggable_error!(
123 gst::CAT_RUST,
124 "Failed to write extension data"
125 ))
126 } else {
127 Ok(res as usize)
128 }
129 }
130 }
131
132 fn parent_read(
133 &self,
134 read_flags: crate::RTPHeaderExtensionFlags,
135 input_data: &[u8],
136 output: &mut gst::BufferRef,
137 ) -> Result<(), gst::LoggableError> {
138 unsafe {
139 let data = Self::type_data();
140 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPHeaderExtensionClass;
141 let f = (*parent_class)
142 .read
143 .expect("no parent \"read\" implementation");
144
145 gst::result_from_gboolean!(
146 f(
147 self.obj()
148 .unsafe_cast_ref::<RTPHeaderExtension>()
149 .to_glib_none()
150 .0,
151 read_flags.into_glib(),
152 input_data.as_ptr(),
153 input_data.len(),
154 output.as_mut_ptr(),
155 ),
156 gst::CAT_RUST,
157 "Failed to read extension data",
158 )
159 }
160 }
161
162 fn parent_set_non_rtp_sink_caps(&self, caps: &gst::Caps) -> Result<(), gst::LoggableError> {
163 unsafe {
164 let data = Self::type_data();
165 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPHeaderExtensionClass;
166 if let Some(f) = (*parent_class).set_non_rtp_sink_caps {
167 gst::result_from_gboolean!(
168 f(
169 self.obj()
170 .unsafe_cast_ref::<RTPHeaderExtension>()
171 .to_glib_none()
172 .0,
173 caps.as_mut_ptr(),
174 ),
175 gst::CAT_RUST,
176 "Failed to set non-RTP sink caps",
177 )
178 } else {
179 Ok(())
180 }
181 }
182 }
183
184 fn parent_update_non_rtp_src_caps(
185 &self,
186 caps: &mut gst::CapsRef,
187 ) -> Result<(), gst::LoggableError> {
188 unsafe {
189 let data = Self::type_data();
190 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPHeaderExtensionClass;
191 if let Some(f) = (*parent_class).update_non_rtp_src_caps {
192 gst::result_from_gboolean!(
193 f(
194 self.obj()
195 .unsafe_cast_ref::<RTPHeaderExtension>()
196 .to_glib_none()
197 .0,
198 caps.as_mut_ptr(),
199 ),
200 gst::CAT_RUST,
201 "Failed to update non-RTP source caps",
202 )
203 } else {
204 Ok(())
205 }
206 }
207 }
208
209 fn parent_set_attributes(
210 &self,
211 direction: crate::RTPHeaderExtensionDirection,
212 attributes: &str,
213 ) -> Result<(), gst::LoggableError> {
214 unsafe {
215 let data = Self::type_data();
216 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPHeaderExtensionClass;
217 if let Some(f) = (*parent_class).set_attributes {
218 gst::result_from_gboolean!(
219 f(
220 self.obj()
221 .unsafe_cast_ref::<RTPHeaderExtension>()
222 .to_glib_none()
223 .0,
224 direction.into_glib(),
225 attributes.to_glib_none().0,
226 ),
227 gst::CAT_RUST,
228 "Failed to set attributes",
229 )
230 } else {
231 Ok(())
232 }
233 }
234 }
235
236 fn parent_set_caps_from_attributes(
237 &self,
238 caps: &mut gst::CapsRef,
239 ) -> Result<(), gst::LoggableError> {
240 unsafe {
241 let data = Self::type_data();
242 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPHeaderExtensionClass;
243 let f = (*parent_class)
244 .set_caps_from_attributes
245 .expect("no parent \"set_caps_from_attributes\" implementation");
246
247 gst::result_from_gboolean!(
248 f(
249 self.obj()
250 .unsafe_cast_ref::<RTPHeaderExtension>()
251 .to_glib_none()
252 .0,
253 caps.as_mut_ptr(),
254 ),
255 gst::CAT_RUST,
256 "Failed to set caps from attributes",
257 )
258 }
259 }
260}
261
262impl<T: RTPHeaderExtensionImpl> RTPHeaderExtensionImplExt for T {}
263
264unsafe impl<T: RTPHeaderExtensionImpl> IsSubclassable<T> for RTPHeaderExtension {
265 fn class_init(klass: &mut glib::Class<Self>) {
266 Self::parent_class_init::<T>(klass);
267 let klass = klass.as_mut();
268 klass.get_supported_flags = Some(get_supported_flags::<T>);
269 klass.get_max_size = Some(get_max_size::<T>);
270 klass.write = Some(write::<T>);
271 klass.read = Some(read::<T>);
272 klass.set_non_rtp_sink_caps = Some(set_non_rtp_sink_caps::<T>);
273 klass.update_non_rtp_src_caps = Some(update_non_rtp_src_caps::<T>);
274 klass.set_attributes = Some(set_attributes::<T>);
275 klass.set_caps_from_attributes = Some(set_caps_from_attributes::<T>);
276
277 unsafe {
278 ffi::gst_rtp_header_extension_class_set_uri(&mut *klass, T::URI.to_glib_none().0);
279 }
280 }
281}
282
283unsafe extern "C" fn get_supported_flags<T: RTPHeaderExtensionImpl>(
284 ptr: *mut ffi::GstRTPHeaderExtension,
285) -> ffi::GstRTPHeaderExtensionFlags {
286 let instance = &*(ptr as *mut T::Instance);
287 let imp = instance.imp();
288
289 gst::panic_to_error!(imp, crate::RTPHeaderExtensionFlags::empty(), {
290 imp.supported_flags()
291 })
292 .into_glib()
293}
294
295unsafe extern "C" fn get_max_size<T: RTPHeaderExtensionImpl>(
296 ptr: *mut ffi::GstRTPHeaderExtension,
297 input: *const gst::ffi::GstBuffer,
298) -> usize {
299 let instance = &*(ptr as *mut T::Instance);
300 let imp = instance.imp();
301
302 gst::panic_to_error!(imp, 0, { imp.max_size(gst::BufferRef::from_ptr(input)) })
303}
304
305unsafe extern "C" fn write<T: RTPHeaderExtensionImpl>(
306 ptr: *mut ffi::GstRTPHeaderExtension,
307 input: *const gst::ffi::GstBuffer,
308 write_flags: ffi::GstRTPHeaderExtensionFlags,
309 output: *mut gst::ffi::GstBuffer,
310 output_data: *mut u8,
311 output_data_len: usize,
312) -> isize {
313 let instance = &*(ptr as *mut T::Instance);
314 let imp = instance.imp();
315
316 gst::panic_to_error!(imp, -1, {
317 match imp.write(
318 gst::BufferRef::from_ptr(input),
319 from_glib(write_flags),
320 gst::BufferRef::from_ptr(output),
321 if output_data_len == 0 {
322 &mut []
323 } else {
324 std::slice::from_raw_parts_mut(output_data, output_data_len)
325 },
326 ) {
327 Ok(len) => len as isize,
328 Err(err) => {
329 err.log_with_imp(imp);
330 -1
331 }
332 }
333 })
334}
335
336unsafe extern "C" fn read<T: RTPHeaderExtensionImpl>(
337 ptr: *mut ffi::GstRTPHeaderExtension,
338 read_flags: ffi::GstRTPHeaderExtensionFlags,
339 input_data: *const u8,
340 input_data_len: usize,
341 output: *mut gst::ffi::GstBuffer,
342) -> glib::ffi::gboolean {
343 let instance = &*(ptr as *mut T::Instance);
344 let imp = instance.imp();
345
346 gst::panic_to_error!(imp, false, {
347 match imp.read(
348 from_glib(read_flags),
349 if input_data_len == 0 {
350 &[]
351 } else {
352 std::slice::from_raw_parts(input_data, input_data_len)
353 },
354 gst::BufferRef::from_mut_ptr(output),
355 ) {
356 Ok(_) => true,
357 Err(err) => {
358 err.log_with_imp(imp);
359 false
360 }
361 }
362 })
363 .into_glib()
364}
365
366unsafe extern "C" fn set_non_rtp_sink_caps<T: RTPHeaderExtensionImpl>(
367 ptr: *mut ffi::GstRTPHeaderExtension,
368 caps: *mut gst::ffi::GstCaps,
369) -> glib::ffi::gboolean {
370 let instance = &*(ptr as *mut T::Instance);
371 let imp = instance.imp();
372
373 gst::panic_to_error!(imp, false, {
374 match imp.set_non_rtp_sink_caps(&from_glib_borrow(caps)) {
375 Ok(_) => true,
376 Err(err) => {
377 err.log_with_imp(imp);
378 false
379 }
380 }
381 })
382 .into_glib()
383}
384
385unsafe extern "C" fn update_non_rtp_src_caps<T: RTPHeaderExtensionImpl>(
386 ptr: *mut ffi::GstRTPHeaderExtension,
387 caps: *mut gst::ffi::GstCaps,
388) -> glib::ffi::gboolean {
389 let instance = &*(ptr as *mut T::Instance);
390 let imp = instance.imp();
391
392 gst::panic_to_error!(imp, false, {
393 match imp.update_non_rtp_src_caps(gst::CapsRef::from_mut_ptr(caps)) {
394 Ok(_) => true,
395 Err(err) => {
396 err.log_with_imp(imp);
397 false
398 }
399 }
400 })
401 .into_glib()
402}
403
404unsafe extern "C" fn set_attributes<T: RTPHeaderExtensionImpl>(
405 ptr: *mut ffi::GstRTPHeaderExtension,
406 direction: ffi::GstRTPHeaderExtensionDirection,
407 attributes: *const libc::c_char,
408) -> glib::ffi::gboolean {
409 let instance = &*(ptr as *mut T::Instance);
410 let imp = instance.imp();
411
412 gst::panic_to_error!(imp, false, {
413 match imp.set_attributes(
414 from_glib(direction),
415 &glib::GString::from_glib_borrow(attributes),
416 ) {
417 Ok(_) => true,
418 Err(err) => {
419 err.log_with_imp(imp);
420 false
421 }
422 }
423 })
424 .into_glib()
425}
426
427unsafe extern "C" fn set_caps_from_attributes<T: RTPHeaderExtensionImpl>(
428 ptr: *mut ffi::GstRTPHeaderExtension,
429 caps: *mut gst::ffi::GstCaps,
430) -> glib::ffi::gboolean {
431 let instance = &*(ptr as *mut T::Instance);
432 let imp = instance.imp();
433
434 gst::panic_to_error!(imp, false, {
435 match imp.set_caps_from_attributes(gst::CapsRef::from_mut_ptr(caps)) {
436 Ok(_) => true,
437 Err(err) => {
438 err.log_with_imp(imp);
439 false
440 }
441 }
442 })
443 .into_glib()
444}