Add bindings for gst::tags::register()

This commit is contained in:
Sebastian Dröge 2019-01-23 15:42:46 +02:00
parent bd0cbe99b3
commit 598e012568
5 changed files with 172 additions and 3 deletions

View file

@ -40,6 +40,7 @@ generate = [
"Gst.StreamFlags",
"Gst.ProgressType",
"Gst.BusSyncReply",
"Gst.TagFlag",
"Gst.TagMergeMode",
"Gst.PadProbeType",
"Gst.PadProbeReturn",

View file

@ -2387,6 +2387,73 @@ impl SetValue for StructureChangeType {
}
}
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[derive(Clone, Copy)]
pub enum TagFlag {
Undefined,
Meta,
Encoded,
Decoded,
Count,
#[doc(hidden)]
__Unknown(i32),
}
#[doc(hidden)]
impl ToGlib for TagFlag {
type GlibType = ffi::GstTagFlag;
fn to_glib(&self) -> ffi::GstTagFlag {
match *self {
TagFlag::Undefined => ffi::GST_TAG_FLAG_UNDEFINED,
TagFlag::Meta => ffi::GST_TAG_FLAG_META,
TagFlag::Encoded => ffi::GST_TAG_FLAG_ENCODED,
TagFlag::Decoded => ffi::GST_TAG_FLAG_DECODED,
TagFlag::Count => ffi::GST_TAG_FLAG_COUNT,
TagFlag::__Unknown(value) => value
}
}
}
#[doc(hidden)]
impl FromGlib<ffi::GstTagFlag> for TagFlag {
fn from_glib(value: ffi::GstTagFlag) -> Self {
skip_assert_initialized!();
match value {
0 => TagFlag::Undefined,
1 => TagFlag::Meta,
2 => TagFlag::Encoded,
3 => TagFlag::Decoded,
4 => TagFlag::Count,
value => TagFlag::__Unknown(value),
}
}
}
impl StaticType for TagFlag {
fn static_type() -> Type {
unsafe { from_glib(ffi::gst_tag_flag_get_type()) }
}
}
impl<'a> FromValueOptional<'a> for TagFlag {
unsafe fn from_value_optional(value: &Value) -> Option<Self> {
Some(FromValue::from_value(value))
}
}
impl<'a> FromValue<'a> for TagFlag {
unsafe fn from_value(value: &Value) -> Self {
from_glib(gobject_ffi::g_value_get_enum(value.to_glib_none().0))
}
}
impl SetValue for TagFlag {
unsafe fn set_value(value: &mut Value, this: &Self) {
gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, this.to_glib())
}
}
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[derive(Clone, Copy)]
pub enum TagMergeMode {

View file

@ -144,6 +144,7 @@ pub use self::enums::StateChangeReturn;
pub use self::enums::StreamError;
pub use self::enums::StreamStatusType;
pub use self::enums::StructureChangeType;
pub use self::enums::TagFlag;
pub use self::enums::TagMergeMode;
pub use self::enums::TaskState;
pub use self::enums::TocEntryType;

View file

@ -335,7 +335,7 @@ pub mod prelude {
pub use value::GstValueExt;
pub use miniobject::MiniObject;
pub use tags::Tag;
pub use tags::{CustomTag, Tag};
pub use muldiv::MulDiv;

View file

@ -1,4 +1,4 @@
// Copyright (C) 2016-2017 Sebastian Dröge <sebastian@centricular.com>
// Copyright (C) 2016-2018 Sebastian Dröge <sebastian@centricular.com>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
@ -14,7 +14,9 @@ use std::mem;
use ffi;
use glib;
use glib::translate::{from_glib, from_glib_full, ToGlib, ToGlibPtr, ToGlibPtrMut};
use glib::value::{FromValueOptional, SendValue, SetValue, ToSendValue, TypedValue};
use glib::value::{FromValueOptional, SendValue, SetValue, ToSendValue, TypedValue, Value};
use glib::StaticType;
use gobject_ffi;
use miniobject::*;
@ -765,6 +767,60 @@ impl<'a> DoubleEndedIterator for Iter<'a> {
impl<'a> ExactSizeIterator for Iter<'a> {}
pub trait CustomTag<'a>: Tag<'a> {
const FLAG: ::TagFlag;
const NICK: &'static str;
const DESCRIPTION: &'static str;
fn merge_func(src: &Value) -> Value {
merge_use_first(src)
}
}
pub fn register<T: for<'a> CustomTag<'a>>() {
unsafe extern "C" fn merge_func_trampoline<T: for<'a> CustomTag<'a>>(
dest: *mut gobject_ffi::GValue,
src: *const gobject_ffi::GValue,
) {
*dest = T::merge_func(&*(src as *const Value)).into_raw();
}
unsafe {
ffi::gst_tag_register(
T::tag_name().to_glib_none().0,
T::FLAG.to_glib(),
T::TagType::static_type().to_glib(),
T::NICK.to_glib_none().0,
T::DESCRIPTION.to_glib_none().0,
Some(merge_func_trampoline::<T>),
)
}
}
pub fn merge_use_first(src: &Value) -> Value {
assert_eq!(src.type_(), ::List::static_type());
unsafe {
use glib::translate::Uninitialized;
let mut res = Value::uninitialized();
ffi::gst_tag_merge_use_first(res.to_glib_none_mut().0, src.to_glib_none().0);
res
}
}
pub fn merge_strings_with_comma(src: &Value) -> Value {
assert_eq!(src.type_(), ::List::static_type());
unsafe {
use glib::translate::Uninitialized;
let mut res = Value::uninitialized();
ffi::gst_tag_merge_strings_with_comma(res.to_glib_none_mut().0, src.to_glib_none().0);
res
}
}
#[cfg(test)]
mod tests {
use super::*;
@ -915,4 +971,48 @@ mod tests {
assert_eq!(tag_value.get(), Some(::SECOND * 120));
assert!(tag_iter.next().is_none());
}
#[test]
fn test_custom_tags() {
::init().unwrap();
struct MyCustomTag;
impl<'a> Tag<'a> for MyCustomTag {
type TagType = &'a str;
fn tag_name<'b>() -> &'b str {
"my-custom-tag"
}
}
impl<'a> CustomTag<'a> for MyCustomTag {
const FLAG: ::TagFlag = ::TagFlag::Meta;
const NICK: &'static str = "my custom tag";
const DESCRIPTION: &'static str = "My own custom tag type for testing";
fn merge_func(src: &Value) -> Value {
merge_strings_with_comma(src)
}
}
register::<MyCustomTag>();
let mut tags = TagList::new();
{
let tags = tags.get_mut().unwrap();
tags.add::<MyCustomTag>(&"first one", TagMergeMode::Append);
}
assert_eq!(tags.get::<MyCustomTag>().unwrap().get(), Some("first one"));
{
let tags = tags.get_mut().unwrap();
tags.add::<MyCustomTag>(&"second one", TagMergeMode::Append);
}
assert_eq!(
tags.get::<MyCustomTag>().unwrap().get(),
Some("first one, second one")
);
}
}