1#![allow(clippy::missing_errors_doc)]
4
5use super::CVPixelBuffer;
21use crate::cf::{AsCFType, CFDictionary, CFString, CFType};
22use std::ffi::c_void;
23use std::fmt;
24
25#[link(name = "CoreVideo", kind = "framework")]
26extern "C" {
27 fn CVBufferRetain(buffer: *mut c_void) -> *mut c_void;
28 fn CVBufferRelease(buffer: *mut c_void);
29 fn CVBufferSetAttachment(buffer: *mut c_void, key: *mut c_void, value: *mut c_void, mode: u32);
30 fn CVBufferCopyAttachment(
31 buffer: *mut c_void,
32 key: *mut c_void,
33 attachment_mode: *mut u32,
34 ) -> *mut c_void;
35 fn CVBufferCopyAttachments(buffer: *mut c_void, attachment_mode: u32) -> *mut c_void;
36 fn CVBufferRemoveAllAttachments(buffer: *mut c_void);
37
38 fn CVImageBufferGetEncodedSize(image_buffer: *mut c_void) -> CVImageSize;
39 fn CVImageBufferGetDisplaySize(image_buffer: *mut c_void) -> CVImageSize;
40 fn CVImageBufferGetCleanRect(image_buffer: *mut c_void) -> CVImageRect;
41}
42
43#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
45#[repr(u32)]
46pub enum CVAttachmentMode {
47 ShouldNotPropagate = 0,
48 ShouldPropagate = 1,
49}
50
51#[repr(C)]
53#[derive(Debug, Clone, Copy, PartialEq)]
54pub struct CVImageSize {
55 pub width: f64,
56 pub height: f64,
57}
58
59#[repr(C)]
61#[derive(Debug, Clone, Copy, PartialEq)]
62pub struct CVImageRect {
63 pub x: f64,
64 pub y: f64,
65 pub width: f64,
66 pub height: f64,
67}
68
69pub struct CVBuffer(*mut c_void);
71
72impl CVBuffer {
73 #[must_use]
81 pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
82 if ptr.is_null() {
83 None
84 } else {
85 Some(Self(ptr))
86 }
87 }
88
89 #[must_use]
96 pub unsafe fn from_raw_borrowed(ptr: *mut c_void) -> Option<Self> {
97 if ptr.is_null() {
98 None
99 } else {
100 let retained = unsafe { CVBufferRetain(ptr) };
101 unsafe { Self::from_raw(retained) }
102 }
103 }
104
105 #[must_use]
107 pub fn from_pixel_buffer(pixel_buffer: &CVPixelBuffer) -> Option<Self> {
108 unsafe { Self::from_raw_borrowed(pixel_buffer.as_ptr()) }
109 }
110
111 #[must_use]
113 pub const fn as_ptr(&self) -> *mut c_void {
114 self.0
115 }
116
117 pub fn set_attachment(&self, key: &CFString, value: &dyn AsCFType, mode: CVAttachmentMode) {
119 unsafe { CVBufferSetAttachment(self.0, key.as_ptr(), value.as_ptr(), mode as u32) };
120 }
121
122 #[must_use]
124 pub fn attachment(&self, key: &CFString) -> Option<CFType> {
125 let mut attachment_mode = 0_u32;
126 let ptr = unsafe { CVBufferCopyAttachment(self.0, key.as_ptr(), &mut attachment_mode) };
127 unsafe { CFType::from_raw(ptr) }
128 }
129
130 #[must_use]
132 pub fn attachments(&self, mode: CVAttachmentMode) -> Option<CFDictionary> {
133 let ptr = unsafe { CVBufferCopyAttachments(self.0, mode as u32) };
134 unsafe { CFDictionary::from_raw(ptr) }
135 }
136
137 pub fn remove_all_attachments(&self) {
139 unsafe { CVBufferRemoveAllAttachments(self.0) };
140 }
141}
142
143crate::utils::retained::cf_retained!(
144 CVBuffer,
145 retain = CVBufferRetain,
146 release = CVBufferRelease,
147 drop = unchecked,
148);
149
150impl PartialEq for CVBuffer {
151 fn eq(&self, other: &Self) -> bool {
152 self.0 == other.0
153 }
154}
155
156impl Eq for CVBuffer {}
157
158impl std::hash::Hash for CVBuffer {
159 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
160 self.0.hash(state);
161 }
162}
163
164impl fmt::Debug for CVBuffer {
165 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
166 f.debug_struct("CVBuffer").field("ptr", &self.0).finish()
167 }
168}
169
170pub struct CVImageBuffer(*mut c_void);
172
173impl CVImageBuffer {
174 #[must_use]
182 pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
183 if ptr.is_null() {
184 None
185 } else {
186 Some(Self(ptr))
187 }
188 }
189
190 #[must_use]
197 pub unsafe fn from_raw_borrowed(ptr: *mut c_void) -> Option<Self> {
198 if ptr.is_null() {
199 None
200 } else {
201 let retained = unsafe { CVBufferRetain(ptr) };
202 unsafe { Self::from_raw(retained) }
203 }
204 }
205
206 #[must_use]
208 pub fn from_pixel_buffer(pixel_buffer: &CVPixelBuffer) -> Option<Self> {
209 unsafe { Self::from_raw_borrowed(pixel_buffer.as_ptr()) }
210 }
211
212 #[must_use]
214 pub const fn as_ptr(&self) -> *mut c_void {
215 self.0
216 }
217
218 #[must_use]
220 pub fn encoded_size(&self) -> CVImageSize {
221 unsafe { CVImageBufferGetEncodedSize(self.0) }
222 }
223
224 #[must_use]
226 pub fn display_size(&self) -> CVImageSize {
227 unsafe { CVImageBufferGetDisplaySize(self.0) }
228 }
229
230 #[must_use]
232 pub fn clean_rect(&self) -> CVImageRect {
233 unsafe { CVImageBufferGetCleanRect(self.0) }
234 }
235}
236
237crate::utils::retained::cf_retained!(
238 CVImageBuffer,
239 retain = CVBufferRetain,
240 release = CVBufferRelease,
241 drop = unchecked,
242);
243
244impl PartialEq for CVImageBuffer {
245 fn eq(&self, other: &Self) -> bool {
246 self.0 == other.0
247 }
248}
249
250impl Eq for CVImageBuffer {}
251
252impl std::hash::Hash for CVImageBuffer {
253 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
254 self.0.hash(state);
255 }
256}
257
258impl fmt::Debug for CVImageBuffer {
259 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
260 f.debug_struct("CVImageBuffer")
261 .field("ptr", &self.0)
262 .field("encoded_size", &self.encoded_size())
263 .finish()
264 }
265}