Rewrite GValue bindings

This commit is contained in:
Sebastian Dröge 2017-04-17 11:29:28 +03:00
parent a808c34794
commit 2d97baaf96
6 changed files with 722 additions and 268 deletions

View file

@ -13,7 +13,6 @@ use value::*;
use miniobject::*;
use glib;
use gobject;
use gst;
#[derive(Eq)]
@ -77,9 +76,8 @@ impl Caps {
for value in values {
let name_cstr = CString::new(value.0).unwrap();
unsafe {
let mut gvalue = value.1.to_gvalue();
gst::gst_caps_set_value(self.0, name_cstr.as_ptr(), &gvalue);
gobject::g_value_unset(&mut gvalue);
let gvalue = value.1.as_ptr();
gst::gst_caps_set_value(self.0, name_cstr.as_ptr(), gvalue);
}
}
}

View file

@ -152,20 +152,17 @@ impl<'a, T: MiniObject> From<&'a mut T> for GstRc<T> {
}
}
#[repr(C)]
pub struct GstRefPtr<T: MiniObject>(pub *mut T::PtrType);
#[derive(Hash, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct GstRef<'a, T: 'a + MiniObject> {
obj: T,
#[allow(dead_code)]
phantom: PhantomData<&'a GstRefPtr<T>>,
phantom: PhantomData<&'a T>,
}
impl<'a, T: MiniObject> GstRef<'a, T> {
pub unsafe fn new(ptr: &'a GstRefPtr<T>) -> GstRef<'a, T> {
pub unsafe fn new(ptr: *mut T::PtrType) -> GstRef<'a, T> {
GstRef {
obj: T::new_from_ptr(ptr.0 as *mut T::PtrType),
obj: T::new_from_ptr(ptr),
phantom: PhantomData,
}
}

View file

@ -271,10 +271,9 @@ 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 = GstRefPtr(buffer);
panic_to_error!(wrap, gst::GST_FLOW_ERROR, {
let buffer: GstRef<Buffer> = GstRef::new(&buffer);
let buffer: GstRef<Buffer> = GstRef::new(buffer);
wrap.render(buffer.as_ref())
})
}

View file

@ -330,10 +330,9 @@ 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 = GstRefPtr(buffer);
panic_to_error!(wrap, gst::GST_FLOW_ERROR, {
let mut buffer: GstRef<Buffer> = GstRef::new(&buffer);
let mut buffer: GstRef<Buffer> = GstRef::new(buffer);
wrap.fill(offset, length, buffer.get_mut().unwrap())
})
}

View file

@ -16,15 +16,15 @@ use glib;
use gobject;
use gst;
pub trait Tag {
type TagType: ValueType;
pub trait Tag<'a> {
type TagType: ValueType<'a>;
fn tag_name() -> &'static str;
}
macro_rules! impl_tag(
($name:ident, $t:ty, $tag:expr) => {
pub struct $name;
impl Tag for $name {
impl<'a> Tag<'a> for $name {
type TagType = $t;
fn tag_name() -> &'static str {
$tag
@ -33,16 +33,16 @@ macro_rules! impl_tag(
};
);
impl_tag!(Title, String, "title");
impl_tag!(Album, String, "album");
impl_tag!(Artist, String, "artist");
impl_tag!(Encoder, String, "encoder");
impl_tag!(AudioCodec, String, "audio-codec");
impl_tag!(VideoCodec, String, "video-codec");
impl_tag!(SubtitleCodec, String, "subtitle-codec");
impl_tag!(ContainerFormat, String, "container-format");
impl_tag!(Title, &'a str, "title");
impl_tag!(Album, &'a str, "album");
impl_tag!(Artist, &'a str, "artist");
impl_tag!(Encoder, &'a str, "encoder");
impl_tag!(AudioCodec, &'a str, "audio-codec");
impl_tag!(VideoCodec, &'a str, "video-codec");
impl_tag!(SubtitleCodec, &'a str, "subtitle-codec");
impl_tag!(ContainerFormat, &'a str, "container-format");
// TODO: Should ideally enforce this to be ISO-639
impl_tag!(LanguageCode, String, "language-code");
impl_tag!(LanguageCode, &'a str, "language-code");
impl_tag!(Duration, u64, "duration");
impl_tag!(NominalBitrate, u32, "nominal-bitrate");
@ -92,12 +92,12 @@ impl TagList {
unsafe { GstRc::new_from_owned_ptr(gst::gst_tag_list_new_empty()) }
}
pub fn add<T: Tag>(&mut self, value: T::TagType, mode: MergeMode)
where Value: From<<T as Tag>::TagType>
pub fn add<'a, T: Tag<'a>>(&mut self, value: T::TagType, mode: MergeMode)
where Value: From<<T as Tag<'a>>::TagType>
{
unsafe {
let v = Value::from(value);
let mut gvalue = v.to_gvalue();
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);
@ -106,8 +106,8 @@ impl TagList {
}
}
pub fn get<T: Tag>(&self) -> Option<TypedValue<T::TagType>>
where Value: From<<T as Tag>::TagType>
pub fn get<'a, T: Tag<'a>>(&self) -> Option<TypedValue<T::TagType>>
where Value: From<<T as Tag<'a>>::TagType>
{
unsafe {
let mut gvalue = mem::zeroed();
@ -119,13 +119,11 @@ impl TagList {
return None;
}
let res = match Value::from_gvalue(&gvalue) {
Some(value) => Some(TypedValue::new(value)),
let res = match Value::from_raw(gvalue) {
Some(value) => TypedValue::from_value(value),
None => None,
};
gobject::g_value_unset(&mut gvalue);
res
}
}
@ -194,8 +192,8 @@ mod tests {
tags.add::<Duration>((1000u64 * 1000 * 1000 * 120).into(), MergeMode::Append);
}
assert_eq!(*tags.get::<Title>().unwrap(), "some title");
assert_eq!(*tags.get::<Duration>().unwrap(),
assert_eq!(tags.get::<Title>().unwrap().get(), "some title");
assert_eq!(tags.get::<Duration>().unwrap().get(),
(1000u64 * 1000 * 1000 * 120));
}
}

File diff suppressed because it is too large Load diff