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::mem;
use std::fmt;
use std::slice;
use std::u64;
use std::usize;
@ -17,8 +18,7 @@ use miniobject::*;
use glib;
use gst;
#[derive(Debug)]
pub struct Buffer(*mut gst::GstBuffer);
pub struct Buffer(gst::GstBuffer);
#[derive(Derivative)]
#[derivative(Debug)]
@ -54,18 +54,6 @@ pub struct ReadWriteMappedBuffer {
unsafe impl MiniObject for Buffer {
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 {
@ -112,7 +100,11 @@ impl Buffer {
pub fn map_read(&self) -> Option<ReadBufferMap> {
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 {
Some(ReadBufferMap {
buffer: self,
@ -125,7 +117,9 @@ impl Buffer {
pub fn map_readwrite(&mut self) -> Option<ReadWriteBufferMap> {
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 {
Some(ReadWriteBufferMap {
buffer: self,
@ -138,7 +132,8 @@ impl Buffer {
pub fn into_read_mapped_buffer(buffer: GstRc<Buffer>) -> Option<ReadMappedBuffer> {
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 {
Some(ReadMappedBuffer {
buffer: buffer,
@ -151,7 +146,9 @@ impl Buffer {
pub fn into_readwrite_mapped_buffer(buffer: GstRc<Buffer>) -> Option<ReadWriteMappedBuffer> {
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 {
Some(ReadWriteMappedBuffer {
buffer: buffer,
@ -173,7 +170,10 @@ impl Buffer {
let size_real = size.unwrap_or(usize::MAX);
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() {
@ -191,7 +191,7 @@ impl Buffer {
let copied = unsafe {
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) }
@ -205,21 +205,21 @@ impl Buffer {
let copied = unsafe {
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) }
}
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 {
let mut maxsize: usize = 0;
unsafe {
gst::gst_buffer_get_sizes_range(self.0,
gst::gst_buffer_get_sizes_range(self.as_mut_ptr(),
0,
-1,
ptr::null_mut(),
@ -233,12 +233,12 @@ impl Buffer {
assert!(self.get_maxsize() >= size);
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> {
let offset = unsafe { (*self.0).offset };
let offset = self.0.offset;
if offset == u64::MAX {
None
@ -249,14 +249,11 @@ impl Buffer {
pub fn set_offset(&mut self, offset: Option<u64>) {
let offset = offset.unwrap_or(u64::MAX);
unsafe {
(*self.0).offset = offset;
}
self.0.offset = offset;
}
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 {
None
@ -267,42 +264,33 @@ impl Buffer {
pub fn set_offset_end(&mut self, offset_end: Option<u64>) {
let offset_end = offset_end.unwrap_or(u64::MAX);
unsafe {
(*self.0).offset_end = offset_end;
}
self.0.offset_end = offset_end;
}
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) }
}
pub fn set_pts(&mut self, pts: Option<u64>) {
let pts = pts.unwrap_or(u64::MAX);
unsafe {
(*self.0).pts = pts;
}
self.0.pts = pts;
}
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) }
}
pub fn set_dts(&mut self, dts: Option<u64>) {
let dts = dts.unwrap_or(u64::MAX);
unsafe {
(*self.0).dts = dts;
}
self.0.dts = dts;
}
pub fn get_duration(&self) -> Option<u64> {
let duration = unsafe { (*self.0).duration };
let duration = self.0.duration;
if duration == u64::MAX {
None
@ -313,26 +301,27 @@ impl Buffer {
pub fn set_duration(&mut self, duration: Option<u64>) {
let duration = duration.unwrap_or(u64::MAX);
unsafe {
(*self.0).duration = duration;
}
self.0.duration = duration;
}
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) {
unsafe {
(*self.0).mini_object.flags = flags.bits();
}
self.0.mini_object.flags = flags.bits();
}
}
unsafe impl Sync 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 {
fn eq(&self, other: &Buffer) -> bool {
if self.get_size() != other.get_size() {
@ -351,6 +340,14 @@ impl PartialEq 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> {
pub fn as_slice(&self) -> &[u8] {
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> {
fn drop(&mut self) {
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> {
fn drop(&mut self) {
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 {
fn drop(&mut self) {
if !self.buffer.0.is_null() {
unsafe {
gst::gst_buffer_unmap(self.buffer.0, &mut self.map_info);
}
unsafe {
gst::gst_buffer_unmap(self.buffer.as_mut_ptr(), &mut self.map_info);
}
}
}
@ -446,10 +441,8 @@ impl ReadWriteMappedBuffer {
impl Drop for ReadWriteMappedBuffer {
fn drop(&mut self) {
if !self.buffer.0.is_null() {
unsafe {
gst::gst_buffer_unmap(self.buffer.0, &mut self.map_info);
}
unsafe {
gst::gst_buffer_unmap(self.buffer.as_mut_ptr(), &mut self.map_info);
}
}
}

View file

@ -16,23 +16,11 @@ use structure::*;
use glib;
use gst;
#[derive(Eq)]
pub struct Caps(*mut gst::GstCaps);
#[repr(C)]
pub struct Caps(gst::GstCaps);
unsafe impl MiniObject for Caps {
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 {
@ -51,7 +39,7 @@ impl Caps {
let structure = unsafe { gst::gst_structure_new_empty(name_cstr.as_ptr()) };
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);
@ -78,14 +66,14 @@ impl Caps {
let name_cstr = CString::new(value.0).unwrap();
unsafe {
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 {
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();
glib::g_free(ptr as glib::gpointer);
@ -95,14 +83,14 @@ impl Caps {
pub fn get_structure(&self, idx: u32) -> Option<&Structure> {
unsafe {
let structure = gst::gst_caps_get_structure(self.0, idx);
Structure::from_borrowed_ptr(structure as *mut gst::GstStructure)
let structure = gst::gst_caps_get_structure(self.as_ptr(), idx);
Structure::from_borrowed_ptr(structure as *const gst::GstStructure)
}
}
pub fn get_mut_structure(&mut self, idx: u32) -> Option<&mut Structure> {
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)
}
}
@ -118,7 +106,17 @@ impl fmt::Debug for Caps {
impl PartialEq for Caps {
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) => {
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 {
return flow_ret;

View file

@ -6,21 +6,19 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use std::{fmt, ops, borrow, ptr};
use std::marker::PhantomData;
use std::{fmt, ops, borrow};
use std::mem;
use glib;
use gst;
#[derive(Hash, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct GstRc<T: MiniObject> {
obj: T,
pub struct GstRc<T: 'static + MiniObject> {
obj: &'static T,
}
impl<T: MiniObject> GstRc<T> {
unsafe fn new(obj: T, owned: bool) -> Self {
assert!(!obj.as_ptr().is_null());
unsafe fn new(obj: &'static T, owned: bool) -> Self {
if !owned {
gst::gst_mini_object_ref(obj.as_ptr() as *mut gst::GstMiniObject);
}
@ -28,11 +26,11 @@ impl<T: MiniObject> GstRc<T> {
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)
}
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)
}
@ -41,21 +39,21 @@ impl<T: MiniObject> GstRc<T> {
let ptr = self.obj.as_ptr();
if self.is_writable() {
return &mut self.obj;
return &mut *(self.obj as *const T as *mut T);
}
self.obj
.replace_ptr(gst::gst_mini_object_make_writable(ptr as *mut gst::GstMiniObject) as
*mut T::PtrType);
self.obj = T::from_ptr(gst::gst_mini_object_make_writable(ptr as
*mut gst::GstMiniObject) as
*const T::PtrType);
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> {
if self.is_writable() {
Some(&mut self.obj)
Some(unsafe { &mut *(self.obj as *const T as *mut T) })
} else {
None
}
@ -65,7 +63,7 @@ impl<T: MiniObject> GstRc<T> {
unsafe {
GstRc::from_owned_ptr(gst::gst_mini_object_copy(self.obj.as_ptr() as
*const gst::GstMiniObject) as
*mut T::PtrType)
*const T::PtrType)
}
}
@ -75,30 +73,42 @@ impl<T: MiniObject> GstRc<T> {
} == glib::GTRUE)
}
pub unsafe fn into_ptr(mut self) -> *mut T::PtrType {
self.obj.swap_ptr(ptr::null_mut())
pub unsafe fn into_ptr(self) -> *const T::PtrType {
let ptr = self.obj.as_ptr();
mem::forget(self);
ptr
}
}
impl<T: MiniObject> ops::Deref for GstRc<T> {
type Target = T;
fn deref(&self) -> &T {
&self.obj
self.obj
}
}
impl<T: MiniObject> AsRef<T> for GstRc<T> {
fn as_ref(&self) -> &T {
&self.obj
self.obj
}
}
impl<T: MiniObject> borrow::Borrow<T> for GstRc<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> {
fn clone(&self) -> GstRc<T> {
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> {
fn drop(&mut self) {
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;
unsafe fn as_ptr(&self) -> *mut Self::PtrType;
unsafe fn replace_ptr(&mut self, ptr: *mut 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 as_ptr(&self) -> *const Self::PtrType {
self as *const Self as *const Self::PtrType
}
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> {
@ -151,70 +165,3 @@ impl<'a, T: MiniObject> From<&'a mut T> for GstRc<T> {
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 {
let sink = &*(ptr as *const RsSink);
let wrap: &SinkWrapper = &*sink.wrap;
let buffer: &Buffer = Buffer::from_ptr(buffer);
panic_to_error!(wrap, gst::GST_FLOW_ERROR, {
let buffer: GstRef<Buffer> = GstRef::new(buffer);
wrap.render(buffer.as_ref())
wrap.render(buffer)
})
}
@ -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(),
gst::GST_PAD_SINK,
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);
}

View file

@ -330,10 +330,10 @@ unsafe extern "C" fn source_fill(ptr: *mut gst_base::GstBaseSrc,
-> gst::GstFlowReturn {
let src = &*(ptr as *const RsSrc);
let wrap: &SourceWrapper = &*src.wrap;
let buffer: &mut Buffer = <Buffer as MiniObject>::from_mut_ptr(buffer);
panic_to_error!(wrap, gst::GST_FLOW_ERROR, {
let mut buffer: GstRef<Buffer> = GstRef::new(buffer);
wrap.fill(offset, length, buffer.get_mut().unwrap())
wrap.fill(offset, length, buffer)
})
}
@ -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(),
gst::GST_PAD_SRC,
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);
}

View file

@ -45,7 +45,7 @@ impl Stream {
flags: StreamFlags)
-> Self {
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());
Stream(unsafe {
@ -60,14 +60,14 @@ impl Stream {
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) };
if ptr.is_null() {
return None;
}
Some(unsafe { GstRc::from_owned_ptr(ptr) })
Some(unsafe { <Caps as MiniObject>::from_ptr(ptr) })
}
pub fn get_stream_flags(&self) -> StreamFlags {
@ -83,18 +83,18 @@ impl Stream {
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) };
if ptr.is_null() {
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>>) {
let ptr = caps.map(|caps| unsafe { caps.as_ptr() })
let ptr = caps.map(|caps| unsafe { caps.as_mut_ptr() })
.unwrap_or(ptr::null_mut());
unsafe { gst::gst_stream_set_caps(self.0, ptr) }
@ -109,7 +109,7 @@ impl Stream {
}
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());
unsafe { gst::gst_stream_set_tags(self.0, ptr) }

View file

@ -8,6 +8,7 @@
use std::fmt;
use std::ptr;
use std::mem;
use std::ffi::{CStr, CString};
use std::ops::{Deref, DerefMut};
use std::borrow::{Borrow, ToOwned, BorrowMut};
@ -15,7 +16,6 @@ use std::borrow::{Borrow, ToOwned, BorrowMut};
use value::*;
use glib;
use gobject;
use gst;
pub struct OwnedStructure(&'static mut Structure);
@ -32,7 +32,7 @@ impl OwnedStructure {
pub fn new(name: &str, values: &[(&str, Value)]) -> OwnedStructure {
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());
}
@ -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 {
@ -186,7 +193,7 @@ impl Structure {
let mut gvalue = value.into().into_raw();
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(*mut gst::GstTagList);
pub struct TagList(gst::GstTagList);
unsafe impl MiniObject for TagList {
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 {
@ -101,7 +88,10 @@ impl TagList {
let mut gvalue = v.into_raw();
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);
}
@ -112,7 +102,7 @@ impl TagList {
let mut gvalue = mem::zeroed();
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 {
return None;
@ -126,7 +116,7 @@ impl TagList {
unsafe {
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() {
return None;
@ -140,7 +130,7 @@ impl TagList {
unsafe {
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 {
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();
glib::g_free(ptr as glib::gpointer);
@ -167,7 +157,17 @@ impl fmt::Debug for TagList {
impl PartialEq for TagList {
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 {
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 {
@ -495,11 +498,11 @@ impl<'a> From<Cow<'a, [Value]>> for Value {
}
}
Cow::Owned(array) => {
for mut e in array {
for e in array {
gst::gst_value_array_append_and_take_value(&mut value.0,
e.as_ptr() as
*mut gobject::GValue);
e.0.g_type = gobject::G_TYPE_NONE;
mem::forget(e);
}
}
}