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