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:
authorSebastian Dröge <sebastian@centricular.com>2016-09-17 15:31:10 +0300
committerSebastian Dröge <sebastian@centricular.com>2016-09-18 17:23:14 +0300
commitb23385e88fc67c9391554fef49cc6a4e46746484 (patch)
treec578e3124af72c9e15265fe20124300b77db34b7
parent1ef938b6ec1e729d6e83b23c025d2142ba154089 (diff)
Add some more Buffer API and use explicit bitflags instead of magic numbers
-rw-r--r--Cargo.toml1
-rw-r--r--src/buffer.rs317
-rw-r--r--src/lib.rs2
-rw-r--r--src/plugin.c12
-rw-r--r--src/rsfilesrc.rs2
-rw-r--r--src/rshttpsrc.rs2
6 files changed, 329 insertions, 7 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 957d9112a..bd0e37c25 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -10,6 +10,7 @@ license = "LGPL-2.1+"
libc = "0.2"
url = "1.1"
hyper = "0.9"
+bitflags = "0.7"
[build-dependencies]
gcc = "0.3"
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,
+ }
+}
diff --git a/src/lib.rs b/src/lib.rs
index d9292d23b..094ef8986 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -21,6 +21,8 @@
extern crate libc;
extern crate url;
extern crate hyper;
+#[macro_use]
+extern crate bitflags;
#[macro_use]
pub mod utils;
diff --git a/src/plugin.c b/src/plugin.c
index dee832612..2a3f9e001 100644
--- a/src/plugin.c
+++ b/src/plugin.c
@@ -100,3 +100,15 @@ gst_rs_buffer_set_offset_end (GstBuffer * buffer, guint64 offset_end)
{
GST_BUFFER_OFFSET_END (buffer) = offset_end;
}
+
+GstBufferFlags
+gst_rs_buffer_get_buffer_flags (GstBuffer * buffer)
+{
+ return GST_MINI_OBJECT_FLAGS (buffer);
+}
+
+void
+gst_rs_buffer_set_buffer_flags (GstBuffer * buffer, GstBufferFlags flags)
+{
+ GST_MINI_OBJECT_FLAGS (buffer) = flags;
+}
diff --git a/src/rsfilesrc.rs b/src/rsfilesrc.rs
index dc07d2ce0..3bfacb8be 100644
--- a/src/rsfilesrc.rs
+++ b/src/rsfilesrc.rs
@@ -124,7 +124,7 @@ impl Source for FileSrc {
}
let size = {
- let map = match buffer.map_readwrite() {
+ let mut map = match buffer.map_readwrite() {
None => {
return Err(FlowError::Error(error_msg!(SourceError::Failure,
["Failed to map buffer"])));
diff --git a/src/rshttpsrc.rs b/src/rshttpsrc.rs
index b8447b4b6..bda289da9 100644
--- a/src/rshttpsrc.rs
+++ b/src/rshttpsrc.rs
@@ -205,7 +205,7 @@ impl Source for HttpSrc {
}
let size = {
- let map = match buffer.map_readwrite() {
+ let mut map = match buffer.map_readwrite() {
None => {
return Err(FlowError::Error(error_msg!(SourceError::Failure,
["Failed to map buffer"])));