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 {
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 let instance = &*(ptr as *mut T::Instance);
362 let imp = instance.imp();
363
364 gst::panic_to_error!(imp, crate::RTPHeaderExtensionFlags::empty(), {
365 imp.supported_flags()
366 })
367 .into_glib()
368}
369
370unsafe extern "C" fn get_max_size<T: RTPHeaderExtensionImpl>(
371 ptr: *mut ffi::GstRTPHeaderExtension,
372 input: *const gst::ffi::GstBuffer,
373) -> usize {
374 let instance = &*(ptr as *mut T::Instance);
375 let imp = instance.imp();
376
377 gst::panic_to_error!(imp, 0, { imp.max_size(gst::BufferRef::from_ptr(input)) })
378}
379
380unsafe extern "C" fn write<T: RTPHeaderExtensionImpl>(
381 ptr: *mut ffi::GstRTPHeaderExtension,
382 input: *const gst::ffi::GstBuffer,
383 write_flags: ffi::GstRTPHeaderExtensionFlags,
384 output: *mut gst::ffi::GstBuffer,
385 output_data: *mut u8,
386 output_data_len: usize,
387) -> isize {
388 let instance = &*(ptr as *mut T::Instance);
389 let imp = instance.imp();
390
391 gst::panic_to_error!(imp, -1, {
392 match imp.write(
393 gst::BufferRef::from_ptr(input),
394 from_glib(write_flags),
395 gst::BufferRef::from_ptr(output),
396 if output_data_len == 0 {
397 &mut []
398 } else {
399 std::slice::from_raw_parts_mut(output_data, output_data_len)
400 },
401 ) {
402 Ok(len) => len as isize,
403 Err(err) => {
404 err.log_with_imp(imp);
405 -1
406 }
407 }
408 })
409}
410
411unsafe extern "C" fn read<T: RTPHeaderExtensionImpl>(
412 ptr: *mut ffi::GstRTPHeaderExtension,
413 read_flags: ffi::GstRTPHeaderExtensionFlags,
414 input_data: *const u8,
415 input_data_len: usize,
416 output: *mut gst::ffi::GstBuffer,
417) -> glib::ffi::gboolean {
418 let instance = &*(ptr as *mut T::Instance);
419 let imp = instance.imp();
420
421 gst::panic_to_error!(imp, false, {
422 match imp.read(
423 from_glib(read_flags),
424 if input_data_len == 0 {
425 &[]
426 } else {
427 std::slice::from_raw_parts(input_data, input_data_len)
428 },
429 gst::BufferRef::from_mut_ptr(output),
430 ) {
431 Ok(_) => true,
432 Err(err) => {
433 err.log_with_imp(imp);
434 false
435 }
436 }
437 })
438 .into_glib()
439}
440
441unsafe extern "C" fn set_non_rtp_sink_caps<T: RTPHeaderExtensionImpl>(
442 ptr: *mut ffi::GstRTPHeaderExtension,
443 caps: *mut gst::ffi::GstCaps,
444) -> glib::ffi::gboolean {
445 let instance = &*(ptr as *mut T::Instance);
446 let imp = instance.imp();
447
448 gst::panic_to_error!(imp, false, {
449 match imp.set_non_rtp_sink_caps(&from_glib_borrow(caps)) {
450 Ok(_) => true,
451 Err(err) => {
452 err.log_with_imp(imp);
453 false
454 }
455 }
456 })
457 .into_glib()
458}
459
460unsafe extern "C" fn update_non_rtp_src_caps<T: RTPHeaderExtensionImpl>(
461 ptr: *mut ffi::GstRTPHeaderExtension,
462 caps: *mut gst::ffi::GstCaps,
463) -> glib::ffi::gboolean {
464 let instance = &*(ptr as *mut T::Instance);
465 let imp = instance.imp();
466
467 gst::panic_to_error!(imp, false, {
468 match imp.update_non_rtp_src_caps(gst::CapsRef::from_mut_ptr(caps)) {
469 Ok(_) => true,
470 Err(err) => {
471 err.log_with_imp(imp);
472 false
473 }
474 }
475 })
476 .into_glib()
477}
478
479unsafe extern "C" fn set_attributes<T: RTPHeaderExtensionImpl>(
480 ptr: *mut ffi::GstRTPHeaderExtension,
481 direction: ffi::GstRTPHeaderExtensionDirection,
482 attributes: *const libc::c_char,
483) -> glib::ffi::gboolean {
484 let instance = &*(ptr as *mut T::Instance);
485 let imp = instance.imp();
486
487 gst::panic_to_error!(imp, false, {
488 match imp.set_attributes(
489 from_glib(direction),
490 &glib::GString::from_glib_borrow(attributes),
491 ) {
492 Ok(_) => true,
493 Err(err) => {
494 err.log_with_imp(imp);
495 false
496 }
497 }
498 })
499 .into_glib()
500}
501
502unsafe extern "C" fn set_caps_from_attributes<T: RTPHeaderExtensionImpl>(
503 ptr: *mut ffi::GstRTPHeaderExtension,
504 caps: *mut gst::ffi::GstCaps,
505) -> glib::ffi::gboolean {
506 let instance = &*(ptr as *mut T::Instance);
507 let imp = instance.imp();
508
509 gst::panic_to_error!(imp, false, {
510 match imp.set_caps_from_attributes(gst::CapsRef::from_mut_ptr(caps)) {
511 Ok(_) => true,
512 Err(err) => {
513 err.log_with_imp(imp);
514 false
515 }
516 }
517 })
518 .into_glib()
519}