core_video/
pixel_buffer_pool.rs1use std::ptr::{null, null_mut};
2
3use core_foundation::{
4 base::{kCFAllocatorDefault, CFAllocatorRef, CFType, CFTypeID, TCFType},
5 dictionary::{CFDictionary, CFDictionaryRef},
6 impl_CFTypeDescription, impl_TCFType,
7 string::{CFString, CFStringRef},
8};
9use libc::c_void;
10
11use crate::{
12 base::CVOptionFlags,
13 pixel_buffer::{CVPixelBuffer, CVPixelBufferRef},
14 r#return::{kCVReturnSuccess, CVReturn},
15};
16
17#[repr(C)]
18pub struct __CVPixelBufferPool(c_void);
19
20pub type CVPixelBufferPoolRef = *mut __CVPixelBufferPool;
21
22pub type CVPixelBufferPoolFlushFlags = CVOptionFlags;
23
24pub const kCVPixelBufferPoolFlushExcessBuffers: CVPixelBufferPoolFlushFlags = 1;
25
26extern "C" {
27 pub static kCVPixelBufferPoolMinimumBufferCountKey: CFStringRef;
28 pub static kCVPixelBufferPoolMaximumBufferAgeKey: CFStringRef;
29
30 pub static kCVPixelBufferPoolAllocationThresholdKey: CFStringRef;
31 pub static kCVPixelBufferPoolFreeBufferNotification: CFStringRef;
32
33 pub fn CVPixelBufferPoolGetTypeID() -> CFTypeID;
34 pub fn CVPixelBufferPoolRetain(pixelBufferPool: CVPixelBufferPoolRef) -> CVPixelBufferPoolRef;
35 pub fn CVPixelBufferPoolRelease(pixelBufferPool: CVPixelBufferPoolRef);
36 pub fn CVPixelBufferPoolCreate(
37 allocator: CFAllocatorRef,
38 poolAttributes: CFDictionaryRef,
39 pixelBufferAttributes: CFDictionaryRef,
40 poolOut: *mut CVPixelBufferPoolRef,
41 ) -> CVReturn;
42 pub fn CVPixelBufferPoolGetAttributes(pool: CVPixelBufferPoolRef) -> CFDictionaryRef;
43 pub fn CVPixelBufferPoolGetPixelBufferAttributes(pool: CVPixelBufferPoolRef) -> CFDictionaryRef;
44 pub fn CVPixelBufferPoolCreatePixelBuffer(
45 allocator: CFAllocatorRef,
46 pixelBufferPool: CVPixelBufferPoolRef,
47 pixelBufferOut: *mut CVPixelBufferRef,
48 ) -> CVReturn;
49 pub fn CVPixelBufferPoolCreatePixelBufferWithAuxAttributes(
50 allocator: CFAllocatorRef,
51 pixelBufferPool: CVPixelBufferPoolRef,
52 auxAttributes: CFDictionaryRef,
53 pixelBufferOut: *mut CVPixelBufferRef,
54 ) -> CVReturn;
55 pub fn CVPixelBufferPoolFlush(pool: CVPixelBufferPoolRef, options: CVPixelBufferPoolFlushFlags);
56}
57
58pub enum CVPixelBufferPoolKeys {
59 MinimumBufferCount,
60 MaximumBufferAge,
61 AllocationThreshold,
62 FreeBufferNotification,
63}
64
65impl From<CVPixelBufferPoolKeys> for CFStringRef {
66 fn from(key: CVPixelBufferPoolKeys) -> CFStringRef {
67 match key {
68 CVPixelBufferPoolKeys::MinimumBufferCount => unsafe { kCVPixelBufferPoolMinimumBufferCountKey },
69 CVPixelBufferPoolKeys::MaximumBufferAge => unsafe { kCVPixelBufferPoolMaximumBufferAgeKey },
70 CVPixelBufferPoolKeys::AllocationThreshold => unsafe { kCVPixelBufferPoolAllocationThresholdKey },
71 CVPixelBufferPoolKeys::FreeBufferNotification => unsafe { kCVPixelBufferPoolFreeBufferNotification },
72 }
73 }
74}
75
76impl From<CVPixelBufferPoolKeys> for CFString {
77 fn from(key: CVPixelBufferPoolKeys) -> CFString {
78 unsafe { CFString::wrap_under_get_rule(CFStringRef::from(key)) }
79 }
80}
81
82pub struct CVPixelBufferPool(CVPixelBufferPoolRef);
83
84impl Drop for CVPixelBufferPool {
85 fn drop(&mut self) {
86 unsafe { CVPixelBufferPoolRelease(self.0) }
87 }
88}
89
90impl_TCFType!(CVPixelBufferPool, CVPixelBufferPoolRef, CVPixelBufferPoolGetTypeID);
91impl_CFTypeDescription!(CVPixelBufferPool);
92
93impl CVPixelBufferPool {
94 #[inline]
95 pub fn new(
96 pool_attributes: Option<&CFDictionary<CFString, CFType>>,
97 pixel_buffer_attributes: Option<&CFDictionary<CFString, CFType>>,
98 ) -> Result<CVPixelBufferPool, CVReturn> {
99 let mut pool: CVPixelBufferPoolRef = null_mut();
100 let status = unsafe {
101 CVPixelBufferPoolCreate(
102 kCFAllocatorDefault,
103 pool_attributes.map_or(null(), |attrs| attrs.as_concrete_TypeRef()),
104 pixel_buffer_attributes.map_or(null(), |attrs| attrs.as_concrete_TypeRef()),
105 &mut pool,
106 )
107 };
108 if status == kCVReturnSuccess {
109 Ok(unsafe { TCFType::wrap_under_create_rule(pool) })
110 } else {
111 Err(status)
112 }
113 }
114
115 #[inline]
116 pub fn get_attributes(&self) -> Option<CFDictionary<CFString, CFType>> {
117 unsafe {
118 let attributes = CVPixelBufferPoolGetAttributes(self.as_concrete_TypeRef());
119 if attributes.is_null() {
120 None
121 } else {
122 Some(TCFType::wrap_under_create_rule(attributes))
123 }
124 }
125 }
126
127 #[inline]
128 pub fn get_pixel_buffer_attributes(&self) -> Option<CFDictionary<CFString, CFType>> {
129 unsafe {
130 let attributes = CVPixelBufferPoolGetPixelBufferAttributes(self.as_concrete_TypeRef());
131 if attributes.is_null() {
132 None
133 } else {
134 Some(TCFType::wrap_under_create_rule(attributes))
135 }
136 }
137 }
138
139 #[inline]
140 pub fn create_pixel_buffer(&self) -> Result<CVPixelBuffer, CVReturn> {
141 let mut pixel_buffer: CVPixelBufferRef = null_mut();
142 let status = unsafe { CVPixelBufferPoolCreatePixelBuffer(kCFAllocatorDefault, self.as_concrete_TypeRef(), &mut pixel_buffer) };
143 if status == kCVReturnSuccess {
144 Ok(unsafe { TCFType::wrap_under_create_rule(pixel_buffer) })
145 } else {
146 Err(status)
147 }
148 }
149
150 #[inline]
151 pub fn create_pixel_buffer_with_aux_attributes(&self, auxAttributes: Option<&CFDictionary<CFString, CFType>>) -> Result<CVPixelBuffer, CVReturn> {
152 let mut pixel_buffer: CVPixelBufferRef = null_mut();
153 let status = unsafe {
154 CVPixelBufferPoolCreatePixelBufferWithAuxAttributes(
155 kCFAllocatorDefault,
156 self.as_concrete_TypeRef(),
157 auxAttributes.map_or(null(), |attrs| attrs.as_concrete_TypeRef()),
158 &mut pixel_buffer,
159 )
160 };
161 if status == kCVReturnSuccess {
162 Ok(unsafe { TCFType::wrap_under_create_rule(pixel_buffer) })
163 } else {
164 Err(status)
165 }
166 }
167}