Skip to main content

core_video/
pixel_buffer.rs

1use std::ptr::{null, null_mut};
2
3use core_foundation::{
4    array::CFArrayRef,
5    base::{kCFAllocatorDefault, Boolean, CFAllocatorRef, CFType, CFTypeID, TCFType},
6    declare_TCFType,
7    dictionary::{CFDictionary, CFDictionaryRef},
8    impl_CFTypeDescription, impl_TCFType,
9    string::{CFString, CFStringRef},
10};
11use libc::{c_void, size_t};
12
13use crate::{
14    base::CVOptionFlags,
15    buffer::TCVBuffer,
16    image_buffer::{CVImageBufferRef, TCVImageBuffer},
17    r#return::{kCVReturnInvalidArgument, kCVReturnSuccess, CVReturn},
18    OSType,
19};
20
21pub type CVPixelBufferRef = CVImageBufferRef;
22
23#[inline]
24const fn fourcc(code: &[u8; 4]) -> u32 {
25    ((code[0] as u32) << 24) | ((code[1] as u32) << 16) | ((code[2] as u32) << 8) | ((code[3] as u32) << 0)
26}
27
28pub type CVPixelBufferLockFlags = u64;
29
30pub const kCVPixelFormatType_1Monochrome: OSType = 0x00000001; // 1 bit indexed
31pub const kCVPixelFormatType_2Indexed: OSType = 0x00000002; // 2 bit indexed
32pub const kCVPixelFormatType_4Indexed: OSType = 0x00000004; // 4 bit indexed
33pub const kCVPixelFormatType_8Indexed: OSType = 0x00000008; // 8 bit indexed
34pub const kCVPixelFormatType_1IndexedGray_WhiteIsZero: OSType = 0x00000021; // 1 bit indexed gray, white is zero
35pub const kCVPixelFormatType_2IndexedGray_WhiteIsZero: OSType = 0x00000022; // 2 bit indexed gray, white is zero
36pub const kCVPixelFormatType_4IndexedGray_WhiteIsZero: OSType = 0x00000024; // 4 bit indexed gray, white is zero
37pub const kCVPixelFormatType_8IndexedGray_WhiteIsZero: OSType = 0x00000028; // 8 bit indexed gray, white is zero
38pub const kCVPixelFormatType_16BE555: OSType = 0x00000010; // 16 bit BE RGB 555
39pub const kCVPixelFormatType_16LE555: OSType = fourcc(b"L555"); // 16 bit LE RGB 555
40pub const kCVPixelFormatType_16LE5551: OSType = fourcc(b"5551"); // 16 bit LE RGB 5551
41pub const kCVPixelFormatType_16BE565: OSType = fourcc(b"B565"); // 16 bit BE RGB 565
42pub const kCVPixelFormatType_16LE565: OSType = fourcc(b"L565"); // 16 bit LE RGB 565
43pub const kCVPixelFormatType_24RGB: OSType = 0x00000018; // 24 bit RGB
44pub const kCVPixelFormatType_24BGR: OSType = fourcc(b"24BG"); // 24 bit BGR
45pub const kCVPixelFormatType_32ARGB: OSType = 0x00000020; // 32 bit ARGB
46pub const kCVPixelFormatType_32BGRA: OSType = fourcc(b"BGRA"); // 32 bit BGRA
47pub const kCVPixelFormatType_32ABGR: OSType = fourcc(b"ABGR"); // 32 bit ABGR
48pub const kCVPixelFormatType_32RGBA: OSType = fourcc(b"RGBA"); // 32 bit RGBA
49pub const kCVPixelFormatType_64ARGB: OSType = fourcc(b"b64a"); // 64 bit ARGB, 16-bit big-endian samples
50pub const kCVPixelFormatType_48RGB: OSType = fourcc(b"b48r"); // 48 bit RGB, 16-bit big-endian samples
51pub const kCVPixelFormatType_32AlphaGray: OSType = fourcc(b"b32a"); // 32 bit AlphaGray, 16-bit big-endian samples, black is zero
52pub const kCVPixelFormatType_16Gray: OSType = fourcc(b"b16g"); // 16 bit Grayscale, 16-bit big-endian samples, black is zero
53pub const kCVPixelFormatType_30RGB: OSType = fourcc(b"R10k"); // 30 bit RGB, 10-bit big-endian samples, 2 unused padding bits (at least
54                                                              // significant end).
55pub const kCVPixelFormatType_422YpCbCr8: OSType = fourcc(b"2vuy"); // Component Y'CbCr 8-bit 4:2:2, ordered Cb Y'0 Cr Y'1
56pub const kCVPixelFormatType_4444YpCbCrA8: OSType = fourcc(b"v408"); // Component Y'CbCrA 8-bit 4:4:4:4, ordered Cb Y' Cr A
57pub const kCVPixelFormatType_4444YpCbCrA8R: OSType = fourcc(b"r408"); // Component Y'CbCrA 8-bit 4:4:4:4, rendering format. full range alpha, zero
58                                                                      // biased YUV, ordered A Y' Cb Cr
59pub const kCVPixelFormatType_4444AYpCbCr8: OSType = fourcc(b"y408"); // Component Y'CbCrA 8-bit 4:4:4:4, ordered A Y' Cb Cr, full range alpha, video
60                                                                     // range Y'CbCr.
61pub const kCVPixelFormatType_4444AYpCbCr16: OSType = fourcc(b"y416"); // Component Y'CbCrA 16-bit 4:4:4:4, ordered A Y' Cb Cr, full range alpha, video
62                                                                      // range Y'CbCr, 16-bit little-endian samples.
63pub const kCVPixelFormatType_4444AYpCbCrFloat: OSType = fourcc(b"r4fl"); // Component AY'CbCr single precision floating-point 4:4:4:4
64pub const kCVPixelFormatType_444YpCbCr8: OSType = fourcc(b"v308"); // Component Y'CbCr 8-bit 4:4:4
65pub const kCVPixelFormatType_422YpCbCr16: OSType = fourcc(b"v216"); // Component Y'CbCr 10,12,14,16-bit 4:2:2
66pub const kCVPixelFormatType_422YpCbCr10: OSType = fourcc(b"v210"); // Component Y'CbCr 10-bit 4:2:2
67pub const kCVPixelFormatType_444YpCbCr10: OSType = fourcc(b"v410"); // Component Y'CbCr 10-bit 4:4:4
68pub const kCVPixelFormatType_420YpCbCr8Planar: OSType = fourcc(b"y420"); // Planar Component Y'CbCr 8-bit 4:2:0.  baseAddr points to a big-endian
69                                                                         // CVPlanarPixelBufferInfo_YCbCrPlanar struct
70pub const kCVPixelFormatType_420YpCbCr8PlanarFullRange: OSType = fourcc(b"f420"); // Planar Component Y'CbCr 8-bit 4:2:0, full range.  baseAddr points to a
71                                                                                  // big-endian CVPlanarPixelBufferInfo_YCbCrPlanar struct
72pub const kCVPixelFormatType_422YpCbCr_4A_8BiPlanar: OSType = fourcc(b"a2vy"); // First plane: Video-range Component Y'CbCr 8-bit 4:2:2, ordered Cb Y'0 Cr Y'1;
73                                                                               // second plane: alpha 8-bit 0-255
74pub const kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange: OSType = fourcc(b"420v"); // Bi-Planar Component Y'CbCr 8-bit 4:2:0, video-range (luma=[16,235]
75                                                                                     // chroma=[16,240]).  baseAddr points to a big-endian
76                                                                                     // CVPlanarPixelBufferInfo_YCbCrBiPlanar struct
77pub const kCVPixelFormatType_420YpCbCr8BiPlanarFullRange: OSType = fourcc(b"420f"); // Bi-Planar Component Y'CbCr 8-bit 4:2:0, full-range (luma=[0,255]
78                                                                                    // chroma=[1,255]).  baseAddr points to a big-endian
79                                                                                    // CVPlanarPixelBufferInfo_YCbCrBiPlanar struct
80pub const kCVPixelFormatType_422YpCbCr8BiPlanarVideoRange: OSType = fourcc(b"422v"); // Bi-Planar Component Y'CbCr 8-bit 4:2:2, video-range (luma=[16,235]
81                                                                                     // chroma=[16,240]).  baseAddr points to a big-endian
82                                                                                     // CVPlanarPixelBufferInfo_YCbCrBiPlanar struct
83pub const kCVPixelFormatType_422YpCbCr8BiPlanarFullRange: OSType = fourcc(b"422f"); // Bi-Planar Component Y'CbCr 8-bit 4:2:2, full-range (luma=[0,255]
84                                                                                    // chroma=[1,255]).  baseAddr points to a big-endian
85                                                                                    // CVPlanarPixelBufferInfo_YCbCrBiPlanar struct
86pub const kCVPixelFormatType_444YpCbCr8BiPlanarVideoRange: OSType = fourcc(b"444v"); // Bi-Planar Component Y'CbCr 8-bit 4:4:4, video-range (luma=[16,235]
87                                                                                     // chroma=[16,240]).  baseAddr points to a big-endian
88                                                                                     // CVPlanarPixelBufferInfo_YCbCrBiPlanar struct
89pub const kCVPixelFormatType_444YpCbCr8BiPlanarFullRange: OSType = fourcc(b"444f"); // Bi-Planar Component Y'CbCr 8-bit 4:4:4, full-range (luma=[0,255]
90                                                                                    // chroma=[1,255]).  baseAddr points to a big-endian
91                                                                                    // CVPlanarPixelBufferInfo_YCbCrBiPlanar struct
92pub const kCVPixelFormatType_422YpCbCr8_yuvs: OSType = fourcc(b"yuvs"); // Component Y'CbCr 8-bit 4:2:2, ordered Y'0 Cb Y'1 Cr
93pub const kCVPixelFormatType_422YpCbCr8FullRange: OSType = fourcc(b"yuvf"); // Component Y'CbCr 8-bit 4:2:2, full range, ordered Y'0 Cb Y'1 Cr
94pub const kCVPixelFormatType_OneComponent8: OSType = fourcc(b"L008"); // 8 bit one component, black is zero
95pub const kCVPixelFormatType_TwoComponent8: OSType = fourcc(b"2C08"); // 8 bit two component, black is zero
96pub const kCVPixelFormatType_30RGBLEPackedWideGamut: OSType = fourcc(b"w30r"); // little-endian RGB101010, 2 MSB are zero, wide-gamut (384-895)
97pub const kCVPixelFormatType_ARGB2101010LEPacked: OSType = fourcc(b"l10r"); // little-endian ARGB2101010 full-range ARGB
98pub const kCVPixelFormatType_40ARGBLEWideGamut: OSType = fourcc(b"w40a"); // little-endian ARGB10101010, each 10 bits in the MSBs of 16bits, wide-gamut
99                                                                          // (384-895, including alpha)
100pub const kCVPixelFormatType_40ARGBLEWideGamutPremultiplied: OSType = fourcc(b"w40m"); // little-endian ARGB10101010, each 10 bits in the MSBs of 16bits, wide-gamut
101                                                                                       // (384-895, including alpha). Alpha premultiplied
102pub const kCVPixelFormatType_OneComponent10: OSType = fourcc(b"L010"); // 10 bit little-endian one component, stored as 10 MSBs of 16 bits, black is
103                                                                       // zero
104pub const kCVPixelFormatType_OneComponent12: OSType = fourcc(b"L012"); // 12 bit little-endian one component, stored as 12 MSBs of 16 bits, black is
105                                                                       // zero
106pub const kCVPixelFormatType_OneComponent16: OSType = fourcc(b"L016"); // 16 bit little-endian one component, black is zero
107pub const kCVPixelFormatType_TwoComponent16: OSType = fourcc(b"2C16"); // 16 bit little-endian two component, black is zero
108pub const kCVPixelFormatType_OneComponent16Half: OSType = fourcc(b"L00h"); // 16 bit one component IEEE half-precision float, 16-bit little-endian samples
109pub const kCVPixelFormatType_OneComponent32Float: OSType = fourcc(b"L00f"); // 32 bit one component IEEE float, 32-bit little-endian samples
110pub const kCVPixelFormatType_TwoComponent16Half: OSType = fourcc(b"2C0h"); // 16 bit two component IEEE half-precision float, 16-bit little-endian samples
111pub const kCVPixelFormatType_TwoComponent32Float: OSType = fourcc(b"2C0f"); // 32 bit two component IEEE float, 32-bit little-endian samples
112pub const kCVPixelFormatType_64RGBAHalf: OSType = fourcc(b"RGhA"); // 64 bit RGBA IEEE half-precision float, 16-bit little-endian samples
113pub const kCVPixelFormatType_128RGBAFloat: OSType = fourcc(b"RGfA"); // 128 bit RGBA IEEE float, 32-bit little-endian samples
114pub const kCVPixelFormatType_14Bayer_GRBG: OSType = fourcc(b"grb4"); // Bayer 14-bit Little-Endian, packed in 16-bits, ordered G R G R... alternating
115                                                                     // with B G B G...
116pub const kCVPixelFormatType_14Bayer_RGGB: OSType = fourcc(b"rgg4"); // Bayer 14-bit Little-Endian, packed in 16-bits, ordered R G R G... alternating
117                                                                     // with G B G B...
118pub const kCVPixelFormatType_14Bayer_BGGR: OSType = fourcc(b"bgg4"); // Bayer 14-bit Little-Endian, packed in 16-bits, ordered B G B G... alternating
119                                                                     // with G R G R...
120pub const kCVPixelFormatType_14Bayer_GBRG: OSType = fourcc(b"gbr4"); // Bayer 14-bit Little-Endian, packed in 16-bits, ordered G B G B... alternating
121                                                                     // with R G R G...
122pub const kCVPixelFormatType_DisparityFloat16: OSType = fourcc(b"hdis"); // IEEE754-2008 binary16 (half float), describing the normalized shift when
123                                                                         // comparing two images. Units are 1/meters: ( pixelShift / (pixelFocalLength *
124                                                                         // baselineInMeters) )
125pub const kCVPixelFormatType_DisparityFloat32: OSType = fourcc(b"fdis"); // IEEE754-2008 binary32 float, describing the normalized shift when comparing
126                                                                         // two images. Units are 1/meters: ( pixelShift / (pixelFocalLength *
127                                                                         // baselineInMeters) )
128pub const kCVPixelFormatType_DepthFloat16: OSType = fourcc(b"hdep"); // IEEE754-2008 binary16 (half float), describing the depth (distance to an
129                                                                     // object) in meters
130pub const kCVPixelFormatType_DepthFloat32: OSType = fourcc(b"fdep"); // IEEE754-2008 binary32 float, describing the depth (distance to an object) in
131                                                                     // meters
132pub const kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange: OSType = fourcc(b"x420"); // 2 plane YCbCr10 4:2:0, each 10 bits in the MSBs of 16bits, video-range
133                                                                                      // (luma=[64,940] chroma=[64,960])
134pub const kCVPixelFormatType_422YpCbCr10BiPlanarVideoRange: OSType = fourcc(b"x422"); // 2 plane YCbCr10 4:2:2, each 10 bits in the MSBs of 16bits, video-range
135                                                                                      // (luma=[64,940] chroma=[64,960])
136pub const kCVPixelFormatType_444YpCbCr10BiPlanarVideoRange: OSType = fourcc(b"x444"); // 2 plane YCbCr10 4:4:4, each 10 bits in the MSBs of 16bits, video-range
137                                                                                      // (luma=[64,940] chroma=[64,960])
138pub const kCVPixelFormatType_420YpCbCr10BiPlanarFullRange: OSType = fourcc(b"xf20"); // 2 plane YCbCr10 4:2:0, each 10 bits in the MSBs of 16bits, full-range (Y
139                                                                                     // range 0-1023)
140pub const kCVPixelFormatType_422YpCbCr10BiPlanarFullRange: OSType = fourcc(b"xf22"); // 2 plane YCbCr10 4:2:2, each 10 bits in the MSBs of 16bits, full-range (Y
141                                                                                     // range 0-1023)
142pub const kCVPixelFormatType_444YpCbCr10BiPlanarFullRange: OSType = fourcc(b"xf44"); // 2 plane YCbCr10 4:4:4, each 10 bits in the MSBs of 16bits, full-range (Y
143                                                                                     // range 0-1023)
144pub const kCVPixelFormatType_420YpCbCr8VideoRange_8A_TriPlanar: OSType = fourcc(b"v0a8"); // first and second planes as per 420YpCbCr8BiPlanarVideoRange (420v), alpha 8
145                                                                                          // bits in third plane full-range.  No CVPlanarPixelBufferInfo struct.
146pub const kCVPixelFormatType_16VersatileBayer: OSType = fourcc(b"bp16"); // Single plane Bayer 16-bit little-endian sensor element ("sensel") samples
147                                                                         // from full-size decoding of ProRes RAW images; Bayer pattern (sensel ordering)
148                                                                         // and other raw conversion information is described via buffer attachments
149pub const kCVPixelFormatType_64RGBA_DownscaledProResRAW: OSType = fourcc(b"bp64"); // Single plane 64-bit RGBA (16-bit little-endian samples) from downscaled
150                                                                                   // decoding of ProRes RAW images; components--which may not be co-sited with one
151                                                                                   // another--are sensel values and require raw conversion, information for which
152                                                                                   // is described via buffer attachments
153pub const kCVPixelFormatType_422YpCbCr16BiPlanarVideoRange: OSType = fourcc(b"sv22"); // 2 plane YCbCr16 4:2:2, video-range (luma=[4096,60160] chroma=[4096,61440])
154pub const kCVPixelFormatType_444YpCbCr16BiPlanarVideoRange: OSType = fourcc(b"sv44"); // 2 plane YCbCr16 4:4:4, video-range (luma=[4096,60160] chroma=[4096,61440])
155pub const kCVPixelFormatType_444YpCbCr16VideoRange_16A_TriPlanar: OSType = fourcc(b"s4as"); // 3 plane video-range YCbCr16 4:4:4 with 16-bit full-range alpha
156                                                                                            // (luma=[4096,60160] chroma=[4096,61440] alpha=[0,65535]).  No
157                                                                                            // CVPlanarPixelBufferInfo struct.
158
159pub const kCVPixelFormatType_Lossless_32BGRA: OSType = fourcc(b"&BGA"); // Lossless-compressed form of kCVPixelFormatType_32BGRA.
160
161// Lossless-compressed Bi-planar YCbCr pixel format types
162pub const kCVPixelFormatType_Lossless_420YpCbCr8BiPlanarVideoRange: OSType = fourcc(b"&8v0"); // Lossless-compressed form of kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange.
163                                                                                              // No CVPlanarPixelBufferInfo struct.
164pub const kCVPixelFormatType_Lossless_420YpCbCr8BiPlanarFullRange: OSType = fourcc(b"&8f0"); // Lossless-compressed form of kCVPixelFormatType_420YpCbCr8BiPlanarFullRange.
165                                                                                             // No CVPlanarPixelBufferInfo struct.
166pub const kCVPixelFormatType_Lossless_420YpCbCr10PackedBiPlanarVideoRange: OSType = fourcc(b"&xv0"); // Lossless-compressed-packed form of
167                                                                                                     // kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange.  No CVPlanarPixelBufferInfo
168                                                                                                     // struct. Format is compressed-packed with no padding bits between pixels.
169pub const kCVPixelFormatType_Lossless_422YpCbCr10PackedBiPlanarVideoRange: OSType = fourcc(b"&xv2"); // Lossless-compressed form of kCVPixelFormatType_422YpCbCr10BiPlanarVideoRange.
170                                                                                                     // No CVPlanarPixelBufferInfo struct. Format is compressed-packed with no
171                                                                                                     // padding bits between pixels.
172
173pub const kCVPixelFormatType_Lossy_32BGRA: OSType = fourcc(b"-BGA"); // Lossy-compressed form of kCVPixelFormatType_32BGRA. No
174                                                                     // CVPlanarPixelBufferInfo struct.
175pub const kCVPixelFormatType_Lossy_420YpCbCr8BiPlanarVideoRange: OSType = fourcc(b"-8v0"); // Lossy-compressed form of kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange.  No
176                                                                                           // CVPlanarPixelBufferInfo struct.
177pub const kCVPixelFormatType_Lossy_420YpCbCr8BiPlanarFullRange: OSType = fourcc(b"-8f0"); // Lossy-compressed form of kCVPixelFormatType_420YpCbCr8BiPlanarFullRange.  No
178                                                                                          // CVPlanarPixelBufferInfo struct.
179pub const kCVPixelFormatType_Lossy_420YpCbCr10PackedBiPlanarVideoRange: OSType = fourcc(b"-xv0"); // Lossy-compressed form of kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange.
180                                                                                                  // No CVPlanarPixelBufferInfo struct. Format is compressed-packed with no
181                                                                                                  // padding bits between pixels.
182pub const kCVPixelFormatType_Lossy_422YpCbCr10PackedBiPlanarVideoRange: OSType = fourcc(b"-xv2"); // Lossy-compressed form of kCVPixelFormatType_422YpCbCr10BiPlanarVideoRange.
183                                                                                                  // No CVPlanarPixelBufferInfo struct. Format is compressed-packed with no
184                                                                                                  // padding bits between pixels.
185
186pub const kCVPixelBufferLock_ReadOnly: CVPixelBufferLockFlags = 0x00000001;
187
188#[repr(C)]
189pub struct CVPlanarComponentInfo {
190    pub offset: i32,
191    pub rowBytes: u32,
192}
193
194#[repr(C)]
195pub struct CVPlanarPixelBufferInfo {
196    pub componentInfo: [CVPlanarComponentInfo; 1],
197}
198
199#[repr(C)]
200pub struct CVPlanarPixelBufferInfo_YCbCrPlanar {
201    pub componentInfoY: CVPlanarComponentInfo,
202    pub componentInfoCb: CVPlanarComponentInfo,
203    pub componentInfoCr: CVPlanarComponentInfo,
204}
205
206#[repr(C)]
207pub struct CVPlanarPixelBufferInfo_YCbCrBiPlanar {
208    pub componentInfoY: CVPlanarComponentInfo,
209    pub componentInfoCbCr: CVPlanarComponentInfo,
210}
211
212pub type CVPixelBufferReleaseBytesCallback = extern "C" fn(releaseRefCon: *mut c_void, baseAddress: *const *const c_void);
213pub type CVPixelBufferReleasePlanarBytesCallback = extern "C" fn(
214    releaseRefCon: *mut c_void,
215    dataPtr: *const *const c_void,
216    dataSize: size_t,
217    numberOfPlanes: size_t,
218    planeAddresses: *const *const c_void,
219);
220
221extern "C" {
222    pub static kCVPixelBufferPixelFormatTypeKey: CFStringRef;
223    pub static kCVPixelBufferMemoryAllocatorKey: CFStringRef;
224    pub static kCVPixelBufferWidthKey: CFStringRef;
225    pub static kCVPixelBufferHeightKey: CFStringRef;
226    pub static kCVPixelBufferExtendedPixelsLeftKey: CFStringRef;
227    pub static kCVPixelBufferExtendedPixelsTopKey: CFStringRef;
228    pub static kCVPixelBufferExtendedPixelsRightKey: CFStringRef;
229    pub static kCVPixelBufferExtendedPixelsBottomKey: CFStringRef;
230    pub static kCVPixelBufferBytesPerRowAlignmentKey: CFStringRef;
231    pub static kCVPixelBufferCGBitmapContextCompatibilityKey: CFStringRef;
232    pub static kCVPixelBufferCGImageCompatibilityKey: CFStringRef;
233    pub static kCVPixelBufferOpenGLCompatibilityKey: CFStringRef;
234    pub static kCVPixelBufferPlaneAlignmentKey: CFStringRef;
235    pub static kCVPixelBufferIOSurfacePropertiesKey: CFStringRef;
236    #[cfg(target_os = "ios")]
237    pub static kCVPixelBufferOpenGLESCompatibilityKey: CFStringRef;
238    pub static kCVPixelBufferMetalCompatibilityKey: CFStringRef;
239    #[cfg(target_os = "macos")]
240    pub static kCVPixelBufferOpenGLTextureCacheCompatibilityKey: CFStringRef;
241    #[cfg(target_os = "ios")]
242    pub static kCVPixelBufferOpenGLESTextureCacheCompatibilityKey: CFStringRef;
243    pub static kCVPixelBufferVersatileBayerKey_BayerPattern: CFStringRef;
244}
245
246pub const kCVVersatileBayer_BayerPattern_RGGB: u32 = 0;
247pub const kCVVersatileBayer_BayerPattern_GRBG: u32 = 1;
248pub const kCVVersatileBayer_BayerPattern_GBRG: u32 = 2;
249pub const kCVVersatileBayer_BayerPattern_BGGR: u32 = 3;
250
251extern "C" {
252    pub static kCVPixelBufferProResRAWKey_SenselSitingOffsets: CFStringRef;
253    pub static kCVPixelBufferProResRAWKey_BlackLevel: CFStringRef;
254    pub static kCVPixelBufferProResRAWKey_WhiteLevel: CFStringRef;
255    pub static kCVPixelBufferProResRAWKey_WhiteBalanceCCT: CFStringRef;
256    pub static kCVPixelBufferProResRAWKey_WhiteBalanceRedFactor: CFStringRef;
257    pub static kCVPixelBufferProResRAWKey_WhiteBalanceBlueFactor: CFStringRef;
258    pub static kCVPixelBufferProResRAWKey_ColorMatrix: CFStringRef;
259    pub static kCVPixelBufferProResRAWKey_GainFactor: CFStringRef;
260    pub static kCVPixelBufferProResRAWKey_RecommendedCrop: CFStringRef;
261    pub static kCVPixelBufferProResRAWKey_MetadataExtension: CFStringRef;
262}
263
264extern "C" {
265    pub fn CVPixelBufferGetTypeID() -> CFTypeID;
266    pub fn CVPixelBufferRetain(texture: CVPixelBufferRef) -> CVPixelBufferRef;
267    pub fn CVPixelBufferRelease(texture: CVPixelBufferRef);
268    pub fn CVPixelBufferCreateResolvedAttributesDictionary(
269        allocator: CFAllocatorRef,
270        attributes: CFArrayRef,
271        resolvedDictionaryOut: *mut CFDictionaryRef,
272    ) -> CVReturn;
273    pub fn CVPixelBufferCreate(
274        allocator: CFAllocatorRef,
275        width: size_t,
276        height: size_t,
277        pixelFormatType: OSType,
278        pixelBufferAttributes: CFDictionaryRef,
279        pixelBufferOut: *mut CVPixelBufferRef,
280    ) -> CVReturn;
281    pub fn CVPixelBufferCreateWithBytes(
282        allocator: CFAllocatorRef,
283        width: size_t,
284        height: size_t,
285        pixelFormatType: OSType,
286        baseAddress: *mut c_void,
287        bytesPerRow: size_t,
288        releaseCallback: CVPixelBufferReleaseBytesCallback,
289        releaseRefCon: *mut c_void,
290        pixelBufferAttributes: CFDictionaryRef,
291        pixelBufferOut: *mut CVPixelBufferRef,
292    ) -> CVReturn;
293    pub fn CVPixelBufferCreateWithPlanarBytes(
294        allocator: CFAllocatorRef,
295        width: size_t,
296        height: size_t,
297        pixelFormatType: OSType,
298        dataPtr: *mut c_void,
299        dataSize: size_t,
300        numberOfPlanes: size_t,
301        planeBaseAddress: *const *mut c_void,
302        planeWidth: *const size_t,
303        planeHeight: *const size_t,
304        planeBytesPerRow: *const size_t,
305        releaseCallback: CVPixelBufferReleasePlanarBytesCallback,
306        releaseRefCon: *mut c_void,
307        pixelBufferAttributes: CFDictionaryRef,
308        pixelBufferOut: *mut CVPixelBufferRef,
309    ) -> CVReturn;
310    pub fn CVPixelBufferLockBaseAddress(pixelBuffer: CVPixelBufferRef, lockFlags: CVOptionFlags) -> CVReturn;
311    pub fn CVPixelBufferUnlockBaseAddress(pixelBuffer: CVPixelBufferRef, unlockFlags: CVOptionFlags) -> CVReturn;
312    pub fn CVPixelBufferGetWidth(pixelBuffer: CVPixelBufferRef) -> size_t;
313    pub fn CVPixelBufferGetHeight(pixelBuffer: CVPixelBufferRef) -> size_t;
314    pub fn CVPixelBufferGetPixelFormatType(pixelBuffer: CVPixelBufferRef) -> OSType;
315
316    pub fn CVPixelBufferGetBaseAddress(pixelBuffer: CVPixelBufferRef) -> *mut c_void;
317    pub fn CVPixelBufferGetBytesPerRow(pixelBuffer: CVPixelBufferRef) -> size_t;
318    pub fn CVPixelBufferGetDataSize(pixelBuffer: CVPixelBufferRef) -> size_t;
319    pub fn CVPixelBufferIsPlanar(pixelBuffer: CVPixelBufferRef) -> Boolean;
320    pub fn CVPixelBufferGetPlaneCount(pixelBuffer: CVPixelBufferRef) -> size_t;
321    pub fn CVPixelBufferGetWidthOfPlane(pixelBuffer: CVPixelBufferRef, planeIndex: size_t) -> size_t;
322    pub fn CVPixelBufferGetHeightOfPlane(pixelBuffer: CVPixelBufferRef, planeIndex: size_t) -> size_t;
323    pub fn CVPixelBufferGetBaseAddressOfPlane(pixelBuffer: CVPixelBufferRef, planeIndex: size_t) -> *mut c_void;
324    pub fn CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer: CVPixelBufferRef, planeIndex: size_t) -> size_t;
325    pub fn CVPixelBufferGetExtendedPixels(
326        pixelBuffer: CVPixelBufferRef,
327        extraColumnsOnLeft: *const size_t,
328        extraColumnsOnRight: *const size_t,
329        extraRowsOnTop: *const size_t,
330        extraRowsOnBottom: *const size_t,
331    );
332    pub fn CVPixelBufferFillExtendedPixels(pixelBuffer: CVPixelBufferRef) -> CVReturn;
333    pub fn CVPixelBufferCopyCreationAttributes(pixelBuffer: CVPixelBufferRef) -> CFDictionaryRef;
334}
335
336pub enum CVPixelBufferKeys {
337    PixelFormatType,
338    MemoryAllocator,
339    Width,
340    Height,
341    ExtendedPixelsLeft,
342    ExtendedPixelsTop,
343    ExtendedPixelsRight,
344    ExtendedPixelsBottom,
345    BytesPerRowAlignment,
346    CGBitmapContextCompatibility,
347    CGImageCompatibility,
348    OpenGLCompatibility,
349    PlaneAlignment,
350    IOSurfaceProperties,
351    #[cfg(target_os = "ios")]
352    OpenGLESCompatibility,
353    MetalCompatibility,
354    #[cfg(target_os = "macos")]
355    OpenGLTextureCacheCompatibility,
356    #[cfg(target_os = "ios")]
357    OpenGLESTextureCacheCompatibility,
358    VersatileBayerKey_BayerPattern,
359}
360
361impl From<CVPixelBufferKeys> for CFStringRef {
362    fn from(key: CVPixelBufferKeys) -> Self {
363        unsafe {
364            match key {
365                CVPixelBufferKeys::PixelFormatType => kCVPixelBufferPixelFormatTypeKey,
366                CVPixelBufferKeys::MemoryAllocator => kCVPixelBufferMemoryAllocatorKey,
367                CVPixelBufferKeys::Width => kCVPixelBufferWidthKey,
368                CVPixelBufferKeys::Height => kCVPixelBufferHeightKey,
369                CVPixelBufferKeys::ExtendedPixelsLeft => kCVPixelBufferExtendedPixelsLeftKey,
370                CVPixelBufferKeys::ExtendedPixelsTop => kCVPixelBufferExtendedPixelsTopKey,
371                CVPixelBufferKeys::ExtendedPixelsRight => kCVPixelBufferExtendedPixelsRightKey,
372                CVPixelBufferKeys::ExtendedPixelsBottom => kCVPixelBufferExtendedPixelsBottomKey,
373                CVPixelBufferKeys::BytesPerRowAlignment => kCVPixelBufferBytesPerRowAlignmentKey,
374                CVPixelBufferKeys::CGBitmapContextCompatibility => kCVPixelBufferCGBitmapContextCompatibilityKey,
375                CVPixelBufferKeys::CGImageCompatibility => kCVPixelBufferCGImageCompatibilityKey,
376                CVPixelBufferKeys::OpenGLCompatibility => kCVPixelBufferOpenGLCompatibilityKey,
377                CVPixelBufferKeys::PlaneAlignment => kCVPixelBufferPlaneAlignmentKey,
378                CVPixelBufferKeys::IOSurfaceProperties => kCVPixelBufferIOSurfacePropertiesKey,
379                #[cfg(target_os = "ios")]
380                CVPixelBufferKeys::OpenGLESCompatibility => kCVPixelBufferOpenGLESCompatibilityKey,
381                CVPixelBufferKeys::MetalCompatibility => kCVPixelBufferMetalCompatibilityKey,
382                #[cfg(target_os = "macos")]
383                CVPixelBufferKeys::OpenGLTextureCacheCompatibility => kCVPixelBufferOpenGLTextureCacheCompatibilityKey,
384                #[cfg(target_os = "ios")]
385                CVPixelBufferKeys::OpenGLESTextureCacheCompatibility => kCVPixelBufferOpenGLESTextureCacheCompatibilityKey,
386                CVPixelBufferKeys::VersatileBayerKey_BayerPattern => kCVPixelBufferVersatileBayerKey_BayerPattern,
387            }
388        }
389    }
390}
391
392impl From<CVPixelBufferKeys> for CFString {
393    fn from(key: CVPixelBufferKeys) -> Self {
394        unsafe { CFString::wrap_under_get_rule(CFStringRef::from(key)) }
395    }
396}
397
398declare_TCFType!(CVPixelBuffer, CVPixelBufferRef);
399impl_TCFType!(CVPixelBuffer, CVPixelBufferRef, CVPixelBufferGetTypeID);
400impl_CFTypeDescription!(CVPixelBuffer);
401
402impl TCVBuffer for CVPixelBuffer {}
403impl TCVImageBuffer for CVPixelBuffer {}
404
405impl CVPixelBuffer {
406    #[inline]
407    pub fn new(
408        pixel_format: OSType,
409        width: usize,
410        height: usize,
411        options: Option<&CFDictionary<CFString, CFType>>,
412    ) -> Result<CVPixelBuffer, CVReturn> {
413        let mut pixel_buffer: CVPixelBufferRef = null_mut();
414        let status = unsafe {
415            CVPixelBufferCreate(
416                kCFAllocatorDefault,
417                width,
418                height,
419                pixel_format,
420                options.map_or(null(), |options| options.as_concrete_TypeRef()),
421                &mut pixel_buffer,
422            )
423        };
424        if status == kCVReturnSuccess {
425            Ok(unsafe { TCFType::wrap_under_create_rule(pixel_buffer) })
426        } else {
427            Err(status)
428        }
429    }
430
431    #[inline]
432    pub unsafe fn new_with_bytes(
433        pixel_format: OSType,
434        width: usize,
435        height: usize,
436        base_address: *mut c_void,
437        bytes_per_row: usize,
438        release_callback: CVPixelBufferReleaseBytesCallback,
439        release_ref_con: *mut c_void,
440        options: Option<&CFDictionary<CFString, CFType>>,
441    ) -> Result<CVPixelBuffer, CVReturn> {
442        let mut pixel_buffer: CVPixelBufferRef = null_mut();
443        let status = unsafe {
444            CVPixelBufferCreateWithBytes(
445                kCFAllocatorDefault,
446                width,
447                height,
448                pixel_format,
449                base_address,
450                bytes_per_row,
451                release_callback,
452                release_ref_con,
453                options.map_or(null(), |options| options.as_concrete_TypeRef()),
454                &mut pixel_buffer,
455            )
456        };
457        if status == kCVReturnSuccess {
458            Ok(unsafe { TCFType::wrap_under_create_rule(pixel_buffer) })
459        } else {
460            Err(status)
461        }
462    }
463
464    #[inline]
465    pub unsafe fn new_with_planar_bytes(
466        pixel_format: OSType,
467        width: usize,
468        height: usize,
469        data_ptr: *mut c_void,
470        data_size: usize,
471        number_of_planes: usize,
472        plane_base_address: Vec<*mut c_void>,
473        plane_width: Vec<usize>,
474        plane_height: Vec<usize>,
475        plane_bytes_per_row: Vec<usize>,
476        release_callback: CVPixelBufferReleasePlanarBytesCallback,
477        release_ref_con: *mut c_void,
478        options: Option<&CFDictionary<CFString, CFType>>,
479    ) -> Result<CVPixelBuffer, CVReturn> {
480        if plane_base_address.len() != number_of_planes ||
481            plane_width.len() != number_of_planes ||
482            plane_height.len() != number_of_planes ||
483            plane_bytes_per_row.len() != number_of_planes
484        {
485            return Err(kCVReturnInvalidArgument);
486        }
487        let mut pixel_buffer: CVPixelBufferRef = null_mut();
488        let status = unsafe {
489            CVPixelBufferCreateWithPlanarBytes(
490                kCFAllocatorDefault,
491                width,
492                height,
493                pixel_format,
494                data_ptr,
495                data_size,
496                number_of_planes,
497                plane_base_address.as_ptr(),
498                plane_width.as_ptr(),
499                plane_height.as_ptr(),
500                plane_bytes_per_row.as_ptr(),
501                release_callback,
502                release_ref_con,
503                options.map_or(null(), |options| options.as_concrete_TypeRef()),
504                &mut pixel_buffer,
505            )
506        };
507        if status == kCVReturnSuccess {
508            Ok(unsafe { TCFType::wrap_under_create_rule(pixel_buffer) })
509        } else {
510            Err(status)
511        }
512    }
513
514    #[inline]
515    pub fn lock_base_address(&self, options: CVPixelBufferLockFlags) -> CVReturn {
516        unsafe { CVPixelBufferLockBaseAddress(self.as_concrete_TypeRef(), options) }
517    }
518
519    #[inline]
520    pub fn unlock_base_address(&self, options: CVPixelBufferLockFlags) -> CVReturn {
521        unsafe { CVPixelBufferUnlockBaseAddress(self.as_concrete_TypeRef(), options) }
522    }
523
524    #[inline]
525    pub fn get_width(&self) -> usize {
526        unsafe { CVPixelBufferGetWidth(self.as_concrete_TypeRef()) }
527    }
528
529    #[inline]
530    pub fn get_height(&self) -> usize {
531        unsafe { CVPixelBufferGetHeight(self.as_concrete_TypeRef()) }
532    }
533
534    #[inline]
535    pub fn get_pixel_format(&self) -> OSType {
536        unsafe { CVPixelBufferGetPixelFormatType(self.as_concrete_TypeRef()) }
537    }
538
539    #[inline]
540    pub unsafe fn get_base_address(&self) -> *mut c_void {
541        unsafe { CVPixelBufferGetBaseAddress(self.as_concrete_TypeRef()) }
542    }
543
544    #[inline]
545    pub fn get_bytes_per_row(&self) -> usize {
546        unsafe { CVPixelBufferGetBytesPerRow(self.as_concrete_TypeRef()) }
547    }
548
549    #[inline]
550    pub fn get_data_size(&self) -> usize {
551        unsafe { CVPixelBufferGetDataSize(self.as_concrete_TypeRef()) }
552    }
553
554    #[inline]
555    pub fn is_planar(&self) -> bool {
556        unsafe { CVPixelBufferIsPlanar(self.as_concrete_TypeRef()) != 0 }
557    }
558
559    #[inline]
560    pub fn get_plane_count(&self) -> usize {
561        unsafe { CVPixelBufferGetPlaneCount(self.as_concrete_TypeRef()) }
562    }
563
564    #[inline]
565    pub fn get_width_of_plane(&self, plane_index: usize) -> usize {
566        unsafe { CVPixelBufferGetWidthOfPlane(self.as_concrete_TypeRef(), plane_index) }
567    }
568
569    #[inline]
570    pub fn get_height_of_plane(&self, plane_index: usize) -> usize {
571        unsafe { CVPixelBufferGetHeightOfPlane(self.as_concrete_TypeRef(), plane_index) }
572    }
573
574    #[inline]
575    pub unsafe fn get_base_address_of_plane(&self, plane_index: usize) -> *mut c_void {
576        unsafe { CVPixelBufferGetBaseAddressOfPlane(self.as_concrete_TypeRef(), plane_index) }
577    }
578
579    #[inline]
580    pub fn get_bytes_per_row_of_plane(&self, plane_index: usize) -> usize {
581        unsafe { CVPixelBufferGetBytesPerRowOfPlane(self.as_concrete_TypeRef(), plane_index) }
582    }
583
584    #[inline]
585    pub fn get_extended_pixels(&self) -> (usize, usize, usize, usize) {
586        unsafe {
587            let mut left = 0;
588            let mut right = 0;
589            let mut top = 0;
590            let mut bottom = 0;
591            CVPixelBufferGetExtendedPixels(self.as_concrete_TypeRef(), &mut left, &mut right, &mut top, &mut bottom);
592            (left, right, top, bottom)
593        }
594    }
595
596    #[inline]
597    pub fn fill_extended_pixels(&self) -> CVReturn {
598        unsafe { CVPixelBufferFillExtendedPixels(self.as_concrete_TypeRef()) }
599    }
600
601    #[inline]
602    pub fn copy_creation_attributes(&self) -> Option<CFDictionary<CFString, CFType>> {
603        unsafe {
604            let attributes = CVPixelBufferCopyCreationAttributes(self.as_concrete_TypeRef());
605            if attributes.is_null() {
606                None
607            } else {
608                Some(TCFType::wrap_under_create_rule(attributes))
609            }
610        }
611    }
612}