Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/buffer.rs')
-rw-r--r--src/buffer.rs317
1 files changed, 312 insertions, 5 deletions
diff --git a/src/buffer.rs b/src/buffer.rs
index a661203fa..9bf6b11d9 100644
--- a/src/buffer.rs
+++ b/src/buffer.rs
@@ -22,6 +22,7 @@ use std::os::raw::c_void;
use std::slice;
use std::marker::PhantomData;
use std::u64;
+use std::usize;
use std::fmt::{Display, Formatter};
use std::fmt::Error as FmtError;
use std::error::Error;
@@ -29,12 +30,14 @@ use std::ops::{Deref, DerefMut};
use utils::*;
+#[derive(Debug)]
pub struct Buffer {
raw: *mut c_void,
owned: bool,
}
#[repr(C)]
+#[derive(Debug)]
struct GstMapInfo {
memory: *mut c_void,
flags: i32,
@@ -45,20 +48,35 @@ struct GstMapInfo {
_gst_reserved: [*const c_void; 4],
}
+#[derive(Debug)]
pub struct ReadBufferMap<'a> {
buffer: &'a Buffer,
map_info: GstMapInfo,
}
+#[derive(Debug)]
pub struct ReadWriteBufferMap<'a> {
buffer: &'a Buffer,
map_info: GstMapInfo,
}
#[derive(Debug)]
+pub struct ReadMappedBuffer {
+ buffer: Buffer,
+ map_info: GstMapInfo,
+}
+
+#[derive(Debug)]
+pub struct ReadWriteMappedBuffer {
+ buffer: Buffer,
+ map_info: GstMapInfo,
+}
+
+#[derive(Debug, PartialEq, Eq)]
pub enum BufferError {
NotWritable,
NotEnoughSpace,
+ Unknown,
}
impl Display for BufferError {
@@ -72,6 +90,7 @@ impl Error for BufferError {
match *self {
BufferError::NotWritable => "Not Writable",
BufferError::NotEnoughSpace => "Not Enough Space",
+ BufferError::Unknown => "Unknown",
}
}
}
@@ -101,6 +120,18 @@ impl Buffer {
}
}
+ pub fn new() -> Buffer {
+ extern "C" {
+ fn gst_buffer_new() -> *mut c_void;
+ }
+
+ let raw = unsafe { gst_buffer_new() };
+ Buffer {
+ raw: raw,
+ owned: true,
+ }
+ }
+
pub fn new_with_size(size: usize) -> Option<Buffer> {
extern "C" {
fn gst_buffer_new_allocate(allocator: *const c_void,
@@ -122,11 +153,15 @@ impl Buffer {
pub fn map_read(&self) -> Option<ReadBufferMap> {
extern "C" {
- fn gst_buffer_map(buffer: *mut c_void, map: *mut GstMapInfo, flags: i32) -> GBoolean;
+ fn gst_buffer_map(buffer: *mut c_void,
+ map: *mut GstMapInfo,
+ flags: MapFlags)
+ -> GBoolean;
}
let mut map_info: GstMapInfo = unsafe { mem::zeroed() };
- let res = unsafe { gst_buffer_map(self.raw, &mut map_info as *mut GstMapInfo, 1) };
+ let res =
+ unsafe { gst_buffer_map(self.raw, &mut map_info as *mut GstMapInfo, MAP_FLAG_READ) };
if res.to_bool() {
Some(ReadBufferMap {
buffer: self,
@@ -139,11 +174,18 @@ impl Buffer {
pub fn map_readwrite(&mut self) -> Option<ReadWriteBufferMap> {
extern "C" {
- fn gst_buffer_map(buffer: *mut c_void, map: *mut GstMapInfo, flags: i32) -> GBoolean;
+ fn gst_buffer_map(buffer: *mut c_void,
+ map: *mut GstMapInfo,
+ flags: MapFlags)
+ -> GBoolean;
}
let mut map_info: GstMapInfo = unsafe { mem::zeroed() };
- let res = unsafe { gst_buffer_map(self.raw, &mut map_info as *mut GstMapInfo, 3) };
+ let res = unsafe {
+ gst_buffer_map(self.raw,
+ &mut map_info as *mut GstMapInfo,
+ MAP_FLAG_READWRITE)
+ };
if res.to_bool() {
Some(ReadWriteBufferMap {
buffer: self,
@@ -154,6 +196,51 @@ impl Buffer {
}
}
+ pub fn into_read_mapped_buffer(self) -> Option<ReadMappedBuffer> {
+ extern "C" {
+ fn gst_buffer_map(buffer: *mut c_void,
+ map: *mut GstMapInfo,
+ flags: MapFlags)
+ -> GBoolean;
+ }
+
+ let mut map_info: GstMapInfo = unsafe { mem::zeroed() };
+ let res =
+ unsafe { gst_buffer_map(self.raw, &mut map_info as *mut GstMapInfo, MAP_FLAG_READ) };
+ if res.to_bool() {
+ Some(ReadMappedBuffer {
+ buffer: self,
+ map_info: map_info,
+ })
+ } else {
+ None
+ }
+ }
+
+ pub fn into_readwrite_mapped_buffer(self) -> Option<ReadWriteMappedBuffer> {
+ extern "C" {
+ fn gst_buffer_map(buffer: *mut c_void,
+ map: *mut GstMapInfo,
+ flags: MapFlags)
+ -> GBoolean;
+ }
+
+ let mut map_info: GstMapInfo = unsafe { mem::zeroed() };
+ let res = unsafe {
+ gst_buffer_map(self.raw,
+ &mut map_info as *mut GstMapInfo,
+ MAP_FLAG_READWRITE)
+ };
+ if res.to_bool() {
+ Some(ReadWriteMappedBuffer {
+ buffer: self,
+ map_info: map_info,
+ })
+ } else {
+ None
+ }
+ }
+
pub fn is_writable(&self) -> bool {
extern "C" {
fn gst_mini_object_is_writable(obj: *const c_void) -> GBoolean;
@@ -181,6 +268,101 @@ impl Buffer {
unsafe { Buffer::new_from_ptr(self.raw) }
}
+ pub fn append(self, other: Buffer) -> Buffer {
+ extern "C" {
+ fn gst_buffer_append(buf1: *mut c_void, buf2: *mut c_void) -> *mut c_void;
+ }
+
+ let raw = unsafe { gst_buffer_append(self.raw, other.raw) };
+
+ Buffer {
+ raw: raw,
+ owned: true,
+ }
+ }
+
+ pub fn copy_region(&self, offset: usize, size: Option<usize>) -> Option<Buffer> {
+ extern "C" {
+ fn gst_buffer_copy_region(buf: *mut c_void,
+ flags: BufferCopyFlags,
+ offset: usize,
+ size: usize)
+ -> *mut c_void;
+ }
+
+ let size_real = size.unwrap_or(usize::MAX);
+
+ let raw =
+ unsafe { gst_buffer_copy_region(self.raw, BUFFER_COPY_FLAG_ALL, offset, size_real) };
+
+ if raw.is_null() {
+ None
+ } else {
+ Some(Buffer {
+ raw: raw,
+ owned: true,
+ })
+ }
+ }
+
+ pub fn copy_from_slice(&mut self, offset: usize, slice: &[u8]) -> Result<(), BufferError> {
+ if !self.is_writable() {
+ return Err(BufferError::NotWritable);
+ }
+
+ let maxsize = self.get_maxsize();
+ let size = slice.len();
+ if maxsize < offset || maxsize - offset < size {
+ return Err(BufferError::NotEnoughSpace);
+ }
+
+ extern "C" {
+ fn gst_buffer_fill(buffer: *mut c_void,
+ offset: usize,
+ src: *const u8,
+ size: usize)
+ -> usize;
+ };
+
+ let copied = unsafe {
+ let src = slice.as_ptr();
+ gst_buffer_fill(self.raw, offset, src, size)
+ };
+
+ if copied < size {
+ Err(BufferError::Unknown)
+ } else {
+ Ok(())
+ }
+ }
+
+ pub fn copy_to_slice(&self, offset: usize, slice: &mut [u8]) -> Result<(), BufferError> {
+ let maxsize = self.get_size();
+ let size = slice.len();
+ if maxsize < offset || maxsize - offset < size {
+ return Err(BufferError::NotEnoughSpace);
+ }
+
+ extern "C" {
+ fn gst_buffer_extract(buffer: *mut c_void,
+ offset: usize,
+ src: *mut u8,
+ size: usize)
+ -> usize;
+ };
+
+ let copied = unsafe {
+ let src = slice.as_mut_ptr();
+ gst_buffer_extract(self.raw, offset, src, size)
+ };
+
+ if copied < size {
+ Err(BufferError::Unknown)
+ } else {
+ Ok(())
+ }
+ }
+
pub fn get_size(&self) -> usize {
extern "C" {
fn gst_buffer_get_size(obj: *const c_void) -> usize;
@@ -363,6 +545,30 @@ impl Buffer {
Ok(())
}
+
+ pub fn get_flags(&self) -> BufferFlags {
+ extern "C" {
+ fn gst_rs_buffer_get_flags(buf: *const c_void) -> BufferFlags;
+ }
+
+ unsafe { gst_rs_buffer_get_flags(self.raw) }
+ }
+
+ pub fn set_flags(&mut self, flags: BufferFlags) -> Result<(), BufferError> {
+ if !self.is_writable() {
+ return Err(BufferError::NotWritable);
+ }
+
+ extern "C" {
+ fn gst_rs_buffer_set_flags(buf: *const c_void, flags: BufferFlags);
+ }
+
+ unsafe {
+ gst_rs_buffer_set_flags(self.raw, flags);
+ }
+
+ Ok(())
+ }
}
impl Drop for Buffer {
@@ -415,7 +621,7 @@ impl<'a> Drop for ReadBufferMap<'a> {
}
impl<'a> ReadWriteBufferMap<'a> {
- pub fn as_mut_slice(&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) }
}
@@ -440,6 +646,62 @@ impl<'a> Drop for ReadWriteBufferMap<'a> {
}
}
+impl ReadMappedBuffer {
+ 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) -> &Buffer {
+ &self.buffer
+ }
+}
+
+impl Drop for ReadMappedBuffer {
+ fn drop(&mut self) {
+ extern "C" {
+ fn gst_buffer_unmap(buffer: *mut c_void, map: *mut GstMapInfo);
+ };
+
+ unsafe {
+ gst_buffer_unmap(self.buffer.raw, &mut self.map_info as *mut GstMapInfo);
+ }
+ }
+}
+
+impl ReadWriteMappedBuffer {
+ 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) }
+ }
+
+ 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) -> &Buffer {
+ &self.buffer
+ }
+}
+
+impl Drop for ReadWriteMappedBuffer {
+ fn drop(&mut self) {
+ extern "C" {
+ fn gst_buffer_unmap(buffer: *mut c_void, map: *mut GstMapInfo);
+ };
+
+ unsafe {
+ gst_buffer_unmap(self.buffer.raw, &mut self.map_info as *mut GstMapInfo);
+ }
+ }
+}
+
#[repr(C)]
pub struct ScopedBufferPtr(*mut c_void);
@@ -471,3 +733,48 @@ impl<'a> DerefMut for ScopedBuffer<'a> {
&mut self.buffer
}
}
+
+bitflags! {
+ #[repr(C)]
+ flags MapFlags: u32 {
+ const MAP_FLAG_READ = 0b00000001,
+ const MAP_FLAG_WRITE = 0b00000010,
+ const MAP_FLAG_READWRITE = MAP_FLAG_READ.bits
+ | MAP_FLAG_WRITE.bits,
+ }
+}
+
+bitflags! {
+ #[repr(C)]
+ pub flags BufferFlags: u32 {
+ const BUFFER_FLAG_LIVE = 0b0000000000010000,
+ const BUFFER_FLAG_DECODE_ONLY = 0b0000000000100000,
+ const BUFFER_FLAG_DISCONT = 0b0000000001000000,
+ const BUFFER_FLAG_RESYNC = 0b0000000010000000,
+ const BUFFER_FLAG_CORRUPTED = 0b0000000100000000,
+ const BUFFER_FLAG_MARKER = 0b0000001000000000,
+ const BUFFER_FLAG_HEADER = 0b0000010000000000,
+ const BUFFER_FLAG_GAP = 0b0000100000000000,
+ const BUFFER_FLAG_DROPPABLE = 0b0001000000000000,
+ const BUFFER_FLAG_DELTA_UNIT = 0b0010000000000000,
+ const BUFFER_FLAG_TAG_MEMORY = 0b0100000000000000,
+ const BUFFER_FLAG_SYNC_AFTER = 0b1000000000000000,
+ }
+}
+
+bitflags! {
+ #[repr(C)]
+ flags BufferCopyFlags: u32 {
+ const BUFFER_COPY_FLAG_FLAGS = 0b00000001,
+ const BUFFER_COPY_FLAG_TIMESTAMPS = 0b00000010,
+ const BUFFER_COPY_FLAG_META = 0b00000100,
+ const BUFFER_COPY_FLAG_MEMORY = 0b00001000,
+ const BUFFER_COPY_FLAG_MERGE = 0b00010000,
+ const BUFFER_COPY_FLAG_DEEP = 0b00100000,
+ const BUFFER_COPY_FLAG_METADATA = BUFFER_COPY_FLAG_FLAGS.bits
+ | BUFFER_COPY_FLAG_TIMESTAMPS.bits
+ | BUFFER_COPY_FLAG_META.bits,
+ const BUFFER_COPY_FLAG_ALL = BUFFER_COPY_FLAG_METADATA.bits
+ | BUFFER_COPY_FLAG_MEMORY.bits,
+ }
+}