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]
75 pub fn from_raw(ptr: *mut c_void) -> Option<Self> {
76 if ptr.is_null() {
77 None
78 } else {
79 Some(Self(ptr))
80 }
81 }
82
83 #[must_use]
89 pub unsafe fn from_raw_retained(ptr: *mut c_void) -> Option<Self> {
90 if ptr.is_null() {
91 None
92 } else {
93 let retained = unsafe { CVBufferRetain(ptr) };
94 Self::from_raw(retained)
95 }
96 }
97
98 #[must_use]
100 pub fn from_pixel_buffer(pixel_buffer: &CVPixelBuffer) -> Option<Self> {
101 unsafe { Self::from_raw_retained(pixel_buffer.as_ptr()) }
102 }
103
104 #[must_use]
106 pub const fn as_ptr(&self) -> *mut c_void {
107 self.0
108 }
109
110 pub fn set_attachment(&self, key: &CFString, value: &dyn AsCFType, mode: CVAttachmentMode) {
112 unsafe { CVBufferSetAttachment(self.0, key.as_ptr(), value.as_ptr(), mode as u32) };
113 }
114
115 #[must_use]
117 pub fn attachment(&self, key: &CFString) -> Option<CFType> {
118 let mut attachment_mode = 0_u32;
119 let ptr = unsafe { CVBufferCopyAttachment(self.0, key.as_ptr(), &mut attachment_mode) };
120 CFType::from_raw(ptr)
121 }
122
123 #[must_use]
125 pub fn attachments(&self, mode: CVAttachmentMode) -> Option<CFDictionary> {
126 let ptr = unsafe { CVBufferCopyAttachments(self.0, mode as u32) };
127 CFDictionary::from_raw(ptr)
128 }
129
130 pub fn remove_all_attachments(&self) {
132 unsafe { CVBufferRemoveAllAttachments(self.0) };
133 }
134}
135
136impl Clone for CVBuffer {
137 fn clone(&self) -> Self {
138 let retained = unsafe { CVBufferRetain(self.0) };
139 Self(retained)
140 }
141}
142
143impl Drop for CVBuffer {
144 fn drop(&mut self) {
145 unsafe { CVBufferRelease(self.0) };
146 }
147}
148
149impl PartialEq for CVBuffer {
150 fn eq(&self, other: &Self) -> bool {
151 self.0 == other.0
152 }
153}
154
155impl Eq for CVBuffer {}
156
157impl std::hash::Hash for CVBuffer {
158 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
159 self.0.hash(state);
160 }
161}
162
163impl fmt::Debug for CVBuffer {
164 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
165 f.debug_struct("CVBuffer").field("ptr", &self.0).finish()
166 }
167}
168
169pub struct CVImageBuffer(*mut c_void);
171
172impl CVImageBuffer {
173 #[must_use]
175 pub fn from_raw(ptr: *mut c_void) -> Option<Self> {
176 if ptr.is_null() {
177 None
178 } else {
179 Some(Self(ptr))
180 }
181 }
182
183 #[must_use]
185 pub fn from_pixel_buffer(pixel_buffer: &CVPixelBuffer) -> Option<Self> {
186 let retained = unsafe { CVBufferRetain(pixel_buffer.as_ptr()) };
187 Self::from_raw(retained)
188 }
189
190 #[must_use]
192 pub const fn as_ptr(&self) -> *mut c_void {
193 self.0
194 }
195
196 #[must_use]
198 pub fn encoded_size(&self) -> CVImageSize {
199 unsafe { CVImageBufferGetEncodedSize(self.0) }
200 }
201
202 #[must_use]
204 pub fn display_size(&self) -> CVImageSize {
205 unsafe { CVImageBufferGetDisplaySize(self.0) }
206 }
207
208 #[must_use]
210 pub fn clean_rect(&self) -> CVImageRect {
211 unsafe { CVImageBufferGetCleanRect(self.0) }
212 }
213}
214
215impl Clone for CVImageBuffer {
216 fn clone(&self) -> Self {
217 let retained = unsafe { CVBufferRetain(self.0) };
218 Self(retained)
219 }
220}
221
222impl Drop for CVImageBuffer {
223 fn drop(&mut self) {
224 unsafe { CVBufferRelease(self.0) };
225 }
226}
227
228impl PartialEq for CVImageBuffer {
229 fn eq(&self, other: &Self) -> bool {
230 self.0 == other.0
231 }
232}
233
234impl Eq for CVImageBuffer {}
235
236impl std::hash::Hash for CVImageBuffer {
237 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
238 self.0.hash(state);
239 }
240}
241
242impl fmt::Debug for CVImageBuffer {
243 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
244 f.debug_struct("CVImageBuffer")
245 .field("ptr", &self.0)
246 .field("encoded_size", &self.encoded_size())
247 .finish()
248 }
249}