Skip to main content

video_toolbox/
session.rs

1use std::{
2    mem,
3    ptr::{addr_of_mut, null_mut},
4};
5
6use core_foundation::{
7    base::{kCFAllocatorDefault, CFAllocatorRef, CFGetTypeID, CFRetain, CFType, CFTypeID, CFTypeRef, OSStatus, TCFType, TCFTypeRef},
8    declare_TCFType,
9    dictionary::{CFDictionary, CFDictionaryRef},
10    impl_CFTypeDescription,
11    string::{CFString, CFStringRef},
12};
13use libc::c_void;
14
15use crate::base::status_to_result;
16
17pub type VTSessionRef = CFTypeRef;
18
19pub type FrameDelay = i32;
20
21pub const kVTUnlimitedFrameDelayCount: FrameDelay = -1;
22
23extern "C" {
24    pub fn VTSessionCopySupportedPropertyDictionary(session: VTSessionRef, supportedPropertyDictionaryOut: *mut CFDictionaryRef) -> OSStatus;
25
26    pub static kVTPropertyTypeKey: CFStringRef;
27    pub static kVTPropertyType_Enumeration: CFStringRef;
28    pub static kVTPropertyType_Boolean: CFStringRef;
29    pub static kVTPropertyType_Number: CFStringRef;
30    pub static kVTPropertyReadWriteStatusKey: CFStringRef;
31    pub static kVTPropertyReadWriteStatus_ReadOnly: CFStringRef;
32    pub static kVTPropertyReadWriteStatus_ReadWrite: CFStringRef;
33    pub static kVTPropertyShouldBeSerializedKey: CFStringRef;
34    pub static kVTPropertySupportedValueMinimumKey: CFStringRef;
35    pub static kVTPropertySupportedValueMaximumKey: CFStringRef;
36    pub static kVTPropertySupportedValueListKey: CFStringRef;
37    pub static kVTPropertyDocumentationKey: CFStringRef;
38
39    pub fn VTSessionSetProperty(session: VTSessionRef, propertyKey: CFStringRef, propertyValue: CFTypeRef) -> OSStatus;
40    pub fn VTSessionSetProperties(session: VTSessionRef, propertyDictionary: CFDictionaryRef) -> OSStatus;
41    pub fn VTSessionCopyProperty(
42        session: VTSessionRef,
43        propertyKey: CFStringRef,
44        allocator: CFAllocatorRef,
45        propertyValueOut: *mut c_void,
46    ) -> OSStatus;
47    pub fn VTSessionCopySerializableProperties(session: VTSessionRef, allocator: CFAllocatorRef, dictionaryOut: *mut CFDictionaryRef) -> OSStatus;
48}
49
50declare_TCFType!(VTSession, VTSessionRef);
51impl_CFTypeDescription!(VTSession);
52
53impl VTSession {
54    #[inline]
55    pub fn as_concrete_TypeRef(&self) -> VTSessionRef {
56        self.0
57    }
58
59    #[inline]
60    pub fn as_CFType(&self) -> CFType {
61        unsafe { CFType::wrap_under_get_rule(self.as_CFTypeRef()) }
62    }
63
64    #[inline]
65    pub fn as_CFTypeRef(&self) -> CFTypeRef {
66        self.as_concrete_TypeRef() as CFTypeRef
67    }
68
69    #[inline]
70    pub fn into_CFType(self) -> CFType {
71        let reference = self.as_CFTypeRef();
72        mem::forget(self);
73        unsafe { CFType::wrap_under_create_rule(reference) }
74    }
75
76    #[inline]
77    pub unsafe fn wrap_under_create_rule(reference: VTSessionRef) -> VTSession {
78        VTSession(reference)
79    }
80
81    #[inline]
82    pub unsafe fn wrap_under_get_rule(reference: VTSessionRef) -> VTSession {
83        VTSession(CFRetain(reference as CFTypeRef) as VTSessionRef)
84    }
85
86    #[inline]
87    pub fn type_of(&self) -> CFTypeID {
88        unsafe { CFGetTypeID(self.as_CFTypeRef()) }
89    }
90
91    #[inline]
92    pub fn instance_of<T: TCFType>(&self) -> bool {
93        self.type_of() == T::type_id()
94    }
95}
96
97impl Clone for VTSession {
98    #[inline]
99    fn clone(&self) -> VTSession {
100        unsafe { VTSession::wrap_under_get_rule(self.0) }
101    }
102}
103
104impl PartialEq for VTSession {
105    #[inline]
106    fn eq(&self, other: &VTSession) -> bool {
107        self.as_CFType().eq(&other.as_CFType())
108    }
109}
110
111pub trait TVTSession: TCFType {
112    #[inline]
113    fn as_session(&self) -> VTSession {
114        unsafe { VTSession::wrap_under_get_rule(self.as_concrete_TypeRef().as_void_ptr() as VTSessionRef) }
115    }
116
117    #[inline]
118    fn into_session(self) -> VTSession
119    where
120        Self: Sized,
121    {
122        let reference = self.as_concrete_TypeRef().as_void_ptr() as VTSessionRef;
123        mem::forget(self);
124        unsafe { VTSession::wrap_under_create_rule(reference) }
125    }
126}
127
128impl VTSession {
129    #[inline]
130    pub fn downcast<T: TVTSession>(&self) -> Option<T> {
131        if self.instance_of::<T>() {
132            unsafe { Some(T::wrap_under_get_rule(T::Ref::from_void_ptr(self.as_concrete_TypeRef().as_void_ptr()))) }
133        } else {
134            None
135        }
136    }
137
138    #[inline]
139    pub fn downcast_into<T: TVTSession>(self) -> Option<T> {
140        if self.instance_of::<T>() {
141            unsafe {
142                let reference = T::Ref::from_void_ptr(self.as_concrete_TypeRef().as_void_ptr());
143                mem::forget(self);
144                Some(T::wrap_under_create_rule(reference))
145            }
146        } else {
147            None
148        }
149    }
150}
151
152impl VTSession {
153    pub fn copy_supported_property_dictionary(&self) -> Result<CFDictionary<CFString, CFType>, OSStatus> {
154        unsafe {
155            let mut dict: CFDictionaryRef = null_mut();
156            let status = VTSessionCopySupportedPropertyDictionary(self.as_concrete_TypeRef(), &mut dict);
157            status_to_result(status).map(|_| CFDictionary::wrap_under_create_rule(dict))
158        }
159    }
160
161    pub fn copy_property(&self, property_key: CFString) -> Result<CFType, OSStatus> {
162        unsafe {
163            let mut value: CFTypeRef = null_mut();
164            let status = VTSessionCopyProperty(
165                self.as_concrete_TypeRef(),
166                property_key.as_concrete_TypeRef(),
167                kCFAllocatorDefault,
168                addr_of_mut!(value).cast(),
169            );
170            status_to_result(status).map(|_| CFType::wrap_under_create_rule(value))
171        }
172    }
173
174    pub fn copy_serializable_properties(&self) -> Result<CFDictionary<CFString, CFType>, OSStatus> {
175        unsafe {
176            let mut dict: CFDictionaryRef = null_mut();
177            let status = VTSessionCopySerializableProperties(self.as_concrete_TypeRef(), kCFAllocatorDefault, &mut dict);
178            status_to_result(status).map(|_| CFDictionary::wrap_under_create_rule(dict))
179        }
180    }
181
182    pub fn set_property(&self, property_key: CFString, property_value: CFType) -> Result<(), OSStatus> {
183        unsafe {
184            let status = VTSessionSetProperty(self.as_concrete_TypeRef(), property_key.as_concrete_TypeRef(), property_value.as_concrete_TypeRef());
185            status_to_result(status)
186        }
187    }
188
189    pub fn set_properties(&self, property_dictionary: &CFDictionary<CFString, CFType>) -> Result<(), OSStatus> {
190        unsafe {
191            let status = VTSessionSetProperties(self.as_concrete_TypeRef(), property_dictionary.as_concrete_TypeRef());
192            status_to_result(status)
193        }
194    }
195}