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 {
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 unsafe {
287 let instance = &*(ptr as *mut T::Instance);
288 let imp = instance.imp();
289
290 gst::panic_to_error!(imp, crate::RTPHeaderExtensionFlags::empty(), {
291 imp.supported_flags()
292 })
293 .into_glib()
294 }
295}
296
297unsafe extern "C" fn get_max_size<T: RTPHeaderExtensionImpl>(
298 ptr: *mut ffi::GstRTPHeaderExtension,
299 input: *const gst::ffi::GstBuffer,
300) -> usize {
301 unsafe {
302 let instance = &*(ptr as *mut T::Instance);
303 let imp = instance.imp();
304
305 gst::panic_to_error!(imp, 0, { imp.max_size(gst::BufferRef::from_ptr(input)) })
306 }
307}
308
309unsafe extern "C" fn write<T: RTPHeaderExtensionImpl>(
310 ptr: *mut ffi::GstRTPHeaderExtension,
311 input: *const gst::ffi::GstBuffer,
312 write_flags: ffi::GstRTPHeaderExtensionFlags,
313 output: *mut gst::ffi::GstBuffer,
314 output_data: *mut u8,
315 output_data_len: usize,
316) -> isize {
317 unsafe {
318 let instance = &*(ptr as *mut T::Instance);
319 let imp = instance.imp();
320
321 gst::panic_to_error!(imp, -1, {
322 match imp.write(
323 gst::BufferRef::from_ptr(input),
324 from_glib(write_flags),
325 gst::BufferRef::from_ptr(output),
326 if output_data_len == 0 {
327 &mut []
328 } else {
329 std::slice::from_raw_parts_mut(output_data, output_data_len)
330 },
331 ) {
332 Ok(len) => len as isize,
333 Err(err) => {
334 err.log_with_imp(imp);
335 -1
336 }
337 }
338 })
339 }
340}
341
342unsafe extern "C" fn read<T: RTPHeaderExtensionImpl>(
343 ptr: *mut ffi::GstRTPHeaderExtension,
344 read_flags: ffi::GstRTPHeaderExtensionFlags,
345 input_data: *const u8,
346 input_data_len: usize,
347 output: *mut gst::ffi::GstBuffer,
348) -> glib::ffi::gboolean {
349 unsafe {
350 let instance = &*(ptr as *mut T::Instance);
351 let imp = instance.imp();
352
353 gst::panic_to_error!(imp, false, {
354 match imp.read(
355 from_glib(read_flags),
356 if input_data_len == 0 {
357 &[]
358 } else {
359 std::slice::from_raw_parts(input_data, input_data_len)
360 },
361 gst::BufferRef::from_mut_ptr(output),
362 ) {
363 Ok(_) => true,
364 Err(err) => {
365 err.log_with_imp(imp);
366 false
367 }
368 }
369 })
370 .into_glib()
371 }
372}
373
374unsafe extern "C" fn set_non_rtp_sink_caps<T: RTPHeaderExtensionImpl>(
375 ptr: *mut ffi::GstRTPHeaderExtension,
376 caps: *mut gst::ffi::GstCaps,
377) -> glib::ffi::gboolean {
378 unsafe {
379 let instance = &*(ptr as *mut T::Instance);
380 let imp = instance.imp();
381
382 gst::panic_to_error!(imp, false, {
383 match imp.set_non_rtp_sink_caps(&from_glib_borrow(caps)) {
384 Ok(_) => true,
385 Err(err) => {
386 err.log_with_imp(imp);
387 false
388 }
389 }
390 })
391 .into_glib()
392 }
393}
394
395unsafe extern "C" fn update_non_rtp_src_caps<T: RTPHeaderExtensionImpl>(
396 ptr: *mut ffi::GstRTPHeaderExtension,
397 caps: *mut gst::ffi::GstCaps,
398) -> glib::ffi::gboolean {
399 unsafe {
400 let instance = &*(ptr as *mut T::Instance);
401 let imp = instance.imp();
402
403 gst::panic_to_error!(imp, false, {
404 match imp.update_non_rtp_src_caps(gst::CapsRef::from_mut_ptr(caps)) {
405 Ok(_) => true,
406 Err(err) => {
407 err.log_with_imp(imp);
408 false
409 }
410 }
411 })
412 .into_glib()
413 }
414}
415
416unsafe extern "C" fn set_attributes<T: RTPHeaderExtensionImpl>(
417 ptr: *mut ffi::GstRTPHeaderExtension,
418 direction: ffi::GstRTPHeaderExtensionDirection,
419 attributes: *const libc::c_char,
420) -> glib::ffi::gboolean {
421 unsafe {
422 let instance = &*(ptr as *mut T::Instance);
423 let imp = instance.imp();
424
425 gst::panic_to_error!(imp, false, {
426 match imp.set_attributes(
427 from_glib(direction),
428 &glib::GString::from_glib_borrow(attributes),
429 ) {
430 Ok(_) => true,
431 Err(err) => {
432 err.log_with_imp(imp);
433 false
434 }
435 }
436 })
437 .into_glib()
438 }
439}
440
441unsafe extern "C" fn set_caps_from_attributes<T: RTPHeaderExtensionImpl>(
442 ptr: *mut ffi::GstRTPHeaderExtension,
443 caps: *mut gst::ffi::GstCaps,
444) -> glib::ffi::gboolean {
445 unsafe {
446 let instance = &*(ptr as *mut T::Instance);
447 let imp = instance.imp();
448
449 gst::panic_to_error!(imp, false, {
450 match imp.set_caps_from_attributes(gst::CapsRef::from_mut_ptr(caps)) {
451 Ok(_) => true,
452 Err(err) => {
453 err.log_with_imp(imp);
454 false
455 }
456 }
457 })
458 .into_glib()
459 }
460}