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