mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer-rs.git
synced 2025-09-03 18:33:51 +00:00
Make Buffer map bindings more simple and consistent
This commit is contained in:
parent
4b24ca1823
commit
1a3b556fb6
4 changed files with 62 additions and 105 deletions
|
@ -53,7 +53,9 @@ fn create_pipeline() -> Result<Pipeline, utils::ExampleError> {
|
||||||
.get_buffer()
|
.get_buffer()
|
||||||
.expect("Unable to extract buffer from the sample");
|
.expect("Unable to extract buffer from the sample");
|
||||||
assert_eq!(buffer.get_size() % 2, 0);
|
assert_eq!(buffer.get_size() % 2, 0);
|
||||||
let map = buffer.map_read().expect("Unable to map buffer for reading");
|
let map = buffer
|
||||||
|
.map_readable()
|
||||||
|
.expect("Unable to map buffer for reading");
|
||||||
let data = map.as_slice();
|
let data = map.as_slice();
|
||||||
let sum: f64 = data.chunks(2)
|
let sum: f64 = data.chunks(2)
|
||||||
.map(|sample| {
|
.map(|sample| {
|
||||||
|
|
|
@ -21,7 +21,7 @@ fn main() {
|
||||||
let src_pad = src.get_static_pad("src").unwrap();
|
let src_pad = src.get_static_pad("src").unwrap();
|
||||||
src_pad.add_probe(PAD_PROBE_TYPE_BUFFER, |_, probe_info| {
|
src_pad.add_probe(PAD_PROBE_TYPE_BUFFER, |_, probe_info| {
|
||||||
if let Some(PadProbeData::Buffer(ref buffer)) = probe_info.data {
|
if let Some(PadProbeData::Buffer(ref buffer)) = probe_info.data {
|
||||||
let map = buffer.map_read().unwrap();
|
let map = buffer.map_readable().unwrap();
|
||||||
let data = map.as_slice();
|
let data = map.as_slice();
|
||||||
let sum: f64 = data.chunks(2)
|
let sum: f64 = data.chunks(2)
|
||||||
.map(|sample| {
|
.map(|sample| {
|
||||||
|
|
|
@ -12,6 +12,7 @@ use std::fmt;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use std::u64;
|
use std::u64;
|
||||||
use std::usize;
|
use std::usize;
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
use miniobject::*;
|
use miniobject::*;
|
||||||
use BufferFlags;
|
use BufferFlags;
|
||||||
|
@ -22,6 +23,9 @@ use glib_ffi;
|
||||||
use ffi;
|
use ffi;
|
||||||
use glib::translate::{from_glib, from_glib_full};
|
use glib::translate::{from_glib, from_glib_full};
|
||||||
|
|
||||||
|
pub struct Readable;
|
||||||
|
pub struct Writable;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct BufferRef(ffi::GstBuffer);
|
pub struct BufferRef(ffi::GstBuffer);
|
||||||
pub type Buffer = GstRc<BufferRef>;
|
pub type Buffer = GstRc<BufferRef>;
|
||||||
|
@ -30,36 +34,16 @@ unsafe impl MiniObject for BufferRef {
|
||||||
type GstType = ffi::GstBuffer;
|
type GstType = ffi::GstBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
//#[derive(Derivative)]
|
pub struct BufferMap<'a, T> {
|
||||||
//#[derivative(Debug)]
|
|
||||||
pub struct ReadBufferMap<'a> {
|
|
||||||
buffer: &'a BufferRef,
|
buffer: &'a BufferRef,
|
||||||
//#[derivative(Debug = "ignore")]
|
|
||||||
map_info: ffi::GstMapInfo,
|
map_info: ffi::GstMapInfo,
|
||||||
|
phantom: PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
//#[derive(Derivative)]
|
pub struct MappedBuffer<T> {
|
||||||
//#[derivative(Debug)]
|
buffer: Option<Buffer>,
|
||||||
pub struct ReadWriteBufferMap<'a> {
|
|
||||||
buffer: &'a BufferRef,
|
|
||||||
//#[derivative(Debug = "ignore")]
|
|
||||||
map_info: ffi::GstMapInfo,
|
|
||||||
}
|
|
||||||
|
|
||||||
//#[derive(Derivative)]
|
|
||||||
//#[derivative(Debug)]
|
|
||||||
pub struct ReadMappedBuffer {
|
|
||||||
buffer: Buffer,
|
|
||||||
//#[derivative(Debug = "ignore")]
|
|
||||||
map_info: ffi::GstMapInfo,
|
|
||||||
}
|
|
||||||
|
|
||||||
//#[derive(Derivative)]
|
|
||||||
//#[derivative(Debug)]
|
|
||||||
pub struct ReadWriteMappedBuffer {
|
|
||||||
buffer: Buffer,
|
|
||||||
//#[derivative(Debug = "ignore")]
|
|
||||||
map_info: ffi::GstMapInfo,
|
map_info: ffi::GstMapInfo,
|
||||||
|
phantom: PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GstRc<BufferRef> {
|
impl GstRc<BufferRef> {
|
||||||
|
@ -69,7 +53,7 @@ impl GstRc<BufferRef> {
|
||||||
unsafe { from_glib_full(ffi::gst_buffer_new()) }
|
unsafe { from_glib_full(ffi::gst_buffer_new()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_with_size(size: usize) -> Option<Self> {
|
pub fn with_size(size: usize) -> Option<Self> {
|
||||||
let raw = unsafe { ffi::gst_buffer_new_allocate(ptr::null_mut(), size, ptr::null_mut()) };
|
let raw = unsafe { ffi::gst_buffer_new_allocate(ptr::null_mut(), size, ptr::null_mut()) };
|
||||||
if raw.is_null() {
|
if raw.is_null() {
|
||||||
None
|
None
|
||||||
|
@ -108,7 +92,7 @@ impl GstRc<BufferRef> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn into_read_mapped_buffer(self) -> Result<ReadMappedBuffer, Self> {
|
pub fn into_mapped_buffer_readable(self) -> Result<MappedBuffer<Readable>, Self> {
|
||||||
let mut map_info: ffi::GstMapInfo = unsafe { mem::zeroed() };
|
let mut map_info: ffi::GstMapInfo = unsafe { mem::zeroed() };
|
||||||
let res: bool = unsafe {
|
let res: bool = unsafe {
|
||||||
from_glib(ffi::gst_buffer_map(
|
from_glib(ffi::gst_buffer_map(
|
||||||
|
@ -118,16 +102,17 @@ impl GstRc<BufferRef> {
|
||||||
))
|
))
|
||||||
};
|
};
|
||||||
if res {
|
if res {
|
||||||
Ok(ReadMappedBuffer {
|
Ok(MappedBuffer {
|
||||||
buffer: self,
|
buffer: Some(self),
|
||||||
map_info: map_info,
|
map_info: map_info,
|
||||||
|
phantom: PhantomData,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Err(self)
|
Err(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn into_readwrite_mapped_buffer(self) -> Result<ReadWriteMappedBuffer, Self> {
|
pub fn into_mapped_buffer_writable(self) -> Result<MappedBuffer<Writable>, Self> {
|
||||||
let mut map_info: ffi::GstMapInfo = unsafe { mem::zeroed() };
|
let mut map_info: ffi::GstMapInfo = unsafe { mem::zeroed() };
|
||||||
let res: bool = unsafe {
|
let res: bool = unsafe {
|
||||||
from_glib(ffi::gst_buffer_map(
|
from_glib(ffi::gst_buffer_map(
|
||||||
|
@ -137,9 +122,10 @@ impl GstRc<BufferRef> {
|
||||||
))
|
))
|
||||||
};
|
};
|
||||||
if res {
|
if res {
|
||||||
Ok(ReadWriteMappedBuffer {
|
Ok(MappedBuffer {
|
||||||
buffer: self,
|
buffer: Some(self),
|
||||||
map_info: map_info,
|
map_info: map_info,
|
||||||
|
phantom: PhantomData,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Err(self)
|
Err(self)
|
||||||
|
@ -152,29 +138,31 @@ impl GstRc<BufferRef> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BufferRef {
|
impl BufferRef {
|
||||||
pub fn map_read(&self) -> Option<ReadBufferMap> {
|
pub fn map_readable(&self) -> Option<BufferMap<Readable>> {
|
||||||
let mut map_info: ffi::GstMapInfo = unsafe { mem::zeroed() };
|
let mut map_info: ffi::GstMapInfo = unsafe { mem::zeroed() };
|
||||||
let res =
|
let res =
|
||||||
unsafe { ffi::gst_buffer_map(self.as_mut_ptr(), &mut map_info, ffi::GST_MAP_READ) };
|
unsafe { ffi::gst_buffer_map(self.as_mut_ptr(), &mut map_info, ffi::GST_MAP_READ) };
|
||||||
if res == glib_ffi::GTRUE {
|
if res == glib_ffi::GTRUE {
|
||||||
Some(ReadBufferMap {
|
Some(BufferMap {
|
||||||
buffer: self,
|
buffer: self,
|
||||||
map_info: map_info,
|
map_info: map_info,
|
||||||
|
phantom: PhantomData,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn map_readwrite(&mut self) -> Option<ReadWriteBufferMap> {
|
pub fn map_writable(&mut self) -> Option<BufferMap<Writable>> {
|
||||||
let mut map_info: ffi::GstMapInfo = unsafe { mem::zeroed() };
|
let mut map_info: ffi::GstMapInfo = unsafe { mem::zeroed() };
|
||||||
let res = unsafe {
|
let res = unsafe {
|
||||||
ffi::gst_buffer_map(self.as_mut_ptr(), &mut map_info, ffi::GST_MAP_READWRITE)
|
ffi::gst_buffer_map(self.as_mut_ptr(), &mut map_info, ffi::GST_MAP_READWRITE)
|
||||||
};
|
};
|
||||||
if res == glib_ffi::GTRUE {
|
if res == glib_ffi::GTRUE {
|
||||||
Some(ReadWriteBufferMap {
|
Some(BufferMap {
|
||||||
buffer: self,
|
buffer: self,
|
||||||
map_info: map_info,
|
map_info: map_info,
|
||||||
|
phantom: PhantomData,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -353,8 +341,8 @@ impl PartialEq for BufferRef {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let self_map = self.map_read();
|
let self_map = self.map_readable();
|
||||||
let other_map = other.map_read();
|
let other_map = other.map_readable();
|
||||||
|
|
||||||
match (self_map, other_map) {
|
match (self_map, other_map) {
|
||||||
(Some(self_map), Some(other_map)) => self_map.as_slice().eq(other_map.as_slice()),
|
(Some(self_map), Some(other_map)) => self_map.as_slice().eq(other_map.as_slice()),
|
||||||
|
@ -365,11 +353,7 @@ impl PartialEq for BufferRef {
|
||||||
|
|
||||||
impl Eq for BufferRef {}
|
impl Eq for BufferRef {}
|
||||||
|
|
||||||
impl<'a> ReadBufferMap<'a> {
|
impl<'a, T> BufferMap<'a, T> {
|
||||||
pub fn as_slice(&self) -> &[u8] {
|
|
||||||
unsafe { slice::from_raw_parts(self.map_info.data as *const u8, self.map_info.size) }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_size(&self) -> usize {
|
pub fn get_size(&self) -> usize {
|
||||||
self.map_info.size
|
self.map_info.size
|
||||||
}
|
}
|
||||||
|
@ -377,21 +361,27 @@ impl<'a> ReadBufferMap<'a> {
|
||||||
pub fn get_buffer(&self) -> &BufferRef {
|
pub fn get_buffer(&self) -> &BufferRef {
|
||||||
self.buffer
|
self.buffer
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Drop for ReadBufferMap<'a> {
|
pub fn as_slice(&self) -> &[u8] {
|
||||||
fn drop(&mut self) {
|
unsafe { slice::from_raw_parts(self.map_info.data as *const u8, self.map_info.size) }
|
||||||
unsafe {
|
|
||||||
ffi::gst_buffer_unmap(self.buffer.as_mut_ptr(), &mut self.map_info);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ReadWriteBufferMap<'a> {
|
impl<'a> BufferMap<'a, Writable> {
|
||||||
pub fn as_mut_slice(&mut self) -> &mut [u8] {
|
pub fn as_mut_slice(&mut self) -> &mut [u8] {
|
||||||
unsafe { slice::from_raw_parts_mut(self.map_info.data as *mut u8, self.map_info.size) }
|
unsafe { slice::from_raw_parts_mut(self.map_info.data as *mut u8, self.map_info.size) }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T> Drop for BufferMap<'a, T> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
ffi::gst_buffer_unmap(self.buffer.as_mut_ptr(), &mut self.map_info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> MappedBuffer<T> {
|
||||||
pub fn as_slice(&self) -> &[u8] {
|
pub fn as_slice(&self) -> &[u8] {
|
||||||
unsafe { slice::from_raw_parts(self.map_info.data as *const u8, self.map_info.size) }
|
unsafe { slice::from_raw_parts(self.map_info.data as *const u8, self.map_info.size) }
|
||||||
}
|
}
|
||||||
|
@ -401,70 +391,36 @@ impl<'a> ReadWriteBufferMap<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_buffer(&self) -> &BufferRef {
|
pub fn get_buffer(&self) -> &BufferRef {
|
||||||
self.buffer
|
self.buffer.as_ref().unwrap().as_ref()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Drop for ReadWriteBufferMap<'a> {
|
pub fn into_buffer(mut self) -> Buffer {
|
||||||
fn drop(&mut self) {
|
let buffer = self.buffer.take().unwrap();
|
||||||
unsafe {
|
unsafe {
|
||||||
ffi::gst_buffer_unmap(self.buffer.as_mut_ptr(), &mut self.map_info);
|
ffi::gst_buffer_unmap(buffer.as_mut_ptr(), &mut self.map_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buffer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReadMappedBuffer {
|
impl MappedBuffer<Writable> {
|
||||||
pub fn as_slice(&self) -> &[u8] {
|
|
||||||
unsafe { slice::from_raw_parts(self.map_info.data as *const u8, self.map_info.size) }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_size(&self) -> usize {
|
|
||||||
self.map_info.size
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_buffer(&self) -> &BufferRef {
|
|
||||||
self.buffer.as_ref()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for ReadMappedBuffer {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
unsafe {
|
|
||||||
ffi::gst_buffer_unmap(self.buffer.as_mut_ptr(), &mut self.map_info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl Sync for ReadMappedBuffer {}
|
|
||||||
unsafe impl Send for ReadMappedBuffer {}
|
|
||||||
|
|
||||||
impl ReadWriteMappedBuffer {
|
|
||||||
pub fn as_mut_slice(&mut self) -> &mut [u8] {
|
pub fn as_mut_slice(&mut self) -> &mut [u8] {
|
||||||
unsafe { slice::from_raw_parts_mut(self.map_info.data as *mut u8, self.map_info.size) }
|
unsafe { slice::from_raw_parts_mut(self.map_info.data as *mut u8, self.map_info.size) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_slice(&self) -> &[u8] {
|
|
||||||
unsafe { slice::from_raw_parts(self.map_info.data as *const u8, self.map_info.size) }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_size(&self) -> usize {
|
|
||||||
self.map_info.size
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_buffer(&self) -> &BufferRef {
|
|
||||||
self.buffer.as_ref()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for ReadWriteMappedBuffer {
|
impl<T> Drop for MappedBuffer<T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
if let Some(ref buffer) = self.buffer {
|
||||||
ffi::gst_buffer_unmap(self.buffer.as_mut_ptr(), &mut self.map_info);
|
unsafe {
|
||||||
|
ffi::gst_buffer_unmap(buffer.as_mut_ptr(), &mut self.map_info);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl Send for ReadWriteMappedBuffer {}
|
unsafe impl<T> Send for MappedBuffer<T> {}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
@ -497,7 +453,7 @@ mod tests {
|
||||||
|
|
||||||
let mut buffer = Buffer::from_vec(vec![1, 2, 3, 4]).unwrap();
|
let mut buffer = Buffer::from_vec(vec![1, 2, 3, 4]).unwrap();
|
||||||
{
|
{
|
||||||
let data = buffer.map_read().unwrap();
|
let data = buffer.map_readable().unwrap();
|
||||||
assert_eq!(data.as_slice(), vec![1, 2, 3, 4].as_slice());
|
assert_eq!(data.as_slice(), vec![1, 2, 3, 4].as_slice());
|
||||||
}
|
}
|
||||||
assert_ne!(buffer.get_mut(), None);
|
assert_ne!(buffer.get_mut(), None);
|
||||||
|
@ -521,7 +477,7 @@ mod tests {
|
||||||
|
|
||||||
buffer2.set_pts(2);
|
buffer2.set_pts(2);
|
||||||
|
|
||||||
let mut data = buffer2.map_readwrite().unwrap();
|
let mut data = buffer2.map_writable().unwrap();
|
||||||
assert_eq!(data.as_slice(), vec![1, 2, 3, 4].as_slice());
|
assert_eq!(data.as_slice(), vec![1, 2, 3, 4].as_slice());
|
||||||
data.as_mut_slice()[0] = 0;
|
data.as_mut_slice()[0] = 0;
|
||||||
}
|
}
|
||||||
|
@ -530,10 +486,10 @@ mod tests {
|
||||||
assert_eq!(buffer2.get_pts(), 2);
|
assert_eq!(buffer2.get_pts(), 2);
|
||||||
|
|
||||||
{
|
{
|
||||||
let data = buffer.map_read().unwrap();
|
let data = buffer.map_readable().unwrap();
|
||||||
assert_eq!(data.as_slice(), vec![1, 2, 3, 4].as_slice());
|
assert_eq!(data.as_slice(), vec![1, 2, 3, 4].as_slice());
|
||||||
|
|
||||||
let data = buffer2.map_read().unwrap();
|
let data = buffer2.map_readable().unwrap();
|
||||||
assert_eq!(data.as_slice(), vec![0, 2, 3, 4].as_slice());
|
assert_eq!(data.as_slice(), vec![0, 2, 3, 4].as_slice());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,8 +63,7 @@ pub use caps::{Caps, CapsRef};
|
||||||
pub mod tags;
|
pub mod tags;
|
||||||
pub use tags::*;
|
pub use tags::*;
|
||||||
pub mod buffer;
|
pub mod buffer;
|
||||||
pub use buffer::{Buffer, BufferRef, ReadBufferMap, ReadMappedBuffer, ReadWriteBufferMap,
|
pub use buffer::{Buffer, BufferMap, BufferRef, MappedBuffer};
|
||||||
ReadWriteMappedBuffer};
|
|
||||||
pub mod sample;
|
pub mod sample;
|
||||||
pub use sample::{Sample, SampleRef};
|
pub use sample::{Sample, SampleRef};
|
||||||
pub mod bufferlist;
|
pub mod bufferlist;
|
||||||
|
|
Loading…
Reference in a new issue