From 9b593136da3f905b6ee0d011e96c3397a1de4154 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Mon, 24 Apr 2017 10:06:38 +0100 Subject: [PATCH] Rewrite MiniObject bindings These now use references were applicable and GstRef became useless --- gst-plugin/src/buffer.rs | 119 +++++++++++++--------------- gst-plugin/src/caps.rs | 40 +++++----- gst-plugin/src/demuxer.rs | 4 +- gst-plugin/src/miniobject.rs | 149 +++++++++++------------------------ gst-plugin/src/sink.rs | 6 +- gst-plugin/src/source.rs | 6 +- gst-plugin/src/streams.rs | 14 ++-- gst-plugin/src/structure.rs | 13 ++- gst-plugin/src/tags.rs | 40 +++++----- gst-plugin/src/value.rs | 9 ++- 10 files changed, 175 insertions(+), 225 deletions(-) diff --git a/gst-plugin/src/buffer.rs b/gst-plugin/src/buffer.rs index e42c9492..b02c0ddf 100644 --- a/gst-plugin/src/buffer.rs +++ b/gst-plugin/src/buffer.rs @@ -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 { 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 { 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) -> Option { 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) -> Option { 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 { - 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) { let offset = offset.unwrap_or(u64::MAX); - - unsafe { - (*self.0).offset = offset; - } + self.0.offset = offset; } pub fn get_offset_end(&self) -> Option { - 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) { 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 { - 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) { let pts = pts.unwrap_or(u64::MAX); - - unsafe { - (*self.0).pts = pts; - } + self.0.pts = pts; } pub fn get_dts(&self) -> Option { - 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) { let dts = dts.unwrap_or(u64::MAX); - - unsafe { - (*self.0).dts = dts; - } + self.0.dts = dts; } pub fn get_duration(&self) -> Option { - 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) { 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; + + fn to_owned(&self) -> GstRc { + 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); } } } diff --git a/gst-plugin/src/caps.rs b/gst-plugin/src/caps.rs index cfbb7aef..f5fb9163 100644 --- a/gst-plugin/src/caps.rs +++ b/gst-plugin/src/caps.rs @@ -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; + + fn to_owned(&self) -> GstRc { + unsafe { GstRc::from_unowned_ptr(self.as_ptr()) } } } diff --git a/gst-plugin/src/demuxer.rs b/gst-plugin/src/demuxer.rs index 0801ea09..02181e65 100644 --- a/gst-plugin/src/demuxer.rs +++ b/gst-plugin/src/demuxer.rs @@ -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; diff --git a/gst-plugin/src/miniobject.rs b/gst-plugin/src/miniobject.rs index 42ebba17..cdc2aa63 100644 --- a/gst-plugin/src/miniobject.rs +++ b/gst-plugin/src/miniobject.rs @@ -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 { - obj: T, +pub struct GstRc { + obj: &'static T, } impl GstRc { - 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 GstRc { 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 GstRc { 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 GstRc { 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 GstRc { } == 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 ops::Deref for GstRc { type Target = T; fn deref(&self) -> &T { - &self.obj + self.obj } } impl AsRef for GstRc { fn as_ref(&self) -> &T { - &self.obj + self.obj } } impl borrow::Borrow for GstRc { fn borrow(&self) -> &T { - &self.obj + self.obj } } +// FIXME: Not generally possible because neither T nor ToOwned are defined here... +//impl ToOwned for T { +// type Owned = GstRc; +// +// fn to_owned(&self) -> GstRc { +// unsafe { GstRc::from_unowned_ptr(self.as_ptr()) } +// } +//} + impl Clone for GstRc { fn clone(&self) -> GstRc { unsafe { GstRc::from_unowned_ptr(self.obj.as_ptr()) } @@ -108,9 +118,7 @@ impl Clone for GstRc { impl Drop for GstRc { 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 fmt::Display for GstRc { } } -// 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 { @@ -151,70 +165,3 @@ impl<'a, T: MiniObject> From<&'a mut T> for GstRc { 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 { - 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 for GstRef<'a, T> { - fn as_ref(&self) -> &T { - &self.obj - } -} - -impl<'a, T: MiniObject> borrow::Borrow 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) - } -} diff --git a/gst-plugin/src/sink.rs b/gst-plugin/src/sink.rs index 4831ff05..8996426e 100644 --- a/gst-plugin/src/sink.rs +++ b/gst-plugin/src/sink.rs @@ -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 = 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); } diff --git a/gst-plugin/src/source.rs b/gst-plugin/src/source.rs index 67e28023..28cc1274 100644 --- a/gst-plugin/src/source.rs +++ b/gst-plugin/src/source.rs @@ -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 = ::from_mut_ptr(buffer); panic_to_error!(wrap, gst::GST_FLOW_ERROR, { - let mut buffer: GstRef = 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); } diff --git a/gst-plugin/src/streams.rs b/gst-plugin/src/streams.rs index a7893d1d..85d375e4 100644 --- a/gst-plugin/src/streams.rs +++ b/gst-plugin/src/streams.rs @@ -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> { + 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 { ::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 { + 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 { ::from_ptr(ptr) }) } pub fn set_caps(&self, caps: Option>) { - 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) { - 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) } diff --git a/gst-plugin/src/structure.rs b/gst-plugin/src/structure.rs index ffdc4d40..64702e7c 100644 --- a/gst-plugin/src/structure.rs +++ b/gst-plugin/src/structure.rs @@ -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); } } diff --git a/gst-plugin/src/tags.rs b/gst-plugin/src/tags.rs index 6cefa2fc..11ea04c6 100644 --- a/gst-plugin/src/tags.rs +++ b/gst-plugin/src/tags.rs @@ -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; + + fn to_owned(&self) -> GstRc { + unsafe { GstRc::from_unowned_ptr(self.as_ptr()) } } } diff --git a/gst-plugin/src/value.rs b/gst-plugin/src/value.rs index 1829d11a..a624b9da 100644 --- a/gst-plugin/src/value.rs +++ b/gst-plugin/src/value.rs @@ -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> 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); } } }