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