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