2020-12-15 10:53:31 +00:00
|
|
|
// Take a look at the license at the top of the repository in the LICENSE file.
|
2018-09-28 09:00:08 +00:00
|
|
|
|
|
|
|
use std::borrow::{Borrow, BorrowMut, ToOwned};
|
|
|
|
use std::ffi::CStr;
|
|
|
|
use std::fmt;
|
|
|
|
use std::mem;
|
|
|
|
use std::ops::{Deref, DerefMut};
|
|
|
|
use std::ptr;
|
|
|
|
use std::str;
|
|
|
|
|
2020-01-22 17:38:13 +00:00
|
|
|
use once_cell::sync::Lazy;
|
|
|
|
|
2021-04-20 07:19:02 +00:00
|
|
|
use glib::translate::*;
|
|
|
|
use glib::StaticType;
|
2018-09-28 09:00:08 +00:00
|
|
|
|
2021-04-03 14:35:22 +00:00
|
|
|
pub struct CapsFeatures(ptr::NonNull<ffi::GstCapsFeatures>);
|
2018-09-28 09:00:08 +00:00
|
|
|
unsafe impl Send for CapsFeatures {}
|
|
|
|
unsafe impl Sync for CapsFeatures {}
|
|
|
|
|
|
|
|
impl CapsFeatures {
|
|
|
|
pub fn new(features: &[&str]) -> Self {
|
2020-03-22 14:18:47 +00:00
|
|
|
assert_initialized_main_thread!();
|
2018-09-28 09:00:08 +00:00
|
|
|
let mut f = Self::new_empty();
|
|
|
|
|
|
|
|
for feature in features {
|
|
|
|
f.add(feature);
|
|
|
|
}
|
|
|
|
|
|
|
|
f
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn new_empty() -> Self {
|
|
|
|
assert_initialized_main_thread!();
|
|
|
|
unsafe {
|
2020-10-24 16:56:48 +00:00
|
|
|
CapsFeatures(ptr::NonNull::new_unchecked(
|
2021-04-03 14:35:22 +00:00
|
|
|
ffi::gst_caps_features_new_empty(),
|
2020-10-24 16:56:48 +00:00
|
|
|
))
|
2018-09-28 09:00:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn new_any() -> Self {
|
|
|
|
assert_initialized_main_thread!();
|
2021-04-03 14:35:22 +00:00
|
|
|
unsafe { CapsFeatures(ptr::NonNull::new_unchecked(ffi::gst_caps_features_new_any())) }
|
2018-09-28 09:00:08 +00:00
|
|
|
}
|
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
pub unsafe fn into_ptr(self) -> *mut ffi::GstCapsFeatures {
|
2020-04-09 12:59:14 +00:00
|
|
|
let s = mem::ManuallyDrop::new(self);
|
2021-04-03 14:35:22 +00:00
|
|
|
s.0.as_ptr()
|
2018-09-28 09:00:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Deref for CapsFeatures {
|
|
|
|
type Target = CapsFeaturesRef;
|
|
|
|
|
|
|
|
fn deref(&self) -> &CapsFeaturesRef {
|
2021-04-03 14:35:22 +00:00
|
|
|
unsafe { &*(self.0.as_ref() as *const ffi::GstCapsFeatures as *const CapsFeaturesRef) }
|
2018-09-28 09:00:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl DerefMut for CapsFeatures {
|
|
|
|
fn deref_mut(&mut self) -> &mut CapsFeaturesRef {
|
2021-04-03 14:35:22 +00:00
|
|
|
unsafe { &mut *(self.0.as_mut() as *mut ffi::GstCapsFeatures as *mut CapsFeaturesRef) }
|
2018-09-28 09:00:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl AsRef<CapsFeaturesRef> for CapsFeatures {
|
|
|
|
fn as_ref(&self) -> &CapsFeaturesRef {
|
|
|
|
self.deref()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl AsMut<CapsFeaturesRef> for CapsFeatures {
|
|
|
|
fn as_mut(&mut self) -> &mut CapsFeaturesRef {
|
|
|
|
self.deref_mut()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Clone for CapsFeatures {
|
|
|
|
fn clone(&self) -> Self {
|
|
|
|
unsafe {
|
2021-04-03 14:35:22 +00:00
|
|
|
let ptr = ffi::gst_caps_features_copy(self.0.as_ref());
|
2018-09-28 09:00:08 +00:00
|
|
|
assert!(!ptr.is_null());
|
2020-10-24 16:56:48 +00:00
|
|
|
CapsFeatures(ptr::NonNull::new_unchecked(ptr))
|
2018-09-28 09:00:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Drop for CapsFeatures {
|
|
|
|
fn drop(&mut self) {
|
2021-04-03 14:35:22 +00:00
|
|
|
unsafe { ffi::gst_caps_features_free(self.0.as_mut()) }
|
2018-09-28 09:00:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Debug for CapsFeatures {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
f.debug_tuple("CapsFeatures")
|
|
|
|
.field(&self.to_string())
|
|
|
|
.finish()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for CapsFeatures {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
// Need to make sure to not call ToString::to_string() here, which
|
|
|
|
// we have because of the Display impl. We need CapsFeaturesRef::to_string()
|
|
|
|
f.write_str(&CapsFeaturesRef::to_string(self.as_ref()))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl str::FromStr for CapsFeatures {
|
2019-12-17 19:00:42 +00:00
|
|
|
type Err = glib::BoolError;
|
2018-09-28 09:00:08 +00:00
|
|
|
|
2020-11-28 11:34:36 +00:00
|
|
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
2019-10-04 06:11:30 +00:00
|
|
|
assert_initialized_main_thread!();
|
|
|
|
unsafe {
|
2020-11-21 13:46:48 +00:00
|
|
|
let ptr = ffi::gst_caps_features_from_string(s.to_glib_none().0);
|
2019-10-04 06:11:30 +00:00
|
|
|
if ptr.is_null() {
|
2020-12-17 22:38:06 +00:00
|
|
|
return Err(glib::bool_error!(
|
2019-12-17 19:00:42 +00:00
|
|
|
"Failed to parse caps features from string"
|
|
|
|
));
|
2019-10-04 06:11:30 +00:00
|
|
|
}
|
|
|
|
|
2021-04-03 14:35:22 +00:00
|
|
|
Ok(Self(ptr::NonNull::new_unchecked(ptr)))
|
2019-10-04 06:11:30 +00:00
|
|
|
}
|
2018-09-28 09:00:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Borrow<CapsFeaturesRef> for CapsFeatures {
|
|
|
|
fn borrow(&self) -> &CapsFeaturesRef {
|
2021-04-03 14:35:22 +00:00
|
|
|
self.as_ref()
|
2018-09-28 09:00:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl BorrowMut<CapsFeaturesRef> for CapsFeatures {
|
|
|
|
fn borrow_mut(&mut self) -> &mut CapsFeaturesRef {
|
2021-04-03 14:35:22 +00:00
|
|
|
self.as_mut()
|
2018-09-28 09:00:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl glib::types::StaticType for CapsFeatures {
|
|
|
|
fn static_type() -> glib::types::Type {
|
2020-11-21 13:46:48 +00:00
|
|
|
unsafe { from_glib(ffi::gst_caps_features_get_type()) }
|
2018-09-28 09:00:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
impl<'a> ToGlibPtr<'a, *const ffi::GstCapsFeatures> for CapsFeatures {
|
2018-09-28 09:00:08 +00:00
|
|
|
type Storage = &'a Self;
|
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
fn to_glib_none(&'a self) -> Stash<'a, *const ffi::GstCapsFeatures, Self> {
|
2021-04-03 14:35:22 +00:00
|
|
|
unsafe { Stash(self.0.as_ref(), self) }
|
2018-09-28 09:00:08 +00:00
|
|
|
}
|
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
fn to_glib_full(&self) -> *const ffi::GstCapsFeatures {
|
2021-04-03 14:35:22 +00:00
|
|
|
unsafe { ffi::gst_caps_features_copy(self.0.as_ref()) }
|
2018-09-28 09:00:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
impl<'a> ToGlibPtr<'a, *mut ffi::GstCapsFeatures> for CapsFeatures {
|
2018-09-28 09:00:08 +00:00
|
|
|
type Storage = &'a Self;
|
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
fn to_glib_none(&'a self) -> Stash<'a, *mut ffi::GstCapsFeatures, Self> {
|
2021-04-03 14:35:22 +00:00
|
|
|
unsafe {
|
|
|
|
Stash(
|
|
|
|
self.0.as_ref() as *const ffi::GstCapsFeatures as *mut ffi::GstCapsFeatures,
|
|
|
|
self,
|
|
|
|
)
|
|
|
|
}
|
2018-09-28 09:00:08 +00:00
|
|
|
}
|
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
fn to_glib_full(&self) -> *mut ffi::GstCapsFeatures {
|
2021-04-03 14:35:22 +00:00
|
|
|
unsafe { ffi::gst_caps_features_copy(self.0.as_ref()) }
|
2018-09-28 09:00:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
impl<'a> ToGlibPtrMut<'a, *mut ffi::GstCapsFeatures> for CapsFeatures {
|
2018-09-28 09:00:08 +00:00
|
|
|
type Storage = &'a mut Self;
|
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
fn to_glib_none_mut(&'a mut self) -> StashMut<*mut ffi::GstCapsFeatures, Self> {
|
2021-04-03 14:35:22 +00:00
|
|
|
unsafe { StashMut(self.0.as_mut(), self) }
|
2018-09-28 09:00:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
impl FromGlibPtrNone<*const ffi::GstCapsFeatures> for CapsFeatures {
|
|
|
|
unsafe fn from_glib_none(ptr: *const ffi::GstCapsFeatures) -> Self {
|
2018-09-28 09:00:08 +00:00
|
|
|
assert!(!ptr.is_null());
|
2020-11-21 13:46:48 +00:00
|
|
|
let ptr = ffi::gst_caps_features_copy(ptr);
|
2018-09-28 09:00:08 +00:00
|
|
|
assert!(!ptr.is_null());
|
2021-04-03 14:35:22 +00:00
|
|
|
CapsFeatures(ptr::NonNull::new_unchecked(ptr))
|
2018-09-28 09:00:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
impl FromGlibPtrNone<*mut ffi::GstCapsFeatures> for CapsFeatures {
|
|
|
|
unsafe fn from_glib_none(ptr: *mut ffi::GstCapsFeatures) -> Self {
|
2018-09-28 09:00:08 +00:00
|
|
|
assert!(!ptr.is_null());
|
2020-11-21 13:46:48 +00:00
|
|
|
let ptr = ffi::gst_caps_features_copy(ptr);
|
2018-09-28 09:00:08 +00:00
|
|
|
assert!(!ptr.is_null());
|
2021-04-03 14:35:22 +00:00
|
|
|
CapsFeatures(ptr::NonNull::new_unchecked(ptr))
|
2018-09-28 09:00:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
impl FromGlibPtrFull<*const ffi::GstCapsFeatures> for CapsFeatures {
|
|
|
|
unsafe fn from_glib_full(ptr: *const ffi::GstCapsFeatures) -> Self {
|
2018-09-28 09:00:08 +00:00
|
|
|
assert!(!ptr.is_null());
|
2021-04-03 14:35:22 +00:00
|
|
|
CapsFeatures(ptr::NonNull::new_unchecked(
|
|
|
|
ptr as *mut ffi::GstCapsFeatures,
|
|
|
|
))
|
2018-09-28 09:00:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
impl FromGlibPtrFull<*mut ffi::GstCapsFeatures> for CapsFeatures {
|
|
|
|
unsafe fn from_glib_full(ptr: *mut ffi::GstCapsFeatures) -> Self {
|
2018-09-28 09:00:08 +00:00
|
|
|
assert!(!ptr.is_null());
|
2021-04-03 14:35:22 +00:00
|
|
|
CapsFeatures(ptr::NonNull::new_unchecked(ptr))
|
2018-09-28 09:00:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-20 07:19:02 +00:00
|
|
|
impl glib::value::ValueType for CapsFeatures {
|
|
|
|
type Type = Self;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsafe impl<'a> glib::value::FromValue<'a> for CapsFeatures {
|
|
|
|
type Checker = glib::value::GenericValueTypeOrNoneChecker<Self>;
|
|
|
|
|
|
|
|
unsafe fn from_value(value: &'a glib::Value) -> Self {
|
|
|
|
skip_assert_initialized!();
|
|
|
|
from_glib_none(glib::gobject_ffi::g_value_get_boxed(value.to_glib_none().0)
|
|
|
|
as *mut ffi::GstCapsFeatures)
|
2018-09-28 09:00:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-20 07:19:02 +00:00
|
|
|
impl glib::value::ToValue for CapsFeatures {
|
|
|
|
fn to_value(&self) -> glib::Value {
|
|
|
|
let mut value = glib::Value::for_value_type::<CapsFeatures>();
|
|
|
|
unsafe {
|
|
|
|
glib::gobject_ffi::g_value_set_boxed(
|
|
|
|
value.to_glib_none_mut().0,
|
|
|
|
ToGlibPtr::<*mut ffi::GstCapsFeatures>::to_glib_none(self).0 as *mut _,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
value
|
|
|
|
}
|
|
|
|
|
|
|
|
fn value_type(&self) -> glib::Type {
|
|
|
|
Self::static_type()
|
2018-09-28 09:00:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-20 07:19:02 +00:00
|
|
|
impl glib::value::ToValueOptional for CapsFeatures {
|
|
|
|
fn to_value_optional(s: Option<&Self>) -> glib::Value {
|
|
|
|
skip_assert_initialized!();
|
|
|
|
let mut value = glib::Value::for_value_type::<CapsFeatures>();
|
|
|
|
unsafe {
|
|
|
|
glib::gobject_ffi::g_value_set_boxed(
|
|
|
|
value.to_glib_none_mut().0,
|
|
|
|
ToGlibPtr::<*mut ffi::GstCapsFeatures>::to_glib_none(&s).0 as *mut _,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
value
|
2018-09-28 09:00:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl GlibPtrDefault for CapsFeatures {
|
2020-11-21 13:46:48 +00:00
|
|
|
type GlibType = *mut ffi::GstCapsFeatures;
|
2018-09-28 09:00:08 +00:00
|
|
|
}
|
|
|
|
|
2020-10-24 17:06:59 +00:00
|
|
|
#[repr(transparent)]
|
2020-11-21 13:46:48 +00:00
|
|
|
pub struct CapsFeaturesRef(ffi::GstCapsFeatures);
|
2018-09-28 09:00:08 +00:00
|
|
|
|
|
|
|
impl CapsFeaturesRef {
|
2020-11-21 13:46:48 +00:00
|
|
|
pub unsafe fn from_glib_borrow<'a>(ptr: *const ffi::GstCapsFeatures) -> &'a CapsFeaturesRef {
|
2018-09-28 09:00:08 +00:00
|
|
|
assert!(!ptr.is_null());
|
|
|
|
|
|
|
|
&*(ptr as *mut CapsFeaturesRef)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub unsafe fn from_glib_borrow_mut<'a>(
|
2020-11-21 13:46:48 +00:00
|
|
|
ptr: *mut ffi::GstCapsFeatures,
|
2018-09-28 09:00:08 +00:00
|
|
|
) -> &'a mut CapsFeaturesRef {
|
|
|
|
assert!(!ptr.is_null());
|
|
|
|
|
|
|
|
&mut *(ptr as *mut CapsFeaturesRef)
|
|
|
|
}
|
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
pub unsafe fn as_ptr(&self) -> *const ffi::GstCapsFeatures {
|
|
|
|
self as *const Self as *const ffi::GstCapsFeatures
|
2018-09-28 09:00:08 +00:00
|
|
|
}
|
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
pub unsafe fn as_mut_ptr(&self) -> *mut ffi::GstCapsFeatures {
|
|
|
|
self as *const Self as *mut ffi::GstCapsFeatures
|
2018-09-28 09:00:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_empty(&self) -> bool {
|
2021-04-11 19:39:50 +00:00
|
|
|
self.size() == 0 && !self.is_any()
|
2018-09-28 09:00:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_any(&self) -> bool {
|
2020-11-21 13:46:48 +00:00
|
|
|
unsafe { from_glib(ffi::gst_caps_features_is_any(self.as_ptr())) }
|
2018-09-28 09:00:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn contains(&self, feature: &str) -> bool {
|
|
|
|
unsafe {
|
2020-11-21 13:46:48 +00:00
|
|
|
from_glib(ffi::gst_caps_features_contains(
|
2018-09-28 09:00:08 +00:00
|
|
|
self.as_ptr(),
|
|
|
|
feature.to_glib_none().0,
|
|
|
|
))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-11 19:39:50 +00:00
|
|
|
pub fn size(&self) -> u32 {
|
2020-11-21 13:46:48 +00:00
|
|
|
unsafe { ffi::gst_caps_features_get_size(self.as_ptr()) }
|
2018-09-28 09:00:08 +00:00
|
|
|
}
|
|
|
|
|
2021-04-20 10:23:24 +00:00
|
|
|
pub fn nth(&self, idx: u32) -> Option<&str> {
|
2021-04-11 19:39:50 +00:00
|
|
|
if idx >= self.size() {
|
2018-09-28 09:00:08 +00:00
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsafe {
|
2020-11-21 13:46:48 +00:00
|
|
|
let feature = ffi::gst_caps_features_get_nth(self.as_ptr(), idx);
|
2018-09-28 09:00:08 +00:00
|
|
|
if feature.is_null() {
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
|
|
|
Some(CStr::from_ptr(feature).to_str().unwrap())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn add(&mut self, feature: &str) {
|
2020-11-21 13:46:48 +00:00
|
|
|
unsafe { ffi::gst_caps_features_add(self.as_mut_ptr(), feature.to_glib_none().0) }
|
2018-09-28 09:00:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn remove(&mut self, feature: &str) {
|
2020-11-21 13:46:48 +00:00
|
|
|
unsafe { ffi::gst_caps_features_remove(self.as_mut_ptr(), feature.to_glib_none().0) }
|
2018-09-28 09:00:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn iter(&self) -> Iter {
|
|
|
|
Iter::new(self)
|
|
|
|
}
|
|
|
|
|
|
|
|
// This is not an equivalence relation with regards to ANY. Everything is equal to ANY
|
|
|
|
pub fn is_equal(&self, other: &CapsFeaturesRef) -> bool {
|
|
|
|
unsafe {
|
2020-11-21 13:46:48 +00:00
|
|
|
from_glib(ffi::gst_caps_features_is_equal(
|
2018-09-28 09:00:08 +00:00
|
|
|
self.as_ptr(),
|
|
|
|
other.as_ptr(),
|
|
|
|
))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-27 10:07:32 +00:00
|
|
|
impl glib::types::StaticType for CapsFeaturesRef {
|
|
|
|
fn static_type() -> glib::types::Type {
|
2020-11-21 13:46:48 +00:00
|
|
|
unsafe { from_glib(ffi::gst_structure_get_type()) }
|
2020-05-27 10:07:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-20 07:19:02 +00:00
|
|
|
unsafe impl<'a> glib::value::FromValue<'a> for &'a CapsFeaturesRef {
|
|
|
|
type Checker = glib::value::GenericValueTypeOrNoneChecker<Self>;
|
|
|
|
|
|
|
|
unsafe fn from_value(value: &'a glib::Value) -> Self {
|
|
|
|
skip_assert_initialized!();
|
|
|
|
&*(glib::gobject_ffi::g_value_get_boxed(value.to_glib_none().0) as *const CapsFeaturesRef)
|
2020-05-27 10:07:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-20 07:19:02 +00:00
|
|
|
impl glib::value::ToValue for CapsFeaturesRef {
|
|
|
|
fn to_value(&self) -> glib::Value {
|
|
|
|
let mut value = glib::Value::for_value_type::<CapsFeatures>();
|
|
|
|
unsafe {
|
|
|
|
glib::gobject_ffi::g_value_set_boxed(
|
|
|
|
value.to_glib_none_mut().0,
|
|
|
|
self.as_mut_ptr() as *mut _,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
value
|
|
|
|
}
|
|
|
|
|
|
|
|
fn value_type(&self) -> glib::Type {
|
|
|
|
Self::static_type()
|
2020-05-27 10:07:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-20 07:19:02 +00:00
|
|
|
impl glib::value::ToValueOptional for CapsFeaturesRef {
|
|
|
|
fn to_value_optional(s: Option<&Self>) -> glib::Value {
|
|
|
|
skip_assert_initialized!();
|
|
|
|
let mut value = glib::Value::for_value_type::<CapsFeatures>();
|
|
|
|
unsafe {
|
|
|
|
glib::gobject_ffi::g_value_set_boxed(
|
|
|
|
value.to_glib_none_mut().0,
|
|
|
|
s.map(|s| s.as_mut_ptr()).unwrap_or(ptr::null_mut()) as *mut _,
|
|
|
|
)
|
2020-05-27 10:07:32 +00:00
|
|
|
}
|
2021-04-20 07:19:02 +00:00
|
|
|
value
|
2020-05-27 10:07:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-22 15:43:29 +00:00
|
|
|
#[derive(Debug)]
|
2018-09-28 09:00:08 +00:00
|
|
|
pub struct Iter<'a> {
|
|
|
|
caps_features: &'a CapsFeaturesRef,
|
|
|
|
idx: u32,
|
|
|
|
n_features: u32,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> Iter<'a> {
|
|
|
|
fn new(caps_features: &'a CapsFeaturesRef) -> Iter<'a> {
|
|
|
|
skip_assert_initialized!();
|
2021-04-11 19:39:50 +00:00
|
|
|
let n_features = caps_features.size();
|
2018-09-28 09:00:08 +00:00
|
|
|
|
|
|
|
Iter {
|
|
|
|
caps_features,
|
|
|
|
idx: 0,
|
|
|
|
n_features,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> Iterator for Iter<'a> {
|
|
|
|
type Item = &'a str;
|
|
|
|
|
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
|
|
if self.idx >= self.n_features {
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsafe {
|
2020-11-21 13:46:48 +00:00
|
|
|
let feature = ffi::gst_caps_features_get_nth(self.caps_features.as_ptr(), self.idx);
|
2018-09-28 09:00:08 +00:00
|
|
|
if feature.is_null() {
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
|
|
|
self.idx += 1;
|
|
|
|
|
|
|
|
Some(CStr::from_ptr(feature).to_str().unwrap())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
|
|
if self.idx == self.n_features {
|
|
|
|
return (0, Some(0));
|
|
|
|
}
|
|
|
|
|
|
|
|
let remaining = (self.n_features - self.idx) as usize;
|
|
|
|
|
|
|
|
(remaining, Some(remaining))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> DoubleEndedIterator for Iter<'a> {
|
|
|
|
fn next_back(&mut self) -> Option<Self::Item> {
|
|
|
|
if self.idx == self.n_features {
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
|
|
|
self.n_features -= 1;
|
|
|
|
|
|
|
|
unsafe {
|
|
|
|
let feature =
|
2020-11-21 13:46:48 +00:00
|
|
|
ffi::gst_caps_features_get_nth(self.caps_features.as_ptr(), self.n_features);
|
2018-09-28 09:00:08 +00:00
|
|
|
if feature.is_null() {
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
|
|
|
Some(CStr::from_ptr(feature).to_str().unwrap())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> ExactSizeIterator for Iter<'a> {}
|
|
|
|
|
|
|
|
impl fmt::Debug for CapsFeaturesRef {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
f.debug_tuple("CapsFeatures")
|
|
|
|
.field(&self.to_string())
|
|
|
|
.finish()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for CapsFeaturesRef {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2019-10-04 06:11:30 +00:00
|
|
|
let s = unsafe {
|
2020-11-21 13:46:48 +00:00
|
|
|
glib::GString::from_glib_full(ffi::gst_caps_features_to_string(self.as_ptr()))
|
2019-10-04 06:11:30 +00:00
|
|
|
};
|
|
|
|
f.write_str(&s)
|
2018-09-28 09:00:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ToOwned for CapsFeaturesRef {
|
|
|
|
type Owned = CapsFeatures;
|
|
|
|
|
|
|
|
fn to_owned(&self) -> CapsFeatures {
|
2020-11-21 13:46:48 +00:00
|
|
|
unsafe { from_glib_full(ffi::gst_caps_features_copy(self.as_ptr() as *const _) as *mut _) }
|
2018-09-28 09:00:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
unsafe impl Sync for CapsFeaturesRef {}
|
|
|
|
unsafe impl Send for CapsFeaturesRef {}
|
|
|
|
|
2020-01-22 17:38:13 +00:00
|
|
|
pub static CAPS_FEATURE_MEMORY_SYSTEM_MEMORY: Lazy<&'static str> = Lazy::new(|| unsafe {
|
2020-11-21 13:46:48 +00:00
|
|
|
CStr::from_ptr(ffi::GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY)
|
2020-01-22 17:38:13 +00:00
|
|
|
.to_str()
|
|
|
|
.unwrap()
|
|
|
|
});
|
|
|
|
pub static CAPS_FEATURES_MEMORY_SYSTEM_MEMORY: Lazy<CapsFeatures> =
|
|
|
|
Lazy::new(|| CapsFeatures::new(&[*CAPS_FEATURE_MEMORY_SYSTEM_MEMORY]));
|
2019-09-24 09:34:08 +00:00
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_from_value_optional() {
|
2021-04-20 07:19:02 +00:00
|
|
|
use glib::ToValue;
|
|
|
|
|
2020-11-21 13:46:48 +00:00
|
|
|
crate::init().unwrap();
|
2019-09-24 09:34:08 +00:00
|
|
|
|
2021-04-20 07:19:02 +00:00
|
|
|
let a = None::<CapsFeatures>.to_value();
|
|
|
|
assert!(a.get::<Option<CapsFeatures>>().unwrap().is_none());
|
2019-09-24 09:34:08 +00:00
|
|
|
let b = glib::value::Value::from(&CapsFeatures::new_empty());
|
2021-04-20 07:19:02 +00:00
|
|
|
assert!(b.get::<Option<CapsFeatures>>().unwrap().is_some());
|
2019-09-24 09:34:08 +00:00
|
|
|
}
|
|
|
|
}
|