2019-12-17 19:00:42 +00:00
|
|
|
use glib::translate::{from_glib, FromGlibPtrFull};
|
2020-01-22 17:08:27 +00:00
|
|
|
use std::fmt;
|
2019-08-14 02:43:24 +00:00
|
|
|
use std::marker::PhantomData;
|
|
|
|
use std::mem;
|
|
|
|
|
|
|
|
use gst::MiniObject;
|
|
|
|
use gst_rtp_sys;
|
|
|
|
|
|
|
|
pub enum Readable {}
|
|
|
|
pub enum Writable {}
|
|
|
|
|
2020-01-22 17:08:27 +00:00
|
|
|
pub struct RTPBuffer<'a, T> {
|
|
|
|
rtp_buffer: gst_rtp_sys::GstRTPBuffer,
|
|
|
|
buffer: &'a gst::Buffer,
|
|
|
|
phantom: PhantomData<T>,
|
|
|
|
}
|
2019-08-14 02:43:24 +00:00
|
|
|
|
2019-12-18 15:04:42 +00:00
|
|
|
unsafe impl<'a, T> Send for RTPBuffer<'a, T> {}
|
|
|
|
unsafe impl<'a, T> Sync for RTPBuffer<'a, T> {}
|
|
|
|
|
2020-01-22 17:08:27 +00:00
|
|
|
impl<'a, T> fmt::Debug for RTPBuffer<'a, T> {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
f.debug_struct("RTPBuffer")
|
|
|
|
.field("rtp_buffer", &self.rtp_buffer)
|
|
|
|
.field("buffer", &self.buffer)
|
|
|
|
.field("phantom", &self.phantom)
|
|
|
|
.finish()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-14 02:43:24 +00:00
|
|
|
impl<'a> RTPBuffer<'a, Readable> {
|
|
|
|
pub fn from_buffer_readable(
|
|
|
|
buffer: &gst::Buffer,
|
|
|
|
) -> Result<RTPBuffer<Readable>, glib::BoolError> {
|
2020-03-22 14:18:47 +00:00
|
|
|
skip_assert_initialized!();
|
2019-08-14 02:43:24 +00:00
|
|
|
unsafe {
|
|
|
|
let mut rtp_buffer = mem::MaybeUninit::zeroed();
|
|
|
|
let res: bool = from_glib(gst_rtp_sys::gst_rtp_buffer_map(
|
|
|
|
buffer.as_mut_ptr(),
|
|
|
|
gst_sys::GST_MAP_READ,
|
|
|
|
rtp_buffer.as_mut_ptr(),
|
|
|
|
));
|
|
|
|
|
|
|
|
if res {
|
2020-01-22 17:08:27 +00:00
|
|
|
Ok(RTPBuffer {
|
|
|
|
rtp_buffer: rtp_buffer.assume_init(),
|
|
|
|
buffer,
|
|
|
|
phantom: PhantomData,
|
|
|
|
})
|
2019-08-14 02:43:24 +00:00
|
|
|
} else {
|
|
|
|
Err(glib_bool_error!("Failed to map RTP buffer readable"))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> RTPBuffer<'a, Writable> {
|
|
|
|
pub fn from_buffer_writable(
|
|
|
|
buffer: &mut gst::Buffer,
|
|
|
|
) -> Result<RTPBuffer<Writable>, glib::BoolError> {
|
2020-03-22 14:18:47 +00:00
|
|
|
skip_assert_initialized!();
|
2019-08-14 02:43:24 +00:00
|
|
|
unsafe {
|
|
|
|
let mut rtp_buffer = mem::MaybeUninit::zeroed();
|
|
|
|
let res: bool = from_glib(gst_rtp_sys::gst_rtp_buffer_map(
|
|
|
|
buffer.as_mut_ptr(),
|
|
|
|
gst_sys::GST_MAP_READWRITE,
|
|
|
|
rtp_buffer.as_mut_ptr(),
|
|
|
|
));
|
|
|
|
|
|
|
|
if res {
|
2020-01-22 17:08:27 +00:00
|
|
|
Ok(RTPBuffer {
|
|
|
|
rtp_buffer: rtp_buffer.assume_init(),
|
|
|
|
buffer,
|
|
|
|
phantom: PhantomData,
|
|
|
|
})
|
2019-08-14 02:43:24 +00:00
|
|
|
} else {
|
|
|
|
Err(glib_bool_error!("Failed to map RTP buffer writable"))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn set_seq(&mut self, seq: u16) {
|
|
|
|
unsafe {
|
2020-01-22 17:08:27 +00:00
|
|
|
gst_rtp_sys::gst_rtp_buffer_set_seq(&mut self.rtp_buffer, seq);
|
2019-08-14 02:43:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn set_payload_type(&mut self, pt: u8) {
|
|
|
|
unsafe {
|
2020-01-22 17:08:27 +00:00
|
|
|
gst_rtp_sys::gst_rtp_buffer_set_payload_type(&mut self.rtp_buffer, pt);
|
2019-08-14 02:43:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn set_timestamp(&mut self, rtptime: u32) {
|
|
|
|
unsafe {
|
2020-01-22 17:08:27 +00:00
|
|
|
gst_rtp_sys::gst_rtp_buffer_set_timestamp(&mut self.rtp_buffer, rtptime);
|
2019-08-14 02:43:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a, T> RTPBuffer<'a, T> {
|
|
|
|
pub fn get_seq(&mut self) -> u16 {
|
2020-01-22 17:08:27 +00:00
|
|
|
unsafe { gst_rtp_sys::gst_rtp_buffer_get_seq(&mut self.rtp_buffer) }
|
2019-08-14 02:43:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_payload_type(&mut self) -> u8 {
|
2020-01-22 17:08:27 +00:00
|
|
|
unsafe { gst_rtp_sys::gst_rtp_buffer_get_payload_type(&mut self.rtp_buffer) }
|
2019-08-14 02:43:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_timestamp(&mut self) -> u32 {
|
2020-01-22 17:08:27 +00:00
|
|
|
unsafe { gst_rtp_sys::gst_rtp_buffer_get_timestamp(&mut self.rtp_buffer) }
|
2019-08-14 02:43:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a, T> Drop for RTPBuffer<'a, T> {
|
|
|
|
fn drop(&mut self) {
|
|
|
|
unsafe {
|
2020-01-22 17:08:27 +00:00
|
|
|
gst_rtp_sys::gst_rtp_buffer_unmap(&mut self.rtp_buffer);
|
2019-08-14 02:43:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub trait RTPBufferExt {
|
2019-12-17 19:00:42 +00:00
|
|
|
fn new_rtp_with_sizes(
|
|
|
|
payload_len: u32,
|
|
|
|
pad_len: u8,
|
|
|
|
csrc_count: u8,
|
|
|
|
) -> Result<gst::Buffer, glib::BoolError>;
|
2019-08-14 02:43:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl RTPBufferExt for gst::Buffer {
|
2019-12-17 19:00:42 +00:00
|
|
|
fn new_rtp_with_sizes(
|
|
|
|
payload_len: u32,
|
|
|
|
pad_len: u8,
|
|
|
|
csrc_count: u8,
|
|
|
|
) -> Result<gst::Buffer, glib::BoolError> {
|
2020-03-22 14:18:47 +00:00
|
|
|
assert_initialized_main_thread!();
|
2019-08-14 02:43:24 +00:00
|
|
|
unsafe {
|
2019-12-17 19:00:42 +00:00
|
|
|
Option::<_>::from_glib_full(gst_rtp_sys::gst_rtp_buffer_new_allocate(
|
2019-08-14 02:43:24 +00:00
|
|
|
payload_len,
|
|
|
|
pad_len,
|
|
|
|
csrc_count,
|
|
|
|
))
|
2019-12-17 19:00:42 +00:00
|
|
|
.ok_or_else(|| glib_bool_error!("Failed to allocate new RTP buffer"))
|
2019-08-14 02:43:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn compare_seqnum(seqnum1: u16, seqnum2: u16) -> i32 {
|
2020-03-22 14:18:47 +00:00
|
|
|
skip_assert_initialized!();
|
2019-08-14 02:43:24 +00:00
|
|
|
unsafe { gst_rtp_sys::gst_rtp_buffer_compare_seqnum(seqnum1, seqnum2) }
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_map() {
|
|
|
|
gst::init().unwrap();
|
|
|
|
|
|
|
|
let mut buffer = gst::Buffer::new_rtp_with_sizes(16, 4, 0).unwrap();
|
|
|
|
let mut rtp_buffer = RTPBuffer::from_buffer_writable(&mut buffer).unwrap();
|
|
|
|
|
|
|
|
rtp_buffer.set_seq(42);
|
|
|
|
assert_eq!(rtp_buffer.get_seq(), 42);
|
|
|
|
|
|
|
|
rtp_buffer.set_payload_type(43);
|
|
|
|
assert_eq!(rtp_buffer.get_payload_type(), 43);
|
|
|
|
|
|
|
|
rtp_buffer.set_timestamp(44);
|
|
|
|
assert_eq!(rtp_buffer.get_timestamp(), 44);
|
|
|
|
}
|
|
|
|
}
|