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}