Rewrite MiniObject bindings

These now use references were applicable and GstRef became useless
This commit is contained in:
Sebastian Dröge 2017-04-24 10:06:38 +01:00
parent 2232af41b6
commit 9b593136da
10 changed files with 175 additions and 225 deletions

View file

@ -8,6 +8,7 @@
use std::ptr; use std::ptr;
use std::mem; use std::mem;
use std::fmt;
use std::slice; use std::slice;
use std::u64; use std::u64;
use std::usize; use std::usize;
@ -17,8 +18,7 @@ use miniobject::*;
use glib; use glib;
use gst; use gst;
#[derive(Debug)] pub struct Buffer(gst::GstBuffer);
pub struct Buffer(*mut gst::GstBuffer);
#[derive(Derivative)] #[derive(Derivative)]
#[derivative(Debug)] #[derivative(Debug)]
@ -54,18 +54,6 @@ pub struct ReadWriteMappedBuffer {
unsafe impl MiniObject for Buffer { unsafe impl MiniObject for Buffer {
type PtrType = gst::GstBuffer; type PtrType = gst::GstBuffer;
unsafe fn as_ptr(&self) -> *mut gst::GstBuffer {
self.0
}
unsafe fn replace_ptr(&mut self, ptr: *mut gst::GstBuffer) {
self.0 = ptr
}
unsafe fn from_ptr(ptr: *mut gst::GstBuffer) -> Self {
Buffer(ptr)
}
} }
impl Buffer { impl Buffer {
@ -112,7 +100,11 @@ impl Buffer {
pub fn map_read(&self) -> Option<ReadBufferMap> { pub fn map_read(&self) -> Option<ReadBufferMap> {
let mut map_info: gst::GstMapInfo = unsafe { mem::zeroed() }; let mut map_info: gst::GstMapInfo = unsafe { mem::zeroed() };
let res = unsafe { gst::gst_buffer_map(self.0, &mut map_info, gst::GST_MAP_READ) }; let res = unsafe {
gst::gst_buffer_map(self.as_mut_ptr() as *mut gst::GstBuffer,
&mut map_info,
gst::GST_MAP_READ)
};
if res == glib::GTRUE { if res == glib::GTRUE {
Some(ReadBufferMap { Some(ReadBufferMap {
buffer: self, buffer: self,
@ -125,7 +117,9 @@ impl Buffer {
pub fn map_readwrite(&mut self) -> Option<ReadWriteBufferMap> { pub fn map_readwrite(&mut self) -> Option<ReadWriteBufferMap> {
let mut map_info: gst::GstMapInfo = unsafe { mem::zeroed() }; let mut map_info: gst::GstMapInfo = unsafe { mem::zeroed() };
let res = unsafe { gst::gst_buffer_map(self.0, &mut map_info, gst::GST_MAP_READWRITE) }; let res = unsafe {
gst::gst_buffer_map(self.as_mut_ptr(), &mut map_info, gst::GST_MAP_READWRITE)
};
if res == glib::GTRUE { if res == glib::GTRUE {
Some(ReadWriteBufferMap { Some(ReadWriteBufferMap {
buffer: self, buffer: self,
@ -138,7 +132,8 @@ impl Buffer {
pub fn into_read_mapped_buffer(buffer: GstRc<Buffer>) -> Option<ReadMappedBuffer> { pub fn into_read_mapped_buffer(buffer: GstRc<Buffer>) -> Option<ReadMappedBuffer> {
let mut map_info: gst::GstMapInfo = unsafe { mem::zeroed() }; let mut map_info: gst::GstMapInfo = unsafe { mem::zeroed() };
let res = unsafe { gst::gst_buffer_map(buffer.0, &mut map_info, gst::GST_MAP_READ) }; let res =
unsafe { gst::gst_buffer_map(buffer.as_mut_ptr(), &mut map_info, gst::GST_MAP_READ) };
if res == glib::GTRUE { if res == glib::GTRUE {
Some(ReadMappedBuffer { Some(ReadMappedBuffer {
buffer: buffer, buffer: buffer,
@ -151,7 +146,9 @@ impl Buffer {
pub fn into_readwrite_mapped_buffer(buffer: GstRc<Buffer>) -> Option<ReadWriteMappedBuffer> { pub fn into_readwrite_mapped_buffer(buffer: GstRc<Buffer>) -> Option<ReadWriteMappedBuffer> {
let mut map_info: gst::GstMapInfo = unsafe { mem::zeroed() }; let mut map_info: gst::GstMapInfo = unsafe { mem::zeroed() };
let res = unsafe { gst::gst_buffer_map(buffer.0, &mut map_info, gst::GST_MAP_READWRITE) }; let res = unsafe {
gst::gst_buffer_map(buffer.as_mut_ptr(), &mut map_info, gst::GST_MAP_READWRITE)
};
if res == glib::GTRUE { if res == glib::GTRUE {
Some(ReadWriteMappedBuffer { Some(ReadWriteMappedBuffer {
buffer: buffer, buffer: buffer,
@ -173,7 +170,10 @@ impl Buffer {
let size_real = size.unwrap_or(usize::MAX); let size_real = size.unwrap_or(usize::MAX);
let raw = unsafe { let raw = unsafe {
gst::gst_buffer_copy_region(self.0, gst::GST_BUFFER_COPY_ALL, offset, size_real) gst::gst_buffer_copy_region(self.as_mut_ptr(),
gst::GST_BUFFER_COPY_ALL,
offset,
size_real)
}; };
if raw.is_null() { if raw.is_null() {
@ -191,7 +191,7 @@ impl Buffer {
let copied = unsafe { let copied = unsafe {
let src = slice.as_ptr(); let src = slice.as_ptr();
gst::gst_buffer_fill(self.0, offset, src as glib::gconstpointer, size) gst::gst_buffer_fill(self.as_mut_ptr(), offset, src as glib::gconstpointer, size)
}; };
if copied == size { Ok(()) } else { Err(copied) } if copied == size { Ok(()) } else { Err(copied) }
@ -205,21 +205,21 @@ impl Buffer {
let copied = unsafe { let copied = unsafe {
let dest = slice.as_mut_ptr(); let dest = slice.as_mut_ptr();
gst::gst_buffer_extract(self.0, offset, dest as glib::gpointer, size) gst::gst_buffer_extract(self.as_mut_ptr(), offset, dest as glib::gpointer, size)
}; };
if copied == size { Ok(()) } else { Err(copied) } if copied == size { Ok(()) } else { Err(copied) }
} }
pub fn get_size(&self) -> usize { pub fn get_size(&self) -> usize {
unsafe { gst::gst_buffer_get_size(self.0) } unsafe { gst::gst_buffer_get_size(self.as_mut_ptr()) }
} }
pub fn get_maxsize(&self) -> usize { pub fn get_maxsize(&self) -> usize {
let mut maxsize: usize = 0; let mut maxsize: usize = 0;
unsafe { unsafe {
gst::gst_buffer_get_sizes_range(self.0, gst::gst_buffer_get_sizes_range(self.as_mut_ptr(),
0, 0,
-1, -1,
ptr::null_mut(), ptr::null_mut(),
@ -233,12 +233,12 @@ impl Buffer {
assert!(self.get_maxsize() >= size); assert!(self.get_maxsize() >= size);
unsafe { unsafe {
gst::gst_buffer_set_size(self.0, size as isize); gst::gst_buffer_set_size(self.as_mut_ptr(), size as isize);
} }
} }
pub fn get_offset(&self) -> Option<u64> { pub fn get_offset(&self) -> Option<u64> {
let offset = unsafe { (*self.0).offset }; let offset = self.0.offset;
if offset == u64::MAX { if offset == u64::MAX {
None None
@ -249,14 +249,11 @@ impl Buffer {
pub fn set_offset(&mut self, offset: Option<u64>) { pub fn set_offset(&mut self, offset: Option<u64>) {
let offset = offset.unwrap_or(u64::MAX); let offset = offset.unwrap_or(u64::MAX);
self.0.offset = offset;
unsafe {
(*self.0).offset = offset;
}
} }
pub fn get_offset_end(&self) -> Option<u64> { pub fn get_offset_end(&self) -> Option<u64> {
let offset_end = unsafe { (*self.0).offset_end }; let offset_end = self.0.offset_end;
if offset_end == u64::MAX { if offset_end == u64::MAX {
None None
@ -267,42 +264,33 @@ impl Buffer {
pub fn set_offset_end(&mut self, offset_end: Option<u64>) { pub fn set_offset_end(&mut self, offset_end: Option<u64>) {
let offset_end = offset_end.unwrap_or(u64::MAX); let offset_end = offset_end.unwrap_or(u64::MAX);
self.0.offset_end = offset_end;
unsafe {
(*self.0).offset_end = offset_end;
}
} }
pub fn get_pts(&self) -> Option<u64> { pub fn get_pts(&self) -> Option<u64> {
let pts = unsafe { (*self.0).pts }; let pts = self.0.pts;
if pts == u64::MAX { None } else { Some(pts) } if pts == u64::MAX { None } else { Some(pts) }
} }
pub fn set_pts(&mut self, pts: Option<u64>) { pub fn set_pts(&mut self, pts: Option<u64>) {
let pts = pts.unwrap_or(u64::MAX); let pts = pts.unwrap_or(u64::MAX);
self.0.pts = pts;
unsafe {
(*self.0).pts = pts;
}
} }
pub fn get_dts(&self) -> Option<u64> { pub fn get_dts(&self) -> Option<u64> {
let dts = unsafe { (*self.0).dts }; let dts = self.0.dts;
if dts == u64::MAX { None } else { Some(dts) } if dts == u64::MAX { None } else { Some(dts) }
} }
pub fn set_dts(&mut self, dts: Option<u64>) { pub fn set_dts(&mut self, dts: Option<u64>) {
let dts = dts.unwrap_or(u64::MAX); let dts = dts.unwrap_or(u64::MAX);
self.0.dts = dts;
unsafe {
(*self.0).dts = dts;
}
} }
pub fn get_duration(&self) -> Option<u64> { pub fn get_duration(&self) -> Option<u64> {
let duration = unsafe { (*self.0).duration }; let duration = self.0.duration;
if duration == u64::MAX { if duration == u64::MAX {
None None
@ -313,26 +301,27 @@ impl Buffer {
pub fn set_duration(&mut self, duration: Option<u64>) { pub fn set_duration(&mut self, duration: Option<u64>) {
let duration = duration.unwrap_or(u64::MAX); let duration = duration.unwrap_or(u64::MAX);
self.0.duration = duration;
unsafe {
(*self.0).duration = duration;
}
} }
pub fn get_flags(&self) -> BufferFlags { pub fn get_flags(&self) -> BufferFlags {
BufferFlags::from_bits_truncate(unsafe { (*self.0).mini_object.flags }) BufferFlags::from_bits_truncate(self.0.mini_object.flags)
} }
pub fn set_flags(&mut self, flags: BufferFlags) { pub fn set_flags(&mut self, flags: BufferFlags) {
unsafe { self.0.mini_object.flags = flags.bits();
(*self.0).mini_object.flags = flags.bits();
}
} }
} }
unsafe impl Sync for Buffer {} unsafe impl Sync for Buffer {}
unsafe impl Send for Buffer {} unsafe impl Send for Buffer {}
impl fmt::Debug for Buffer {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", unsafe { self.as_ptr() })
}
}
impl PartialEq for Buffer { impl PartialEq for Buffer {
fn eq(&self, other: &Buffer) -> bool { fn eq(&self, other: &Buffer) -> bool {
if self.get_size() != other.get_size() { if self.get_size() != other.get_size() {
@ -351,6 +340,14 @@ impl PartialEq for Buffer {
impl Eq for Buffer {} impl Eq for Buffer {}
impl ToOwned for Buffer {
type Owned = GstRc<Buffer>;
fn to_owned(&self) -> GstRc<Buffer> {
unsafe { GstRc::from_unowned_ptr(self.as_ptr()) }
}
}
impl<'a> ReadBufferMap<'a> { impl<'a> ReadBufferMap<'a> {
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) }
@ -368,7 +365,7 @@ impl<'a> ReadBufferMap<'a> {
impl<'a> Drop for ReadBufferMap<'a> { impl<'a> Drop for ReadBufferMap<'a> {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
gst::gst_buffer_unmap(self.buffer.0, &mut self.map_info); gst::gst_buffer_unmap(self.buffer.as_mut_ptr(), &mut self.map_info);
} }
} }
} }
@ -394,7 +391,7 @@ impl<'a> ReadWriteBufferMap<'a> {
impl<'a> Drop for ReadWriteBufferMap<'a> { impl<'a> Drop for ReadWriteBufferMap<'a> {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
gst::gst_buffer_unmap(self.buffer.0, &mut self.map_info); gst::gst_buffer_unmap(self.buffer.as_mut_ptr(), &mut self.map_info);
} }
} }
} }
@ -415,10 +412,8 @@ impl ReadMappedBuffer {
impl Drop for ReadMappedBuffer { impl Drop for ReadMappedBuffer {
fn drop(&mut self) { fn drop(&mut self) {
if !self.buffer.0.is_null() { unsafe {
unsafe { gst::gst_buffer_unmap(self.buffer.as_mut_ptr(), &mut self.map_info);
gst::gst_buffer_unmap(self.buffer.0, &mut self.map_info);
}
} }
} }
} }
@ -446,10 +441,8 @@ impl ReadWriteMappedBuffer {
impl Drop for ReadWriteMappedBuffer { impl Drop for ReadWriteMappedBuffer {
fn drop(&mut self) { fn drop(&mut self) {
if !self.buffer.0.is_null() { unsafe {
unsafe { gst::gst_buffer_unmap(self.buffer.as_mut_ptr(), &mut self.map_info);
gst::gst_buffer_unmap(self.buffer.0, &mut self.map_info);
}
} }
} }
} }

View file

@ -16,23 +16,11 @@ use structure::*;
use glib; use glib;
use gst; use gst;
#[derive(Eq)] #[repr(C)]
pub struct Caps(*mut gst::GstCaps); pub struct Caps(gst::GstCaps);
unsafe impl MiniObject for Caps { unsafe impl MiniObject for Caps {
type PtrType = gst::GstCaps; type PtrType = gst::GstCaps;
unsafe fn as_ptr(&self) -> *mut gst::GstCaps {
self.0
}
unsafe fn replace_ptr(&mut self, ptr: *mut gst::GstCaps) {
self.0 = ptr
}
unsafe fn from_ptr(ptr: *mut gst::GstCaps) -> Self {
Caps(ptr)
}
} }
impl Caps { impl Caps {
@ -51,7 +39,7 @@ impl Caps {
let structure = unsafe { gst::gst_structure_new_empty(name_cstr.as_ptr()) }; let structure = unsafe { gst::gst_structure_new_empty(name_cstr.as_ptr()) };
unsafe { unsafe {
gst::gst_caps_append_structure((*caps).0, structure); gst::gst_caps_append_structure(caps.as_mut_ptr(), structure);
} }
caps.get_mut().unwrap().set_simple(values); caps.get_mut().unwrap().set_simple(values);
@ -78,14 +66,14 @@ impl Caps {
let name_cstr = CString::new(value.0).unwrap(); let name_cstr = CString::new(value.0).unwrap();
unsafe { unsafe {
let gvalue = value.1.as_ptr(); let gvalue = value.1.as_ptr();
gst::gst_caps_set_value(self.0, name_cstr.as_ptr(), gvalue); gst::gst_caps_set_value(self.as_mut_ptr(), name_cstr.as_ptr(), gvalue);
} }
} }
} }
pub fn to_string(&self) -> String { pub fn to_string(&self) -> String {
unsafe { unsafe {
let ptr = gst::gst_caps_to_string(self.0); let ptr = gst::gst_caps_to_string(self.as_ptr());
let s = CStr::from_ptr(ptr).to_str().unwrap().into(); let s = CStr::from_ptr(ptr).to_str().unwrap().into();
glib::g_free(ptr as glib::gpointer); glib::g_free(ptr as glib::gpointer);
@ -95,14 +83,14 @@ impl Caps {
pub fn get_structure(&self, idx: u32) -> Option<&Structure> { pub fn get_structure(&self, idx: u32) -> Option<&Structure> {
unsafe { unsafe {
let structure = gst::gst_caps_get_structure(self.0, idx); let structure = gst::gst_caps_get_structure(self.as_ptr(), idx);
Structure::from_borrowed_ptr(structure as *mut gst::GstStructure) Structure::from_borrowed_ptr(structure as *const gst::GstStructure)
} }
} }
pub fn get_mut_structure(&mut self, idx: u32) -> Option<&mut Structure> { pub fn get_mut_structure(&mut self, idx: u32) -> Option<&mut Structure> {
unsafe { unsafe {
let structure = gst::gst_caps_get_structure(self.0, idx); let structure = gst::gst_caps_get_structure(self.as_ptr(), idx);
Structure::from_borrowed_mut_ptr(structure as *mut gst::GstStructure) Structure::from_borrowed_mut_ptr(structure as *mut gst::GstStructure)
} }
} }
@ -118,7 +106,17 @@ impl fmt::Debug for Caps {
impl PartialEq for Caps { impl PartialEq for Caps {
fn eq(&self, other: &Caps) -> bool { fn eq(&self, other: &Caps) -> bool {
(unsafe { gst::gst_caps_is_equal(self.0, other.0) } == glib::GTRUE) (unsafe { gst::gst_caps_is_equal(self.as_ptr(), other.as_ptr()) } == glib::GTRUE)
}
}
impl Eq for Caps {}
impl ToOwned for Caps {
type Owned = GstRc<Caps>;
fn to_owned(&self) -> GstRc<Caps> {
unsafe { GstRc::from_unowned_ptr(self.as_ptr()) }
} }
} }

View file

@ -321,7 +321,9 @@ impl DemuxerWrapper {
} }
HandleBufferResult::BufferForStream(index, buffer) => { HandleBufferResult::BufferForStream(index, buffer) => {
let flow_ret = unsafe { let flow_ret = unsafe {
gst_rs_demuxer_stream_push_buffer(self.raw, index, buffer.into_ptr()) gst_rs_demuxer_stream_push_buffer(self.raw,
index,
buffer.into_ptr() as *mut gst::GstBuffer)
}; };
if flow_ret != gst::GST_FLOW_OK { if flow_ret != gst::GST_FLOW_OK {
return flow_ret; return flow_ret;

View file

@ -6,21 +6,19 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use std::{fmt, ops, borrow, ptr}; use std::{fmt, ops, borrow};
use std::marker::PhantomData; use std::mem;
use glib; use glib;
use gst; use gst;
#[derive(Hash, Debug, PartialEq, Eq, PartialOrd, Ord)] #[derive(Hash, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct GstRc<T: MiniObject> { pub struct GstRc<T: 'static + MiniObject> {
obj: T, obj: &'static T,
} }
impl<T: MiniObject> GstRc<T> { impl<T: MiniObject> GstRc<T> {
unsafe fn new(obj: T, owned: bool) -> Self { unsafe fn new(obj: &'static T, owned: bool) -> Self {
assert!(!obj.as_ptr().is_null());
if !owned { if !owned {
gst::gst_mini_object_ref(obj.as_ptr() as *mut gst::GstMiniObject); gst::gst_mini_object_ref(obj.as_ptr() as *mut gst::GstMiniObject);
} }
@ -28,11 +26,11 @@ impl<T: MiniObject> GstRc<T> {
GstRc { obj: obj } GstRc { obj: obj }
} }
pub unsafe fn from_owned_ptr(ptr: *mut T::PtrType) -> Self { pub unsafe fn from_owned_ptr(ptr: *const T::PtrType) -> Self {
Self::new(T::from_ptr(ptr), true) Self::new(T::from_ptr(ptr), true)
} }
pub unsafe fn from_unowned_ptr(ptr: *mut T::PtrType) -> Self { pub unsafe fn from_unowned_ptr(ptr: *const T::PtrType) -> Self {
Self::new(T::from_ptr(ptr), false) Self::new(T::from_ptr(ptr), false)
} }
@ -41,21 +39,21 @@ impl<T: MiniObject> GstRc<T> {
let ptr = self.obj.as_ptr(); let ptr = self.obj.as_ptr();
if self.is_writable() { if self.is_writable() {
return &mut self.obj; return &mut *(self.obj as *const T as *mut T);
} }
self.obj self.obj = T::from_ptr(gst::gst_mini_object_make_writable(ptr as
.replace_ptr(gst::gst_mini_object_make_writable(ptr as *mut gst::GstMiniObject) as *mut gst::GstMiniObject) as
*mut T::PtrType); *const T::PtrType);
assert!(self.is_writable()); assert!(self.is_writable());
&mut self.obj &mut *(self.obj as *const T as *mut T)
} }
} }
pub fn get_mut(&mut self) -> Option<&mut T> { pub fn get_mut(&mut self) -> Option<&mut T> {
if self.is_writable() { if self.is_writable() {
Some(&mut self.obj) Some(unsafe { &mut *(self.obj as *const T as *mut T) })
} else { } else {
None None
} }
@ -65,7 +63,7 @@ impl<T: MiniObject> GstRc<T> {
unsafe { unsafe {
GstRc::from_owned_ptr(gst::gst_mini_object_copy(self.obj.as_ptr() as GstRc::from_owned_ptr(gst::gst_mini_object_copy(self.obj.as_ptr() as
*const gst::GstMiniObject) as *const gst::GstMiniObject) as
*mut T::PtrType) *const T::PtrType)
} }
} }
@ -75,30 +73,42 @@ impl<T: MiniObject> GstRc<T> {
} == glib::GTRUE) } == glib::GTRUE)
} }
pub unsafe fn into_ptr(mut self) -> *mut T::PtrType { pub unsafe fn into_ptr(self) -> *const T::PtrType {
self.obj.swap_ptr(ptr::null_mut()) let ptr = self.obj.as_ptr();
mem::forget(self);
ptr
} }
} }
impl<T: MiniObject> ops::Deref for GstRc<T> { impl<T: MiniObject> ops::Deref for GstRc<T> {
type Target = T; type Target = T;
fn deref(&self) -> &T { fn deref(&self) -> &T {
&self.obj self.obj
} }
} }
impl<T: MiniObject> AsRef<T> for GstRc<T> { impl<T: MiniObject> AsRef<T> for GstRc<T> {
fn as_ref(&self) -> &T { fn as_ref(&self) -> &T {
&self.obj self.obj
} }
} }
impl<T: MiniObject> borrow::Borrow<T> for GstRc<T> { impl<T: MiniObject> borrow::Borrow<T> for GstRc<T> {
fn borrow(&self) -> &T { fn borrow(&self) -> &T {
&self.obj self.obj
} }
} }
// FIXME: Not generally possible because neither T nor ToOwned are defined here...
//impl<T: MiniObject> ToOwned for T {
// type Owned = GstRc<T>;
//
// fn to_owned(&self) -> GstRc<T> {
// unsafe { GstRc::from_unowned_ptr(self.as_ptr()) }
// }
//}
impl<T: MiniObject> Clone for GstRc<T> { impl<T: MiniObject> Clone for GstRc<T> {
fn clone(&self) -> GstRc<T> { fn clone(&self) -> GstRc<T> {
unsafe { GstRc::from_unowned_ptr(self.obj.as_ptr()) } unsafe { GstRc::from_unowned_ptr(self.obj.as_ptr()) }
@ -108,9 +118,7 @@ impl<T: MiniObject> Clone for GstRc<T> {
impl<T: MiniObject> Drop for GstRc<T> { impl<T: MiniObject> Drop for GstRc<T> {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
if !self.obj.as_ptr().is_null() { gst::gst_mini_object_unref(self.obj.as_ptr() as *mut gst::GstMiniObject);
gst::gst_mini_object_unref(self.obj.as_ptr() as *mut gst::GstMiniObject);
}
} }
} }
} }
@ -124,20 +132,26 @@ impl<T: MiniObject + fmt::Display> fmt::Display for GstRc<T> {
} }
} }
// NOTE: Reference counting must not happen in here pub unsafe trait MiniObject
pub unsafe trait MiniObject { where Self: Sized
{
type PtrType; type PtrType;
unsafe fn as_ptr(&self) -> *mut Self::PtrType; unsafe fn as_ptr(&self) -> *const Self::PtrType {
unsafe fn replace_ptr(&mut self, ptr: *mut Self::PtrType); self as *const Self as *const Self::PtrType
unsafe fn swap_ptr(&mut self, new_ptr: *mut Self::PtrType) -> *mut Self::PtrType {
let ptr = self.as_ptr();
self.replace_ptr(new_ptr);
ptr
} }
unsafe fn from_ptr(ptr: *mut Self::PtrType) -> Self; unsafe fn as_mut_ptr(&self) -> *mut Self::PtrType {
self as *const Self as *mut Self::PtrType
}
unsafe fn from_ptr<'a>(ptr: *const Self::PtrType) -> &'a Self {
&*(ptr as *const Self)
}
unsafe fn from_mut_ptr<'a>(ptr: *mut Self::PtrType) -> &'a mut Self {
&mut *(ptr as *mut Self)
}
} }
impl<'a, T: MiniObject> From<&'a T> for GstRc<T> { impl<'a, T: MiniObject> From<&'a T> for GstRc<T> {
@ -151,70 +165,3 @@ impl<'a, T: MiniObject> From<&'a mut T> for GstRc<T> {
unsafe { GstRc::from_unowned_ptr(f.as_ptr()) } unsafe { GstRc::from_unowned_ptr(f.as_ptr()) }
} }
} }
#[derive(Hash, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct GstRef<'a, T: 'a + MiniObject> {
obj: T,
#[allow(dead_code)]
phantom: PhantomData<&'a T>,
}
impl<'a, T: MiniObject> GstRef<'a, T> {
pub unsafe fn new(ptr: *mut T::PtrType) -> GstRef<'a, T> {
GstRef {
obj: T::from_ptr(ptr),
phantom: PhantomData,
}
}
pub fn get_mut(&mut self) -> Option<&mut T> {
if self.is_writable() {
Some(&mut self.obj)
} else {
None
}
}
pub fn copy(&self) -> GstRc<T> {
unsafe {
GstRc::from_owned_ptr(gst::gst_mini_object_copy(self.obj.as_ptr() as
*const gst::GstMiniObject) as
*mut T::PtrType)
}
}
fn is_writable(&self) -> bool {
(unsafe {
gst::gst_mini_object_is_writable(self.as_ptr() as *const gst::GstMiniObject)
} == glib::GTRUE)
}
pub unsafe fn into_ptr(mut self) -> *mut T::PtrType {
self.obj.swap_ptr(ptr::null_mut())
}
}
impl<'a, T: MiniObject> ops::Deref for GstRef<'a, T> {
type Target = T;
fn deref(&self) -> &T {
&self.obj
}
}
impl<'a, T: MiniObject> AsRef<T> for GstRef<'a, T> {
fn as_ref(&self) -> &T {
&self.obj
}
}
impl<'a, T: MiniObject> borrow::Borrow<T> for GstRef<'a, T> {
fn borrow(&self) -> &T {
&self.obj
}
}
impl<'a, T: MiniObject + fmt::Display> fmt::Display for GstRef<'a, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.obj.fmt(f)
}
}

View file

@ -271,10 +271,10 @@ unsafe extern "C" fn sink_render(ptr: *mut gst_base::GstBaseSink,
-> gst::GstFlowReturn { -> gst::GstFlowReturn {
let sink = &*(ptr as *const RsSink); let sink = &*(ptr as *const RsSink);
let wrap: &SinkWrapper = &*sink.wrap; let wrap: &SinkWrapper = &*sink.wrap;
let buffer: &Buffer = Buffer::from_ptr(buffer);
panic_to_error!(wrap, gst::GST_FLOW_ERROR, { panic_to_error!(wrap, gst::GST_FLOW_ERROR, {
let buffer: GstRef<Buffer> = GstRef::new(buffer); wrap.render(buffer)
wrap.render(buffer.as_ref())
}) })
} }
@ -389,7 +389,7 @@ unsafe extern "C" fn sink_class_init(klass: glib::gpointer, klass_data: glib::gp
let pad_template = gst::gst_pad_template_new(templ_name.into_raw(), let pad_template = gst::gst_pad_template_new(templ_name.into_raw(),
gst::GST_PAD_SINK, gst::GST_PAD_SINK,
gst::GST_PAD_ALWAYS, gst::GST_PAD_ALWAYS,
caps.as_ptr()); caps.as_ptr() as *mut gst::GstCaps);
gst::gst_element_class_add_pad_template(element_klass, pad_template); gst::gst_element_class_add_pad_template(element_klass, pad_template);
} }

View file

@ -330,10 +330,10 @@ unsafe extern "C" fn source_fill(ptr: *mut gst_base::GstBaseSrc,
-> gst::GstFlowReturn { -> gst::GstFlowReturn {
let src = &*(ptr as *const RsSrc); let src = &*(ptr as *const RsSrc);
let wrap: &SourceWrapper = &*src.wrap; let wrap: &SourceWrapper = &*src.wrap;
let buffer: &mut Buffer = <Buffer as MiniObject>::from_mut_ptr(buffer);
panic_to_error!(wrap, gst::GST_FLOW_ERROR, { panic_to_error!(wrap, gst::GST_FLOW_ERROR, {
let mut buffer: GstRef<Buffer> = GstRef::new(buffer); wrap.fill(offset, length, buffer)
wrap.fill(offset, length, buffer.get_mut().unwrap())
}) })
} }
@ -468,7 +468,7 @@ unsafe extern "C" fn source_class_init(klass: glib::gpointer, klass_data: glib::
let pad_template = gst::gst_pad_template_new(templ_name.into_raw(), let pad_template = gst::gst_pad_template_new(templ_name.into_raw(),
gst::GST_PAD_SRC, gst::GST_PAD_SRC,
gst::GST_PAD_ALWAYS, gst::GST_PAD_ALWAYS,
caps.as_ptr()); caps.as_ptr() as *mut gst::GstCaps);
gst::gst_element_class_add_pad_template(element_klass, pad_template); gst::gst_element_class_add_pad_template(element_klass, pad_template);
} }

View file

@ -45,7 +45,7 @@ impl Stream {
flags: StreamFlags) flags: StreamFlags)
-> Self { -> Self {
let stream_id_cstr = CString::new(stream_id).unwrap(); let stream_id_cstr = CString::new(stream_id).unwrap();
let caps = caps.map(|caps| unsafe { caps.as_ptr() }) let caps = caps.map(|caps| unsafe { caps.as_mut_ptr() })
.unwrap_or(ptr::null_mut()); .unwrap_or(ptr::null_mut());
Stream(unsafe { Stream(unsafe {
@ -60,14 +60,14 @@ impl Stream {
self.0 self.0
} }
pub fn get_caps(&self) -> Option<GstRc<Caps>> { pub fn get_caps(&self) -> Option<&Caps> {
let ptr = unsafe { gst::gst_stream_get_caps(self.0) }; let ptr = unsafe { gst::gst_stream_get_caps(self.0) };
if ptr.is_null() { if ptr.is_null() {
return None; return None;
} }
Some(unsafe { GstRc::from_owned_ptr(ptr) }) Some(unsafe { <Caps as MiniObject>::from_ptr(ptr) })
} }
pub fn get_stream_flags(&self) -> StreamFlags { pub fn get_stream_flags(&self) -> StreamFlags {
@ -83,18 +83,18 @@ impl Stream {
cstr.to_str().unwrap() cstr.to_str().unwrap()
} }
pub fn get_tags(&self) -> Option<TagList> { pub fn get_tags(&self) -> Option<&TagList> {
let ptr = unsafe { gst::gst_stream_get_tags(self.0) }; let ptr = unsafe { gst::gst_stream_get_tags(self.0) };
if ptr.is_null() { if ptr.is_null() {
return None; return None;
} }
Some(unsafe { TagList::from_ptr(ptr) }) Some(unsafe { <TagList as MiniObject>::from_ptr(ptr) })
} }
pub fn set_caps(&self, caps: Option<GstRc<Caps>>) { pub fn set_caps(&self, caps: Option<GstRc<Caps>>) {
let ptr = caps.map(|caps| unsafe { caps.as_ptr() }) let ptr = caps.map(|caps| unsafe { caps.as_mut_ptr() })
.unwrap_or(ptr::null_mut()); .unwrap_or(ptr::null_mut());
unsafe { gst::gst_stream_set_caps(self.0, ptr) } unsafe { gst::gst_stream_set_caps(self.0, ptr) }
@ -109,7 +109,7 @@ impl Stream {
} }
pub fn set_tags(&self, tags: Option<TagList>) { pub fn set_tags(&self, tags: Option<TagList>) {
let ptr = tags.map(|tags| unsafe { tags.as_ptr() }) let ptr = tags.map(|tags| unsafe { tags.as_mut_ptr() })
.unwrap_or(ptr::null_mut()); .unwrap_or(ptr::null_mut());
unsafe { gst::gst_stream_set_tags(self.0, ptr) } unsafe { gst::gst_stream_set_tags(self.0, ptr) }

View file

@ -8,6 +8,7 @@
use std::fmt; use std::fmt;
use std::ptr; use std::ptr;
use std::mem;
use std::ffi::{CStr, CString}; use std::ffi::{CStr, CString};
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
use std::borrow::{Borrow, ToOwned, BorrowMut}; use std::borrow::{Borrow, ToOwned, BorrowMut};
@ -15,7 +16,6 @@ use std::borrow::{Borrow, ToOwned, BorrowMut};
use value::*; use value::*;
use glib; use glib;
use gobject;
use gst; use gst;
pub struct OwnedStructure(&'static mut Structure); pub struct OwnedStructure(&'static mut Structure);
@ -32,7 +32,7 @@ impl OwnedStructure {
pub fn new(name: &str, values: &[(&str, Value)]) -> OwnedStructure { pub fn new(name: &str, values: &[(&str, Value)]) -> OwnedStructure {
let mut structure = OwnedStructure::new_empty(name); let mut structure = OwnedStructure::new_empty(name);
for &(ref f, ref v) in values { for &(f, ref v) in values {
structure.set(f, v.clone()); structure.set(f, v.clone());
} }
@ -50,6 +50,13 @@ impl OwnedStructure {
} }
} }
} }
pub unsafe fn into_ptr(self) -> *const gst::GstStructure {
let ptr = self.0 as *const Structure as *const gst::GstStructure;
mem::forget(self);
ptr
}
} }
impl Deref for OwnedStructure { impl Deref for OwnedStructure {
@ -186,7 +193,7 @@ impl Structure {
let mut gvalue = value.into().into_raw(); let mut gvalue = value.into().into_raw();
gst::gst_structure_take_value(&mut self.0, name_cstr.as_ptr(), &mut gvalue); gst::gst_structure_take_value(&mut self.0, name_cstr.as_ptr(), &mut gvalue);
gvalue.g_type = gobject::G_TYPE_NONE; mem::forget(gvalue);
} }
} }

View file

@ -69,23 +69,10 @@ impl MergeMode {
} }
} }
#[derive(Eq)] pub struct TagList(gst::GstTagList);
pub struct TagList(*mut gst::GstTagList);
unsafe impl MiniObject for TagList { unsafe impl MiniObject for TagList {
type PtrType = gst::GstTagList; type PtrType = gst::GstTagList;
unsafe fn as_ptr(&self) -> *mut gst::GstTagList {
self.0
}
unsafe fn replace_ptr(&mut self, ptr: *mut gst::GstTagList) {
self.0 = ptr
}
unsafe fn from_ptr(ptr: *mut gst::GstTagList) -> Self {
TagList(ptr)
}
} }
impl TagList { impl TagList {
@ -101,7 +88,10 @@ impl TagList {
let mut gvalue = v.into_raw(); let mut gvalue = v.into_raw();
let tag_name = CString::new(T::tag_name()).unwrap(); let tag_name = CString::new(T::tag_name()).unwrap();
gst::gst_tag_list_add_value(self.0, mode.to_ffi(), tag_name.as_ptr(), &gvalue); gst::gst_tag_list_add_value(self.as_mut_ptr(),
mode.to_ffi(),
tag_name.as_ptr(),
&gvalue);
gobject::g_value_unset(&mut gvalue); gobject::g_value_unset(&mut gvalue);
} }
@ -112,7 +102,7 @@ impl TagList {
let mut gvalue = mem::zeroed(); let mut gvalue = mem::zeroed();
let tag_name = CString::new(T::tag_name()).unwrap(); let tag_name = CString::new(T::tag_name()).unwrap();
let found = gst::gst_tag_list_copy_value(&mut gvalue, self.0, tag_name.as_ptr()); let found = gst::gst_tag_list_copy_value(&mut gvalue, self.as_ptr(), tag_name.as_ptr());
if found == glib::GFALSE { if found == glib::GFALSE {
return None; return None;
@ -126,7 +116,7 @@ impl TagList {
unsafe { unsafe {
let tag_name = CString::new(T::tag_name()).unwrap(); let tag_name = CString::new(T::tag_name()).unwrap();
let value = gst::gst_tag_list_get_value_index(self.0, tag_name.as_ptr(), idx); let value = gst::gst_tag_list_get_value_index(self.as_ptr(), tag_name.as_ptr(), idx);
if value.is_null() { if value.is_null() {
return None; return None;
@ -140,7 +130,7 @@ impl TagList {
unsafe { unsafe {
let tag_name = CString::new(T::tag_name()).unwrap(); let tag_name = CString::new(T::tag_name()).unwrap();
gst::gst_tag_list_get_tag_size(self.0, tag_name.as_ptr()) gst::gst_tag_list_get_tag_size(self.as_ptr(), tag_name.as_ptr())
} }
} }
@ -150,7 +140,7 @@ impl TagList {
pub fn to_string(&self) -> String { pub fn to_string(&self) -> String {
unsafe { unsafe {
let ptr = gst::gst_tag_list_to_string(self.0); let ptr = gst::gst_tag_list_to_string(self.as_ptr());
let s = CStr::from_ptr(ptr).to_str().unwrap().into(); let s = CStr::from_ptr(ptr).to_str().unwrap().into();
glib::g_free(ptr as glib::gpointer); glib::g_free(ptr as glib::gpointer);
@ -167,7 +157,17 @@ impl fmt::Debug for TagList {
impl PartialEq for TagList { impl PartialEq for TagList {
fn eq(&self, other: &TagList) -> bool { fn eq(&self, other: &TagList) -> bool {
(unsafe { gst::gst_tag_list_is_equal(self.0, other.0) } == glib::GTRUE) (unsafe { gst::gst_tag_list_is_equal(self.as_ptr(), other.as_ptr()) } == glib::GTRUE)
}
}
impl Eq for TagList {}
impl ToOwned for TagList {
type Owned = GstRc<TagList>;
fn to_owned(&self) -> GstRc<TagList> {
unsafe { GstRc::from_unowned_ptr(self.as_ptr()) }
} }
} }

View file

@ -89,7 +89,10 @@ impl Value {
} }
pub unsafe fn into_raw(mut self) -> gobject::GValue { pub unsafe fn into_raw(mut self) -> gobject::GValue {
mem::replace(&mut self.0, mem::zeroed()) let v = mem::replace(&mut self.0, mem::zeroed());
mem::forget(self);
v
} }
fn is_supported_type(typ: glib::GType) -> bool { fn is_supported_type(typ: glib::GType) -> bool {
@ -495,11 +498,11 @@ impl<'a> From<Cow<'a, [Value]>> for Value {
} }
} }
Cow::Owned(array) => { Cow::Owned(array) => {
for mut e in array { for e in array {
gst::gst_value_array_append_and_take_value(&mut value.0, gst::gst_value_array_append_and_take_value(&mut value.0,
e.as_ptr() as e.as_ptr() as
*mut gobject::GValue); *mut gobject::GValue);
e.0.g_type = gobject::G_TYPE_NONE; mem::forget(e);
} }
} }
} }