1use glib::{prelude::*, subclass::prelude::*, translate::*};
4
5use super::prelude::*;
6use crate::ffi;
7
8pub trait RTPHeaderExtensionImpl: RTPHeaderExtensionImplExt + ElementImpl {
9 const URI: &'static str;
10
11 fn supported_flags(&self) -> crate::RTPHeaderExtensionFlags {
17 self.parent_supported_flags()
18 }
19
20 fn max_size(&self, input: &gst::BufferRef) -> usize {
33 self.parent_max_size(input)
34 }
35
36 fn write(
53 &self,
54 input: &gst::BufferRef,
55 write_flags: crate::RTPHeaderExtensionFlags,
56 output: &gst::BufferRef,
57 output_data: &mut [u8],
58 ) -> Result<usize, gst::LoggableError> {
59 self.parent_write(input, write_flags, output, output_data)
60 }
61
62 fn read(
75 &self,
76 read_flags: crate::RTPHeaderExtensionFlags,
77 input_data: &[u8],
78 output: &mut gst::BufferRef,
79 ) -> Result<(), gst::LoggableError> {
80 self.parent_read(read_flags, input_data, output)
81 }
82
83 fn set_non_rtp_sink_caps(&self, caps: &gst::Caps) -> Result<(), gst::LoggableError> {
92 self.parent_set_non_rtp_sink_caps(caps)
93 }
94
95 fn update_non_rtp_src_caps(&self, caps: &mut gst::CapsRef) -> Result<(), gst::LoggableError> {
104 self.parent_update_non_rtp_src_caps(caps)
105 }
106
107 fn set_attributes(
110 &self,
111 direction: crate::RTPHeaderExtensionDirection,
112 attributes: &str,
113 ) -> Result<(), gst::LoggableError> {
114 self.parent_set_attributes(direction, attributes)
115 }
116
117 fn set_caps_from_attributes(&self, caps: &mut gst::CapsRef) -> Result<(), gst::LoggableError> {
130 self.parent_set_caps_from_attributes(caps)
131 }
132}
133
134mod sealed {
135 pub trait Sealed {}
136 impl<T: super::RTPHeaderExtensionImplExt> Sealed for T {}
137}
138
139pub trait RTPHeaderExtensionImplExt: sealed::Sealed + ObjectSubclass {
140 fn parent_supported_flags(&self) -> crate::RTPHeaderExtensionFlags {
141 unsafe {
142 let data = Self::type_data();
143 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPHeaderExtensionClass;
144 let f = (*parent_class)
145 .get_supported_flags
146 .expect("no parent \"get_supported_flags\" implementation");
147 from_glib(f(self
148 .obj()
149 .unsafe_cast_ref::<crate::RTPHeaderExtension>()
150 .to_glib_none()
151 .0))
152 }
153 }
154
155 fn parent_max_size(&self, input: &gst::BufferRef) -> usize {
156 unsafe {
157 let data = Self::type_data();
158 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPHeaderExtensionClass;
159 let f = (*parent_class)
160 .get_max_size
161 .expect("no parent \"get_max_size\" implementation");
162 f(
163 self.obj()
164 .unsafe_cast_ref::<crate::RTPHeaderExtension>()
165 .to_glib_none()
166 .0,
167 input.as_ptr(),
168 )
169 }
170 }
171
172 fn parent_write(
173 &self,
174 input: &gst::BufferRef,
175 write_flags: crate::RTPHeaderExtensionFlags,
176 output: &gst::BufferRef,
177 output_data: &mut [u8],
178 ) -> Result<usize, gst::LoggableError> {
179 unsafe {
180 let data = Self::type_data();
181 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPHeaderExtensionClass;
182 let f = (*parent_class)
183 .write
184 .expect("no parent \"write\" implementation");
185
186 let res = f(
187 self.obj()
188 .unsafe_cast_ref::<crate::RTPHeaderExtension>()
189 .to_glib_none()
190 .0,
191 input.as_ptr(),
192 write_flags.into_glib(),
193 mut_override(output.as_ptr()),
194 output_data.as_mut_ptr(),
195 output_data.len(),
196 );
197
198 if res < 0 {
199 Err(gst::loggable_error!(
200 gst::CAT_RUST,
201 "Failed to write extension data"
202 ))
203 } else {
204 Ok(res as usize)
205 }
206 }
207 }
208
209 fn parent_read(
210 &self,
211 read_flags: crate::RTPHeaderExtensionFlags,
212 input_data: &[u8],
213 output: &mut gst::BufferRef,
214 ) -> Result<(), gst::LoggableError> {
215 unsafe {
216 let data = Self::type_data();
217 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPHeaderExtensionClass;
218 let f = (*parent_class)
219 .read
220 .expect("no parent \"read\" implementation");
221
222 gst::result_from_gboolean!(
223 f(
224 self.obj()
225 .unsafe_cast_ref::<crate::RTPHeaderExtension>()
226 .to_glib_none()
227 .0,
228 read_flags.into_glib(),
229 input_data.as_ptr(),
230 input_data.len(),
231 output.as_mut_ptr(),
232 ),
233 gst::CAT_RUST,
234 "Failed to read extension data",
235 )
236 }
237 }
238
239 fn parent_set_non_rtp_sink_caps(&self, caps: &gst::Caps) -> 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 if let Some(f) = (*parent_class).set_non_rtp_sink_caps {
244 gst::result_from_gboolean!(
245 f(
246 self.obj()
247 .unsafe_cast_ref::<crate::RTPHeaderExtension>()
248 .to_glib_none()
249 .0,
250 caps.as_mut_ptr(),
251 ),
252 gst::CAT_RUST,
253 "Failed to set non-RTP sink caps",
254 )
255 } else {
256 Ok(())
257 }
258 }
259 }
260
261 fn parent_update_non_rtp_src_caps(
262 &self,
263 caps: &mut gst::CapsRef,
264 ) -> Result<(), gst::LoggableError> {
265 unsafe {
266 let data = Self::type_data();
267 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPHeaderExtensionClass;
268 if let Some(f) = (*parent_class).update_non_rtp_src_caps {
269 gst::result_from_gboolean!(
270 f(
271 self.obj()
272 .unsafe_cast_ref::<crate::RTPHeaderExtension>()
273 .to_glib_none()
274 .0,
275 caps.as_mut_ptr(),
276 ),
277 gst::CAT_RUST,
278 "Failed to update non-RTP source caps",
279 )
280 } else {
281 Ok(())
282 }
283 }
284 }
285
286 fn parent_set_attributes(
287 &self,
288 direction: crate::RTPHeaderExtensionDirection,
289 attributes: &str,
290 ) -> Result<(), gst::LoggableError> {
291 unsafe {
292 let data = Self::type_data();
293 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPHeaderExtensionClass;
294 if let Some(f) = (*parent_class).set_attributes {
295 gst::result_from_gboolean!(
296 f(
297 self.obj()
298 .unsafe_cast_ref::<crate::RTPHeaderExtension>()
299 .to_glib_none()
300 .0,
301 direction.into_glib(),
302 attributes.to_glib_none().0,
303 ),
304 gst::CAT_RUST,
305 "Failed to set attributes",
306 )
307 } else {
308 Ok(())
309 }
310 }
311 }
312
313 fn parent_set_caps_from_attributes(
314 &self,
315 caps: &mut gst::CapsRef,
316 ) -> Result<(), gst::LoggableError> {
317 unsafe {
318 let data = Self::type_data();
319 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPHeaderExtensionClass;
320 let f = (*parent_class)
321 .set_caps_from_attributes
322 .expect("no parent \"set_caps_from_attributes\" implementation");
323
324 gst::result_from_gboolean!(
325 f(
326 self.obj()
327 .unsafe_cast_ref::<crate::RTPHeaderExtension>()
328 .to_glib_none()
329 .0,
330 caps.as_mut_ptr(),
331 ),
332 gst::CAT_RUST,
333 "Failed to set caps from attributes",
334 )
335 }
336 }
337}
338
339impl<T: RTPHeaderExtensionImpl> RTPHeaderExtensionImplExt for T {}
340
341unsafe impl<T: RTPHeaderExtensionImpl> IsSubclassable<T> for crate::RTPHeaderExtension {
342 fn class_init(klass: &mut glib::Class<Self>) {
343 Self::parent_class_init::<T>(klass);
344 let klass = klass.as_mut();
345 klass.get_supported_flags = Some(get_supported_flags::<T>);
346 klass.get_max_size = Some(get_max_size::<T>);
347 klass.write = Some(write::<T>);
348 klass.read = Some(read::<T>);
349 klass.set_non_rtp_sink_caps = Some(set_non_rtp_sink_caps::<T>);
350 klass.update_non_rtp_src_caps = Some(update_non_rtp_src_caps::<T>);
351 klass.set_attributes = Some(set_attributes::<T>);
352 klass.set_caps_from_attributes = Some(set_caps_from_attributes::<T>);
353
354 unsafe {
355 ffi::gst_rtp_header_extension_class_set_uri(&mut *klass, T::URI.to_glib_none().0);
356 }
357 }
358}
359
360unsafe extern "C" fn get_supported_flags<T: RTPHeaderExtensionImpl>(
361 ptr: *mut ffi::GstRTPHeaderExtension,
362) -> ffi::GstRTPHeaderExtensionFlags {
363 let instance = &*(ptr as *mut T::Instance);
364 let imp = instance.imp();
365
366 gst::panic_to_error!(imp, crate::RTPHeaderExtensionFlags::empty(), {
367 imp.supported_flags()
368 })
369 .into_glib()
370}
371
372unsafe extern "C" fn get_max_size<T: RTPHeaderExtensionImpl>(
373 ptr: *mut ffi::GstRTPHeaderExtension,
374 input: *const gst::ffi::GstBuffer,
375) -> usize {
376 let instance = &*(ptr as *mut T::Instance);
377 let imp = instance.imp();
378
379 gst::panic_to_error!(imp, 0, { imp.max_size(gst::BufferRef::from_ptr(input)) })
380}
381
382unsafe extern "C" fn write<T: RTPHeaderExtensionImpl>(
383 ptr: *mut ffi::GstRTPHeaderExtension,
384 input: *const gst::ffi::GstBuffer,
385 write_flags: ffi::GstRTPHeaderExtensionFlags,
386 output: *mut gst::ffi::GstBuffer,
387 output_data: *mut u8,
388 output_data_len: usize,
389) -> isize {
390 let instance = &*(ptr as *mut T::Instance);
391 let imp = instance.imp();
392
393 gst::panic_to_error!(imp, -1, {
394 match imp.write(
395 gst::BufferRef::from_ptr(input),
396 from_glib(write_flags),
397 gst::BufferRef::from_ptr(output),
398 if output_data_len == 0 {
399 &mut []
400 } else {
401 std::slice::from_raw_parts_mut(output_data, output_data_len)
402 },
403 ) {
404 Ok(len) => len as isize,
405 Err(err) => {
406 err.log_with_imp(imp);
407 -1
408 }
409 }
410 })
411}
412
413unsafe extern "C" fn read<T: RTPHeaderExtensionImpl>(
414 ptr: *mut ffi::GstRTPHeaderExtension,
415 read_flags: ffi::GstRTPHeaderExtensionFlags,
416 input_data: *const u8,
417 input_data_len: usize,
418 output: *mut gst::ffi::GstBuffer,
419) -> glib::ffi::gboolean {
420 let instance = &*(ptr as *mut T::Instance);
421 let imp = instance.imp();
422
423 gst::panic_to_error!(imp, false, {
424 match imp.read(
425 from_glib(read_flags),
426 if input_data_len == 0 {
427 &[]
428 } else {
429 std::slice::from_raw_parts(input_data, input_data_len)
430 },
431 gst::BufferRef::from_mut_ptr(output),
432 ) {
433 Ok(_) => true,
434 Err(err) => {
435 err.log_with_imp(imp);
436 false
437 }
438 }
439 })
440 .into_glib()
441}
442
443unsafe extern "C" fn set_non_rtp_sink_caps<T: RTPHeaderExtensionImpl>(
444 ptr: *mut ffi::GstRTPHeaderExtension,
445 caps: *mut gst::ffi::GstCaps,
446) -> glib::ffi::gboolean {
447 let instance = &*(ptr as *mut T::Instance);
448 let imp = instance.imp();
449
450 gst::panic_to_error!(imp, false, {
451 match imp.set_non_rtp_sink_caps(&from_glib_borrow(caps)) {
452 Ok(_) => true,
453 Err(err) => {
454 err.log_with_imp(imp);
455 false
456 }
457 }
458 })
459 .into_glib()
460}
461
462unsafe extern "C" fn update_non_rtp_src_caps<T: RTPHeaderExtensionImpl>(
463 ptr: *mut ffi::GstRTPHeaderExtension,
464 caps: *mut gst::ffi::GstCaps,
465) -> glib::ffi::gboolean {
466 let instance = &*(ptr as *mut T::Instance);
467 let imp = instance.imp();
468
469 gst::panic_to_error!(imp, false, {
470 match imp.update_non_rtp_src_caps(gst::CapsRef::from_mut_ptr(caps)) {
471 Ok(_) => true,
472 Err(err) => {
473 err.log_with_imp(imp);
474 false
475 }
476 }
477 })
478 .into_glib()
479}
480
481unsafe extern "C" fn set_attributes<T: RTPHeaderExtensionImpl>(
482 ptr: *mut ffi::GstRTPHeaderExtension,
483 direction: ffi::GstRTPHeaderExtensionDirection,
484 attributes: *const libc::c_char,
485) -> glib::ffi::gboolean {
486 let instance = &*(ptr as *mut T::Instance);
487 let imp = instance.imp();
488
489 gst::panic_to_error!(imp, false, {
490 match imp.set_attributes(
491 from_glib(direction),
492 &glib::GString::from_glib_borrow(attributes),
493 ) {
494 Ok(_) => true,
495 Err(err) => {
496 err.log_with_imp(imp);
497 false
498 }
499 }
500 })
501 .into_glib()
502}
503
504unsafe extern "C" fn set_caps_from_attributes<T: RTPHeaderExtensionImpl>(
505 ptr: *mut ffi::GstRTPHeaderExtension,
506 caps: *mut gst::ffi::GstCaps,
507) -> glib::ffi::gboolean {
508 let instance = &*(ptr as *mut T::Instance);
509 let imp = instance.imp();
510
511 gst::panic_to_error!(imp, false, {
512 match imp.set_caps_from_attributes(gst::CapsRef::from_mut_ptr(caps)) {
513 Ok(_) => true,
514 Err(err) => {
515 err.log_with_imp(imp);
516 false
517 }
518 }
519 })
520 .into_glib()
521}