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