1use std::{fmt, marker::PhantomData, mem, ptr, slice};
4
5use crate::ffi;
6use glib::translate::{FromGlibPtrFull, IntoGlib, from_glib, mut_override};
7
8pub enum Readable {}
9pub enum Writable {}
10
11pub struct RTPBuffer<'a, T> {
12 rtp_buffer: ffi::GstRTPBuffer,
13 phantom: PhantomData<&'a T>,
14}
15
16unsafe impl<T> Send for RTPBuffer<'_, T> {}
17unsafe impl<T> Sync for RTPBuffer<'_, T> {}
18
19impl<T> fmt::Debug for RTPBuffer<'_, T> {
20 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
21 f.debug_struct("RTPBuffer")
22 .field("rtp_buffer", &self.rtp_buffer)
23 .finish()
24 }
25}
26
27impl<'a> RTPBuffer<'a, Readable> {
28 #[inline]
29 pub fn from_buffer_readable(
30 buffer: &'a gst::BufferRef,
31 ) -> Result<RTPBuffer<'a, Readable>, glib::BoolError> {
32 skip_assert_initialized!();
33 unsafe {
34 let mut rtp_buffer = mem::MaybeUninit::zeroed();
35 let res: bool = from_glib(ffi::gst_rtp_buffer_map(
36 mut_override(buffer.as_ptr()),
37 gst::ffi::GST_MAP_READ,
38 rtp_buffer.as_mut_ptr(),
39 ));
40
41 if res {
42 Ok(RTPBuffer {
43 rtp_buffer: rtp_buffer.assume_init(),
44 phantom: PhantomData,
45 })
46 } else {
47 Err(glib::bool_error!("Failed to map RTP buffer readable"))
48 }
49 }
50 }
51
52 #[inline]
53 pub unsafe fn from_glib_borrow<'b>(
54 rtp_buffer: *mut ffi::GstRTPBuffer,
55 ) -> glib::translate::Borrowed<RTPBuffer<'b, Readable>> {
56 unsafe {
57 glib::translate::Borrowed::new(RTPBuffer {
58 rtp_buffer: *rtp_buffer,
59 phantom: PhantomData,
60 })
61 }
62 }
63}
64
65impl<'a> RTPBuffer<'a, Writable> {
66 #[inline]
67 pub fn from_buffer_writable(
68 buffer: &'a mut gst::BufferRef,
69 ) -> Result<RTPBuffer<'a, Writable>, glib::BoolError> {
70 skip_assert_initialized!();
71 unsafe {
72 let mut rtp_buffer = mem::MaybeUninit::zeroed();
73 let res: bool = from_glib(ffi::gst_rtp_buffer_map(
74 buffer.as_mut_ptr(),
75 gst::ffi::GST_MAP_READWRITE,
76 rtp_buffer.as_mut_ptr(),
77 ));
78
79 if res {
80 Ok(RTPBuffer {
81 rtp_buffer: rtp_buffer.assume_init(),
82 phantom: PhantomData,
83 })
84 } else {
85 Err(glib::bool_error!("Failed to map RTP buffer writable"))
86 }
87 }
88 }
89
90 #[doc(alias = "gst_rtp_buffer_set_seq")]
91 pub fn set_seq(&mut self, seq: u16) {
92 unsafe {
93 ffi::gst_rtp_buffer_set_seq(&mut self.rtp_buffer, seq);
94 }
95 }
96
97 #[doc(alias = "gst_rtp_buffer_set_marker")]
98 pub fn set_marker(&mut self, m: bool) {
99 unsafe {
100 ffi::gst_rtp_buffer_set_marker(&mut self.rtp_buffer, m.into_glib());
101 }
102 }
103
104 #[doc(alias = "gst_rtp_buffer_set_payload_type")]
105 pub fn set_payload_type(&mut self, pt: u8) {
106 unsafe {
107 ffi::gst_rtp_buffer_set_payload_type(&mut self.rtp_buffer, pt);
108 }
109 }
110
111 #[doc(alias = "gst_rtp_buffer_set_ssrc")]
112 pub fn set_ssrc(&mut self, ssrc: u32) {
113 unsafe { ffi::gst_rtp_buffer_set_ssrc(&mut self.rtp_buffer, ssrc) }
114 }
115
116 #[doc(alias = "gst_rtp_buffer_set_csrc")]
117 pub fn set_csrc(&mut self, idx: u8, ssrc: u32) {
118 unsafe { ffi::gst_rtp_buffer_set_csrc(&mut self.rtp_buffer, idx, ssrc) }
119 }
120
121 #[doc(alias = "gst_rtp_buffer_set_timestamp")]
122 pub fn set_timestamp(&mut self, rtptime: u32) {
123 unsafe {
124 ffi::gst_rtp_buffer_set_timestamp(&mut self.rtp_buffer, rtptime);
125 }
126 }
127
128 #[doc(alias = "gst_rtp_buffer_set_extension")]
129 pub fn set_extension(&mut self, extension: bool) {
130 unsafe { ffi::gst_rtp_buffer_set_extension(&mut self.rtp_buffer, extension.into_glib()) }
131 }
132
133 #[doc(alias = "gst_rtp_buffer_add_extension_onebyte_header")]
134 #[allow(clippy::manual_range_contains)]
135 pub fn add_extension_onebyte_header(
136 &mut self,
137 id: u8,
138 data: &[u8],
139 ) -> Result<(), glib::BoolError> {
140 assert!(
141 id >= 1 && id <= 14,
142 "id should be between 1 and 14 (inclusive)"
143 );
144 assert!(
145 !data.is_empty() && data.len() <= 16,
146 "data size should be between 1 and 16 (inclusive"
147 );
148 unsafe {
149 let result: bool = from_glib(ffi::gst_rtp_buffer_add_extension_onebyte_header(
150 &mut self.rtp_buffer,
151 id,
152 data.as_ptr() as glib::ffi::gconstpointer,
153 data.len() as u32,
154 ));
155 if result {
156 Ok(())
157 } else {
158 Err(glib::bool_error!("Failed to add onebyte header extension"))
159 }
160 }
161 }
162
163 #[doc(alias = "gst_rtp_buffer_add_extension_twobytes_header")]
164 pub fn add_extension_twobytes_header(
165 &mut self,
166 appbits: u8,
167 id: u8,
168 data: &[u8],
169 ) -> Result<(), glib::BoolError> {
170 assert_eq!(
171 appbits & 0xF0,
172 0,
173 "appbits must use only 4 bits (max value is 15)"
174 );
175 assert!(data.len() < 256, "data size should be smaller than 256");
176 unsafe {
177 let result: bool = from_glib(ffi::gst_rtp_buffer_add_extension_twobytes_header(
178 &mut self.rtp_buffer,
179 appbits,
180 id,
181 data.as_ptr() as glib::ffi::gconstpointer,
182 data.len() as u32,
183 ));
184 if result {
185 Ok(())
186 } else {
187 Err(glib::bool_error!("Failed to add twobytes header extension"))
188 }
189 }
190 }
191
192 #[cfg(feature = "v1_20")]
193 #[cfg_attr(docsrs, doc(cfg(feature = "v1_20")))]
194 #[doc(alias = "gst_rtp_buffer_remove_extension_data")]
195 pub fn remove_extension_data(&mut self) {
196 unsafe {
197 ffi::gst_rtp_buffer_remove_extension_data(&mut self.rtp_buffer);
198 }
199 }
200
201 #[doc(alias = "gst_rtp_buffer_set_padding")]
202 pub fn set_padding(&mut self, padding: bool) {
203 unsafe { ffi::gst_rtp_buffer_set_padding(&mut self.rtp_buffer, padding.into_glib()) }
204 }
205}
206
207impl<T> RTPBuffer<'_, T> {
208 #[doc(alias = "get_seq")]
209 #[doc(alias = "gst_rtp_buffer_get_seq")]
210 pub fn seq(&self) -> u16 {
211 unsafe { ffi::gst_rtp_buffer_get_seq(glib::translate::mut_override(&self.rtp_buffer)) }
212 }
213
214 #[doc(alias = "get_payload_type")]
215 #[doc(alias = "gst_rtp_buffer_get_payload_type")]
216 pub fn payload_type(&self) -> u8 {
217 unsafe {
218 ffi::gst_rtp_buffer_get_payload_type(glib::translate::mut_override(&self.rtp_buffer))
219 }
220 }
221
222 #[doc(alias = "get_ssrc")]
223 #[doc(alias = "gst_rtp_buffer_get_ssrc")]
224 pub fn ssrc(&self) -> u32 {
225 unsafe { ffi::gst_rtp_buffer_get_ssrc(glib::translate::mut_override(&self.rtp_buffer)) }
226 }
227
228 #[doc(alias = "get_timestamp")]
229 #[doc(alias = "gst_rtp_buffer_get_timestamp")]
230 pub fn timestamp(&self) -> u32 {
231 unsafe {
232 ffi::gst_rtp_buffer_get_timestamp(glib::translate::mut_override(&self.rtp_buffer))
233 }
234 }
235
236 #[doc(alias = "get_csrc")]
237 #[doc(alias = "gst_rtp_buffer_get_csrc")]
238 pub fn csrc(&self, idx: u8) -> Option<u32> {
239 if idx < self.csrc_count() {
240 unsafe {
241 Some(ffi::gst_rtp_buffer_get_csrc(
242 glib::translate::mut_override(&self.rtp_buffer),
243 idx,
244 ))
245 }
246 } else {
247 None
248 }
249 }
250
251 #[doc(alias = "get_csrc_count")]
252 #[doc(alias = "gst_rtp_buffer_get_csrc_count")]
253 pub fn csrc_count(&self) -> u8 {
254 unsafe {
255 ffi::gst_rtp_buffer_get_csrc_count(glib::translate::mut_override(&self.rtp_buffer))
256 }
257 }
258
259 #[doc(alias = "get_marker")]
260 pub fn is_marker(&self) -> bool {
261 unsafe {
262 from_glib(ffi::gst_rtp_buffer_get_marker(
263 glib::translate::mut_override(&self.rtp_buffer),
264 ))
265 }
266 }
267
268 #[doc(alias = "get_payload_size")]
269 pub fn payload_size(&self) -> u32 {
270 unsafe {
271 ffi::gst_rtp_buffer_get_payload_len(glib::translate::mut_override(&self.rtp_buffer))
272 }
273 }
274
275 #[doc(alias = "get_payload")]
276 #[doc(alias = "gst_rtp_buffer_get_payload")]
277 pub fn payload(&self) -> Result<&[u8], glib::error::BoolError> {
278 let size = self.payload_size();
279 if size == 0 {
280 return Ok(&[]);
281 }
282 unsafe {
283 let pointer =
284 ffi::gst_rtp_buffer_get_payload(glib::translate::mut_override(&self.rtp_buffer));
285 if pointer.is_null() {
286 Err(glib::bool_error!("Failed to get payload data"))
287 } else {
288 Ok(slice::from_raw_parts(pointer as *const u8, size as usize))
289 }
290 }
291 }
292
293 #[doc(alias = "get_payload")]
294 #[doc(alias = "gst_rtp_buffer_get_payload")]
295 pub fn payload_mut(&mut self) -> Result<&mut [u8], glib::error::BoolError> {
296 let size = self.payload_size();
297 if size == 0 {
298 return Ok(&mut []);
299 }
300 unsafe {
301 let pointer = ffi::gst_rtp_buffer_get_payload(&mut self.rtp_buffer);
302 if pointer.is_null() {
303 Err(glib::bool_error!("Failed to get payload data"))
304 } else {
305 Ok(slice::from_raw_parts_mut(pointer as *mut u8, size as usize))
306 }
307 }
308 }
309
310 #[doc(alias = "get_payload_buffer")]
311 #[doc(alias = "gst_rtp_buffer_get_payload_buffer")]
312 pub fn payload_buffer(&self) -> Result<gst::Buffer, glib::BoolError> {
313 unsafe {
314 Option::<_>::from_glib_full(ffi::gst_rtp_buffer_get_payload_buffer(
315 glib::translate::mut_override(&self.rtp_buffer),
316 ))
317 .ok_or_else(|| glib::bool_error!("Failed to get payload buffer"))
318 }
319 }
320
321 #[inline]
322 pub fn buffer(&self) -> &gst::BufferRef {
323 unsafe {
324 let ptr = self.rtp_buffer.buffer;
325
326 debug_assert!(!ptr.is_null());
327
328 gst::BufferRef::from_ptr(ptr)
329 }
330 }
331
332 #[doc(alias = "get_extension")]
333 pub fn is_extension(&self) -> bool {
334 unsafe {
335 from_glib(ffi::gst_rtp_buffer_get_extension(
336 glib::translate::mut_override(&self.rtp_buffer),
337 ))
338 }
339 }
340
341 #[doc(alias = "get_extension_bytes")]
342 #[doc(alias = "gst_rtp_buffer_get_extension_bytes")]
343 pub fn extension_bytes(&self) -> Option<(u16, glib::Bytes)> {
344 unsafe {
345 let mut bits: u16 = 0;
346 Option::<glib::Bytes>::from_glib_full(ffi::gst_rtp_buffer_get_extension_bytes(
347 glib::translate::mut_override(&self.rtp_buffer),
348 &mut bits,
349 ))
350 .map(|bytes| (bits, bytes))
351 }
352 }
353
354 #[doc(alias = "get_extension_onebyte_header")]
355 #[doc(alias = "gst_rtp_buffer_get_extension_onebyte_header")]
356 pub fn extension_onebyte_header(&self, id: u8, nth: u32) -> Option<&[u8]> {
357 unsafe {
358 let mut data = ptr::null_mut();
359 let data_ptr = &mut data as *mut *mut u8 as *mut u8;
361 let mut size: u32 = 0;
362 let result: bool = from_glib(ffi::gst_rtp_buffer_get_extension_onebyte_header(
363 glib::translate::mut_override(&self.rtp_buffer),
364 id,
365 nth,
366 data_ptr,
367 &mut size,
368 ));
369 if result {
370 if size == 0 {
371 Some(&[])
372 } else {
373 Some(slice::from_raw_parts(data as *const u8, size as usize))
374 }
375 } else {
376 None
377 }
378 }
379 }
380
381 #[doc(alias = "get_extension_twobytes_header")]
382 #[doc(alias = "gst_rtp_buffer_get_extension_twobytes_header")]
383 pub fn extension_twobytes_header(&self, id: u8, nth: u32) -> Option<(u8, &[u8])> {
384 unsafe {
385 let mut data = ptr::null_mut();
386 let data_ptr = &mut data as *mut *mut u8 as *mut u8;
388 let mut size: u32 = 0;
389 let mut appbits = 0;
390 let result: bool = from_glib(ffi::gst_rtp_buffer_get_extension_twobytes_header(
391 glib::translate::mut_override(&self.rtp_buffer),
392 &mut appbits,
393 id,
394 nth,
395 data_ptr,
396 &mut size,
397 ));
398 if result {
399 if size == 0 {
400 Some((appbits, &[]))
401 } else {
402 Some((
403 appbits,
404 slice::from_raw_parts(data as *const u8, size as usize),
405 ))
406 }
407 } else {
408 None
409 }
410 }
411 }
412
413 #[doc(alias = "get_padding")]
414 #[doc(alias = "gst_rtp_buffer_get_padding")]
415 pub fn has_padding(&self) -> bool {
416 unsafe {
417 from_glib(ffi::gst_rtp_buffer_get_padding(
418 glib::translate::mut_override(&self.rtp_buffer),
419 ))
420 }
421 }
422
423 #[inline]
424 pub fn as_ptr(&self) -> *const ffi::GstRTPBuffer {
425 &self.rtp_buffer as *const ffi::GstRTPBuffer
426 }
427
428 #[inline]
429 pub fn as_mut_ptr(&self) -> *mut ffi::GstRTPBuffer {
430 &self.rtp_buffer as *const ffi::GstRTPBuffer as *mut ffi::GstRTPBuffer
431 }
432}
433
434impl<T> Drop for RTPBuffer<'_, T> {
435 #[inline]
436 fn drop(&mut self) {
437 unsafe {
438 ffi::gst_rtp_buffer_unmap(&mut self.rtp_buffer);
439 }
440 }
441}
442
443pub trait RTPBufferExt {
444 fn new_rtp_with_sizes(
445 payload_len: u32,
446 pad_len: u8,
447 csrc_count: u8,
448 ) -> Result<gst::Buffer, glib::BoolError>;
449}
450
451impl RTPBufferExt for gst::Buffer {
452 fn new_rtp_with_sizes(
453 payload_len: u32,
454 pad_len: u8,
455 csrc_count: u8,
456 ) -> Result<gst::Buffer, glib::BoolError> {
457 assert_initialized_main_thread!();
458 unsafe {
459 Option::<_>::from_glib_full(ffi::gst_rtp_buffer_new_allocate(
460 payload_len,
461 pad_len,
462 csrc_count,
463 ))
464 .ok_or_else(|| glib::bool_error!("Failed to allocate new RTP buffer"))
465 }
466 }
467}
468
469#[doc(alias = "gst_rtp_buffer_compare_seqnum")]
470pub fn compare_seqnum(seqnum1: u16, seqnum2: u16) -> i32 {
471 skip_assert_initialized!();
472 unsafe { ffi::gst_rtp_buffer_compare_seqnum(seqnum1, seqnum2) }
473}
474
475#[doc(alias = "gst_rtp_buffer_calc_header_len")]
476pub fn calc_header_len(csrc_count: u8) -> u32 {
477 skip_assert_initialized!();
478 unsafe { ffi::gst_rtp_buffer_calc_header_len(csrc_count) }
479}
480
481#[doc(alias = "gst_rtp_buffer_calc_packet_len")]
482pub fn calc_packet_len(payload_len: u32, pad_len: u8, csrc_count: u8) -> u32 {
483 skip_assert_initialized!();
484 unsafe { ffi::gst_rtp_buffer_calc_packet_len(payload_len, pad_len, csrc_count) }
485}
486
487#[doc(alias = "gst_rtp_buffer_calc_payload_len")]
488pub fn calc_payload_len(packet_len: u32, pad_len: u8, csrc_count: u8) -> u32 {
489 skip_assert_initialized!();
490 unsafe { ffi::gst_rtp_buffer_calc_payload_len(packet_len, pad_len, csrc_count) }
491}
492
493#[doc(alias = "gst_rtp_buffer_ext_timestamp")]
494pub fn ext_timestamp(exttimestamp: &mut u64, timestamp: u32) -> u64 {
495 skip_assert_initialized!();
496 unsafe { ffi::gst_rtp_buffer_ext_timestamp(exttimestamp, timestamp) }
497}
498
499#[cfg(test)]
500mod tests {
501 use super::*;
502
503 #[test]
504 fn test_map() {
505 gst::init().unwrap();
506
507 let csrc_count = 2;
508 let payload_size = 16;
509 let mut buffer = gst::Buffer::new_rtp_with_sizes(payload_size, 4, csrc_count).unwrap();
510 {
511 let buffer = buffer.get_mut().unwrap();
512 let mut rtp_buffer = RTPBuffer::from_buffer_writable(buffer).unwrap();
513
514 rtp_buffer.set_seq(42);
515 assert_eq!(rtp_buffer.seq(), 42);
516
517 rtp_buffer.set_marker(true);
518 assert!(rtp_buffer.is_marker());
519
520 rtp_buffer.set_payload_type(43);
521 assert_eq!(rtp_buffer.payload_type(), 43);
522
523 rtp_buffer.set_timestamp(44);
524 assert_eq!(rtp_buffer.timestamp(), 44);
525
526 rtp_buffer.set_ssrc(45);
527 assert_eq!(rtp_buffer.ssrc(), 45);
528
529 assert_eq!(rtp_buffer.payload_size(), payload_size);
530 let payload = rtp_buffer.payload();
531 assert!(payload.is_ok());
532 let payload = payload.unwrap();
533 assert_eq!(payload.len(), payload_size as usize);
534
535 assert_eq!(rtp_buffer.csrc_count(), csrc_count);
536 rtp_buffer.set_csrc(0, 12);
537 rtp_buffer.set_csrc(1, 15);
538 assert_eq!(rtp_buffer.csrc(0).unwrap(), 12);
539 assert_eq!(rtp_buffer.csrc(1).unwrap(), 15);
540 assert!(rtp_buffer.csrc(2).is_none());
541
542 rtp_buffer.set_extension(true);
543 assert!(rtp_buffer.is_extension());
544
545 assert_eq!(rtp_buffer.extension_bytes(), None);
546 }
547 }
548
549 #[test]
550 fn test_empty_payload() {
551 gst::init().unwrap();
552
553 let csrc_count = 0;
554 let payload_size = 0;
555 let buffer = gst::Buffer::new_rtp_with_sizes(payload_size, 4, csrc_count).unwrap();
556 let rtp_buffer = RTPBuffer::from_buffer_readable(&buffer).unwrap();
557
558 assert_eq!(rtp_buffer.payload_size(), payload_size);
559 let payload = rtp_buffer.payload();
560 assert!(payload.is_ok());
561 assert_eq!(payload.unwrap().len(), payload_size as usize);
562 }
563
564 #[test]
565 fn test_mut_payload() {
566 gst::init().unwrap();
567
568 let csrc_count = 2;
569 let payload_size = 8;
570 let mut buffer = gst::Buffer::new_rtp_with_sizes(payload_size, 4, csrc_count).unwrap();
571 {
572 let buffer = buffer.get_mut().unwrap();
573 let mut rtp_buffer = RTPBuffer::from_buffer_writable(buffer).unwrap();
574
575 let payload = rtp_buffer.payload_mut();
576 assert!(payload.is_ok());
577
578 let payload = payload.unwrap();
579 payload[3] = 42;
580 }
581
582 let rtp_buffer = RTPBuffer::from_buffer_readable(&buffer).unwrap();
583 let payload = rtp_buffer.payload();
584
585 assert!(payload.is_ok());
586 assert_eq!(payload.unwrap()[3], 42);
587 }
588
589 #[test]
590 fn test_extension_header_onebyte() {
591 gst::init().unwrap();
592
593 let extension_data: [u8; 4] = [100, 101, 102, 103];
594 let mut buffer = gst::Buffer::new_rtp_with_sizes(16, 4, 0).unwrap();
595 {
596 let buffer = buffer.get_mut().unwrap();
597 let mut rtp_buffer = RTPBuffer::from_buffer_writable(buffer).unwrap();
598
599 assert_eq!(rtp_buffer.extension_bytes(), None);
600
601 let result = rtp_buffer.add_extension_onebyte_header(1, &extension_data);
602 assert!(result.is_ok());
603 }
604
605 let rtp_buffer = RTPBuffer::from_buffer_readable(&buffer).unwrap();
606 let bytes_option = rtp_buffer.extension_bytes();
607 assert!(bytes_option.is_some());
608 let (bits, bytes) = bytes_option.unwrap();
609 assert_eq!(bits, 0xbede);
611 assert_eq!(bytes[0] >> 4, 1);
618 assert_eq!(bytes[0] & 0xF, 3);
619 for i in 0..extension_data.len() {
620 assert_eq!(bytes[i + 1], extension_data[i]);
621 }
622
623 let result = rtp_buffer.extension_onebyte_header(2, 0);
624 assert!(result.is_none());
625
626 let result = rtp_buffer.extension_onebyte_header(1, 0);
627 assert!(result.is_some());
628 assert_eq!(result.unwrap(), &extension_data);
629 }
630
631 #[test]
632 fn test_extension_header_twobytes() {
633 gst::init().unwrap();
634
635 let extension_data: [u8; 4] = [100, 101, 102, 103];
636 let appbits = 5;
637 let id = 1;
638
639 let mut buffer = gst::Buffer::new_rtp_with_sizes(16, 4, 0).unwrap();
640 {
641 let buffer = buffer.get_mut().unwrap();
642 let mut rtp_buffer = RTPBuffer::from_buffer_writable(buffer).unwrap();
643
644 assert_eq!(rtp_buffer.extension_bytes(), None);
645
646 let result = rtp_buffer.add_extension_twobytes_header(appbits, id, &extension_data);
647 assert!(result.is_ok());
648 }
649
650 let rtp_buffer = RTPBuffer::from_buffer_readable(&buffer).unwrap();
651
652 let bytes_option = rtp_buffer.extension_bytes();
653 assert!(bytes_option.is_some());
654 let (bits, bytes) = bytes_option.unwrap();
655 assert_eq!(bits, 0x1000 | appbits as u16);
658 assert_eq!(bytes[0], id);
665 assert_eq!(bytes[1], extension_data.len() as u8);
666 for i in 0..extension_data.len() {
667 assert_eq!(bytes[i + 2], extension_data[i]);
668 }
669
670 let result = rtp_buffer.extension_twobytes_header(2, 0);
671 assert!(result.is_none());
672
673 let result = rtp_buffer.extension_twobytes_header(id, 0);
674 assert!(result.is_some());
675 let (extracted_appbits, data) = result.unwrap();
676 assert_eq!(appbits, extracted_appbits);
677 assert_eq!(data, &extension_data);
678 }
679
680 #[test]
681 fn test_padding() {
682 gst::init().unwrap();
683
684 let csrc_count = 2;
685 let payload_size = 16;
686 let mut buffer = gst::Buffer::new_rtp_with_sizes(payload_size, 4, csrc_count).unwrap();
687 {
688 let rtp_buffer = RTPBuffer::from_buffer_readable(&buffer).unwrap();
689 assert!(rtp_buffer.has_padding());
690 }
691 {
692 let buffer = buffer.get_mut().unwrap();
693 let mut rtp_buffer = RTPBuffer::from_buffer_writable(buffer).unwrap();
694
695 rtp_buffer.set_padding(false);
696 }
697
698 {
699 let rtp_buffer = RTPBuffer::from_buffer_readable(&buffer).unwrap();
700 assert!(!rtp_buffer.has_padding());
701 }
702 }
703
704 #[test]
705 fn test_calc_functions() {
706 let res = super::calc_header_len(0);
707 assert_eq!(res, 12);
708 let res = super::calc_packet_len(100, 10, 2);
709 assert_eq!(res, 130);
710 let res = super::calc_payload_len(100, 5, 4);
711 assert_eq!(res, 67);
712 }
713}