mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer-rs.git
synced 2024-11-29 04:51:09 +00:00
rtp/rtpbuffer: Work on &BufferRef
/ &mut BufferRef
instead of &Buffer
/ &mut Buffer
The buffer, in the writable case, needs to be actually writable (i.e. refcount 1) and this was previously not ensured. Also it caused some API mismatch when trying to use it e.g. as part of basetransform's `transform_ip()` virtual method. Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/issues/162
This commit is contained in:
parent
a208919c88
commit
a3a7f85f7f
1 changed files with 57 additions and 49 deletions
|
@ -1,6 +1,6 @@
|
||||||
// Take a look at the license at the top of the repository in the LICENSE file.
|
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||||
|
|
||||||
use glib::translate::{from_glib, FromGlibPtrFull, IntoGlib};
|
use glib::translate::{from_glib, mut_override, FromGlibPtrFull, IntoGlib};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
@ -12,8 +12,7 @@ pub enum Writable {}
|
||||||
|
|
||||||
pub struct RTPBuffer<'a, T> {
|
pub struct RTPBuffer<'a, T> {
|
||||||
rtp_buffer: ffi::GstRTPBuffer,
|
rtp_buffer: ffi::GstRTPBuffer,
|
||||||
buffer: &'a gst::Buffer,
|
phantom: PhantomData<&'a T>,
|
||||||
phantom: PhantomData<T>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<'a, T> Send for RTPBuffer<'a, T> {}
|
unsafe impl<'a, T> Send for RTPBuffer<'a, T> {}
|
||||||
|
@ -23,21 +22,19 @@ impl<'a, T> fmt::Debug for RTPBuffer<'a, T> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
f.debug_struct("RTPBuffer")
|
f.debug_struct("RTPBuffer")
|
||||||
.field("rtp_buffer", &self.rtp_buffer)
|
.field("rtp_buffer", &self.rtp_buffer)
|
||||||
.field("buffer", &self.buffer)
|
|
||||||
.field("phantom", &self.phantom)
|
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> RTPBuffer<'a, Readable> {
|
impl<'a> RTPBuffer<'a, Readable> {
|
||||||
pub fn from_buffer_readable(
|
pub fn from_buffer_readable(
|
||||||
buffer: &gst::Buffer,
|
buffer: &'a gst::BufferRef,
|
||||||
) -> Result<RTPBuffer<Readable>, glib::BoolError> {
|
) -> Result<RTPBuffer<Readable>, glib::BoolError> {
|
||||||
skip_assert_initialized!();
|
skip_assert_initialized!();
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut rtp_buffer = mem::MaybeUninit::zeroed();
|
let mut rtp_buffer = mem::MaybeUninit::zeroed();
|
||||||
let res: bool = from_glib(ffi::gst_rtp_buffer_map(
|
let res: bool = from_glib(ffi::gst_rtp_buffer_map(
|
||||||
buffer.as_mut_ptr(),
|
mut_override(buffer.as_ptr()),
|
||||||
gst::ffi::GST_MAP_READ,
|
gst::ffi::GST_MAP_READ,
|
||||||
rtp_buffer.as_mut_ptr(),
|
rtp_buffer.as_mut_ptr(),
|
||||||
));
|
));
|
||||||
|
@ -45,7 +42,6 @@ impl<'a> RTPBuffer<'a, Readable> {
|
||||||
if res {
|
if res {
|
||||||
Ok(RTPBuffer {
|
Ok(RTPBuffer {
|
||||||
rtp_buffer: rtp_buffer.assume_init(),
|
rtp_buffer: rtp_buffer.assume_init(),
|
||||||
buffer,
|
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
@ -57,7 +53,7 @@ impl<'a> RTPBuffer<'a, Readable> {
|
||||||
|
|
||||||
impl<'a> RTPBuffer<'a, Writable> {
|
impl<'a> RTPBuffer<'a, Writable> {
|
||||||
pub fn from_buffer_writable(
|
pub fn from_buffer_writable(
|
||||||
buffer: &mut gst::Buffer,
|
buffer: &'a mut gst::BufferRef,
|
||||||
) -> Result<RTPBuffer<Writable>, glib::BoolError> {
|
) -> Result<RTPBuffer<Writable>, glib::BoolError> {
|
||||||
skip_assert_initialized!();
|
skip_assert_initialized!();
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -71,7 +67,6 @@ impl<'a> RTPBuffer<'a, Writable> {
|
||||||
if res {
|
if res {
|
||||||
Ok(RTPBuffer {
|
Ok(RTPBuffer {
|
||||||
rtp_buffer: rtp_buffer.assume_init(),
|
rtp_buffer: rtp_buffer.assume_init(),
|
||||||
buffer,
|
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
@ -394,40 +389,43 @@ mod tests {
|
||||||
let csrc_count = 2;
|
let csrc_count = 2;
|
||||||
let payload_size = 16;
|
let payload_size = 16;
|
||||||
let mut buffer = gst::Buffer::new_rtp_with_sizes(payload_size, 4, csrc_count).unwrap();
|
let mut buffer = gst::Buffer::new_rtp_with_sizes(payload_size, 4, csrc_count).unwrap();
|
||||||
let mut rtp_buffer = RTPBuffer::from_buffer_writable(&mut buffer).unwrap();
|
{
|
||||||
|
let buffer = buffer.get_mut().unwrap();
|
||||||
|
let mut rtp_buffer = RTPBuffer::from_buffer_writable(buffer).unwrap();
|
||||||
|
|
||||||
rtp_buffer.set_seq(42);
|
rtp_buffer.set_seq(42);
|
||||||
assert_eq!(rtp_buffer.seq(), 42);
|
assert_eq!(rtp_buffer.seq(), 42);
|
||||||
|
|
||||||
rtp_buffer.set_marker(true);
|
rtp_buffer.set_marker(true);
|
||||||
assert!(rtp_buffer.is_marker());
|
assert!(rtp_buffer.is_marker());
|
||||||
|
|
||||||
rtp_buffer.set_payload_type(43);
|
rtp_buffer.set_payload_type(43);
|
||||||
assert_eq!(rtp_buffer.payload_type(), 43);
|
assert_eq!(rtp_buffer.payload_type(), 43);
|
||||||
|
|
||||||
rtp_buffer.set_timestamp(44);
|
rtp_buffer.set_timestamp(44);
|
||||||
assert_eq!(rtp_buffer.timestamp(), 44);
|
assert_eq!(rtp_buffer.timestamp(), 44);
|
||||||
|
|
||||||
rtp_buffer.set_ssrc(45);
|
rtp_buffer.set_ssrc(45);
|
||||||
assert_eq!(rtp_buffer.ssrc(), 45);
|
assert_eq!(rtp_buffer.ssrc(), 45);
|
||||||
|
|
||||||
assert_eq!(rtp_buffer.payload_size(), payload_size);
|
assert_eq!(rtp_buffer.payload_size(), payload_size);
|
||||||
let payload = rtp_buffer.payload();
|
let payload = rtp_buffer.payload();
|
||||||
assert!(payload.is_ok());
|
assert!(payload.is_ok());
|
||||||
let payload = payload.unwrap();
|
let payload = payload.unwrap();
|
||||||
assert_eq!(payload.len(), payload_size as usize);
|
assert_eq!(payload.len(), payload_size as usize);
|
||||||
|
|
||||||
assert_eq!(rtp_buffer.csrc_count(), csrc_count);
|
assert_eq!(rtp_buffer.csrc_count(), csrc_count);
|
||||||
rtp_buffer.set_csrc(0, 12);
|
rtp_buffer.set_csrc(0, 12);
|
||||||
rtp_buffer.set_csrc(1, 15);
|
rtp_buffer.set_csrc(1, 15);
|
||||||
assert_eq!(rtp_buffer.csrc(0).unwrap(), 12);
|
assert_eq!(rtp_buffer.csrc(0).unwrap(), 12);
|
||||||
assert_eq!(rtp_buffer.csrc(1).unwrap(), 15);
|
assert_eq!(rtp_buffer.csrc(1).unwrap(), 15);
|
||||||
assert!(rtp_buffer.csrc(2).is_none());
|
assert!(rtp_buffer.csrc(2).is_none());
|
||||||
|
|
||||||
rtp_buffer.set_extension(true);
|
rtp_buffer.set_extension(true);
|
||||||
assert!(rtp_buffer.is_extension());
|
assert!(rtp_buffer.is_extension());
|
||||||
|
|
||||||
assert_eq!(rtp_buffer.extension_bytes(), None);
|
assert_eq!(rtp_buffer.extension_bytes(), None);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -449,15 +447,19 @@ mod tests {
|
||||||
fn test_extension_header_onebyte() {
|
fn test_extension_header_onebyte() {
|
||||||
gst::init().unwrap();
|
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();
|
|
||||||
|
|
||||||
assert_eq!(rtp_buffer.extension_bytes(), None);
|
|
||||||
|
|
||||||
let extension_data: [u8; 4] = [100, 101, 102, 103];
|
let extension_data: [u8; 4] = [100, 101, 102, 103];
|
||||||
let result = rtp_buffer.add_extension_onebyte_header(1, &extension_data);
|
let mut buffer = gst::Buffer::new_rtp_with_sizes(16, 4, 0).unwrap();
|
||||||
assert!(result.is_ok());
|
{
|
||||||
|
let buffer = buffer.get_mut().unwrap();
|
||||||
|
let mut rtp_buffer = RTPBuffer::from_buffer_writable(buffer).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(rtp_buffer.extension_bytes(), None);
|
||||||
|
|
||||||
|
let result = rtp_buffer.add_extension_onebyte_header(1, &extension_data);
|
||||||
|
assert!(result.is_ok());
|
||||||
|
}
|
||||||
|
|
||||||
|
let rtp_buffer = RTPBuffer::from_buffer_readable(&buffer).unwrap();
|
||||||
let bytes_option = rtp_buffer.extension_bytes();
|
let bytes_option = rtp_buffer.extension_bytes();
|
||||||
assert!(bytes_option.is_some());
|
assert!(bytes_option.is_some());
|
||||||
let (bits, bytes) = bytes_option.unwrap();
|
let (bits, bytes) = bytes_option.unwrap();
|
||||||
|
@ -487,16 +489,22 @@ mod tests {
|
||||||
fn test_extension_header_twobytes() {
|
fn test_extension_header_twobytes() {
|
||||||
gst::init().unwrap();
|
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();
|
|
||||||
|
|
||||||
assert_eq!(rtp_buffer.extension_bytes(), None);
|
|
||||||
|
|
||||||
let extension_data: [u8; 4] = [100, 101, 102, 103];
|
let extension_data: [u8; 4] = [100, 101, 102, 103];
|
||||||
let appbits = 5;
|
let appbits = 5;
|
||||||
let id = 1;
|
let id = 1;
|
||||||
let result = rtp_buffer.add_extension_twobytes_header(appbits, id, &extension_data);
|
|
||||||
assert!(result.is_ok());
|
let mut buffer = gst::Buffer::new_rtp_with_sizes(16, 4, 0).unwrap();
|
||||||
|
{
|
||||||
|
let buffer = buffer.get_mut().unwrap();
|
||||||
|
let mut rtp_buffer = RTPBuffer::from_buffer_writable(buffer).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(rtp_buffer.extension_bytes(), None);
|
||||||
|
|
||||||
|
let result = rtp_buffer.add_extension_twobytes_header(appbits, id, &extension_data);
|
||||||
|
assert!(result.is_ok());
|
||||||
|
}
|
||||||
|
|
||||||
|
let rtp_buffer = RTPBuffer::from_buffer_readable(&buffer).unwrap();
|
||||||
|
|
||||||
let bytes_option = rtp_buffer.extension_bytes();
|
let bytes_option = rtp_buffer.extension_bytes();
|
||||||
assert!(bytes_option.is_some());
|
assert!(bytes_option.is_some());
|
||||||
|
|
Loading…
Reference in a new issue