1use std::{
2 mem::{forget, size_of_val},
3 ptr::{null, null_mut},
4 slice::from_raw_parts,
5};
6
7use core_audio_types::base_types::{AudioChannelLayout, AudioFormatListItem, AudioStreamBasicDescription};
8use core_foundation::{
9 array::{CFArray, CFArrayRef},
10 base::{kCFAllocatorDefault, Boolean, CFAllocatorRef, CFType, CFTypeID, CFTypeRef, OSStatus, TCFType, TCFTypeRef},
11 declare_TCFType,
12 dictionary::{CFDictionary, CFDictionaryRef},
13 impl_CFTypeDescription, impl_TCFType,
14 propertylist::{CFPropertyList, CFPropertyListRef},
15 string::{CFString, CFStringRef},
16};
17use core_graphics::{
18 base::CGFloat,
19 geometry::{CGRect, CGSize},
20};
21use core_video::image_buffer::{CVImageBuffer, CVImageBufferRef};
22use libc::{c_int, c_void, size_t};
23#[cfg(feature = "objc")]
24use objc2::encode::{Encoding, RefEncode};
25
26use crate::{time::CMTime, OSType};
27
28pub const kCMFormatDescriptionError_InvalidParameter: OSStatus = -12710;
29pub const kCMFormatDescriptionError_AllocationFailed: OSStatus = -12711;
30pub const kCMFormatDescriptionError_ValueNotAvailable: OSStatus = -12718;
31
32type FourCharCode = u32;
33
34pub type CMMediaType = FourCharCode;
35
36#[inline]
37const fn fourcc(code: &[u8; 4]) -> u32 {
38 ((code[0] as u32) << 24) | ((code[1] as u32) << 16) | ((code[2] as u32) << 8) | ((code[3] as u32) << 0)
39}
40
41pub const kCMMediaType_Video: CMMediaType = fourcc(b"vide");
42pub const kCMMediaType_Audio: CMMediaType = fourcc(b"soun");
43pub const kCMMediaType_Muxed: CMMediaType = fourcc(b"muxx");
44pub const kCMMediaType_Text: CMMediaType = fourcc(b"text");
45pub const kCMMediaType_ClosedCaption: CMMediaType = fourcc(b"clcp");
46pub const kCMMediaType_Subtitle: CMMediaType = fourcc(b"sbtl");
47pub const kCMMediaType_TimeCode: CMMediaType = fourcc(b"tmcd");
48pub const kCMMediaType_Metadata: CMMediaType = fourcc(b"meta");
49pub const kCMMediaType_TaggedBufferGroup: CMMediaType = fourcc(b"tbgr");
50
51#[repr(C)]
52pub struct opaqueCMFormatDescription(c_void);
53
54pub type CMFormatDescriptionRef = *mut opaqueCMFormatDescription;
55
56extern "C" {
57 pub fn CMFormatDescriptionCreate(
58 allocator: CFAllocatorRef,
59 mediaType: CMMediaType,
60 mediaSubType: FourCharCode,
61 extensions: CFDictionaryRef,
62 formatDescriptionOut: *mut CMFormatDescriptionRef,
63 ) -> OSStatus;
64 pub fn CMFormatDescriptionGetTypeID() -> CFTypeID;
65 pub fn CMFormatDescriptionEqual(formatDescription: CMFormatDescriptionRef, otherFormatDescription: CMFormatDescriptionRef) -> Boolean;
66 pub fn CMFormatDescriptionEqualIgnoringExtensionKeys(
67 formatDescription: CMFormatDescriptionRef,
68 otherFormatDescription: CMFormatDescriptionRef,
69 formatDescriptionExtensionKeysToIgnore: CFTypeRef,
70 sampleDescriptionExtensionAtomKeysToIgnore: CFTypeRef,
71 ) -> Boolean;
72 pub fn CMFormatDescriptionGetMediaType(desc: CMFormatDescriptionRef) -> CMMediaType;
73 pub fn CMFormatDescriptionGetMediaSubType(desc: CMFormatDescriptionRef) -> FourCharCode;
74 pub fn CMFormatDescriptionGetExtensions(desc: CMFormatDescriptionRef) -> CFDictionaryRef;
75
76 pub static kCMFormatDescriptionExtension_OriginalCompressionSettings: CFStringRef;
77 pub static kCMFormatDescriptionExtension_SampleDescriptionExtensionAtoms: CFStringRef;
78 pub static kCMFormatDescriptionExtension_VerbatimSampleDescription: CFStringRef;
79 pub static kCMFormatDescriptionExtension_VerbatimISOSampleEntry: CFStringRef;
80
81 pub fn CMFormatDescriptionGetExtension(desc: CMFormatDescriptionRef, extensionKey: CFStringRef) -> CFPropertyListRef;
82}
83
84pub type CMAudioCodecType = FourCharCode;
85
86pub const kCMAudioCodecType_AAC_LCProtected: CMAudioCodecType = fourcc(b"paac");
87pub const kCMAudioCodecType_AAC_AudibleProtected: CMAudioCodecType = fourcc(b"aaac");
88
89pub type CMAudioFormatDescriptionRef = CMFormatDescriptionRef;
90
91extern "C" {
92 pub fn CMAudioFormatDescriptionCreate(
93 allocator: CFAllocatorRef,
94 asbd: *const AudioStreamBasicDescription,
95 layoutSize: size_t,
96 layout: *const AudioChannelLayout,
97 magicCookieSize: size_t,
98 magicCookie: *const c_void,
99 extensions: CFDictionaryRef,
100 formatDescriptionOut: *mut CMAudioFormatDescriptionRef,
101 ) -> OSStatus;
102 pub fn CMAudioFormatDescriptionGetStreamBasicDescription(desc: CMAudioFormatDescriptionRef) -> *const AudioStreamBasicDescription;
103 pub fn CMAudioFormatDescriptionGetMagicCookie(desc: CMAudioFormatDescriptionRef, sizeOut: *mut size_t) -> *const c_void;
104 pub fn CMAudioFormatDescriptionGetChannelLayout(desc: CMAudioFormatDescriptionRef, sizeOut: *mut size_t) -> *const AudioChannelLayout;
105 pub fn CMAudioFormatDescriptionGetFormatList(desc: CMAudioFormatDescriptionRef, sizeOut: *mut size_t) -> *const AudioFormatListItem;
106 pub fn CMAudioFormatDescriptionGetRichestDecodableFormat(desc: CMAudioFormatDescriptionRef) -> *const AudioFormatListItem;
107 pub fn CMAudioFormatDescriptionGetMostCompatibleFormat(desc: CMAudioFormatDescriptionRef) -> *const AudioFormatListItem;
108 pub fn CMAudioFormatDescriptionCreateSummary(
109 allocator: CFAllocatorRef,
110 formatDescriptionArray: CFArrayRef,
111 flags: u32,
112 formatDescriptionOut: *mut CMAudioFormatDescriptionRef,
113 ) -> OSStatus;
114}
115
116pub type CMAudioFormatDescriptionMask = u32;
117
118pub const kCMAudioFormatDescriptionMask_StreamBasicDescription: CMAudioFormatDescriptionMask = 1 << 0;
119pub const kCMAudioFormatDescriptionMask_MagicCookie: CMAudioFormatDescriptionMask = 1 << 1;
120pub const kCMAudioFormatDescriptionMask_ChannelLayout: CMAudioFormatDescriptionMask = 1 << 2;
121pub const kCMAudioFormatDescriptionMask_Extensions: CMAudioFormatDescriptionMask = 1 << 3;
122pub const kCMAudioFormatDescriptionMask_All: CMAudioFormatDescriptionMask = kCMAudioFormatDescriptionMask_StreamBasicDescription |
123 kCMAudioFormatDescriptionMask_MagicCookie |
124 kCMAudioFormatDescriptionMask_ChannelLayout |
125 kCMAudioFormatDescriptionMask_Extensions;
126
127extern "C" {
128 pub fn CMAudioFormatDescriptionEqual(
129 formatDescription: CMAudioFormatDescriptionRef,
130 otherFormatDescription: CMAudioFormatDescriptionRef,
131 equalityMask: CMAudioFormatDescriptionMask,
132 equalityMaskOut: *mut CMAudioFormatDescriptionMask,
133 ) -> Boolean;
134}
135
136pub type CMVideoFormatDescriptionRef = CMFormatDescriptionRef;
137
138pub type CMPixelFormatType = FourCharCode;
139
140pub const kCMPixelFormat_32ARGB: CMPixelFormatType = 32;
141pub const kCMPixelFormat_32BGRA: CMPixelFormatType = fourcc(b"BGRA");
142pub const kCMPixelFormat_24RGB: CMPixelFormatType = 24;
143pub const kCMPixelFormat_16BE555: CMPixelFormatType = 16;
144pub const kCMPixelFormat_16BE565: CMPixelFormatType = fourcc(b"B565");
145pub const kCMPixelFormat_16LE555: CMPixelFormatType = fourcc(b"L555");
146pub const kCMPixelFormat_16LE565: CMPixelFormatType = fourcc(b"L565");
147pub const kCMPixelFormat_16LE5551: CMPixelFormatType = fourcc(b"5551");
148pub const kCMPixelFormat_422YpCbCr8: CMPixelFormatType = fourcc(b"2vuy");
149pub const kCMPixelFormat_422YpCbCr8_yuvs: CMPixelFormatType = fourcc(b"yuvs");
150pub const kCMPixelFormat_444YpCbCr8: CMPixelFormatType = fourcc(b"v308");
151pub const kCMPixelFormat_4444YpCbCrA8: CMPixelFormatType = fourcc(b"v408");
152pub const kCMPixelFormat_422YpCbCr16: CMPixelFormatType = fourcc(b"v216");
153pub const kCMPixelFormat_422YpCbCr10: CMPixelFormatType = fourcc(b"v210");
154pub const kCMPixelFormat_444YpCbCr10: CMPixelFormatType = fourcc(b"v410");
155pub const kCMPixelFormat_8IndexedGray_WhiteIsZero: CMPixelFormatType = 0x00000028;
156
157pub type CMVideoCodecType = FourCharCode;
158
159pub const kCMVideoCodecType_422YpCbCr8: CMVideoCodecType = kCMPixelFormat_422YpCbCr8;
160pub const kCMVideoCodecType_Animation: CMVideoCodecType = fourcc(b"rle ");
161pub const kCMVideoCodecType_Cinepak: CMVideoCodecType = fourcc(b"cvid");
162pub const kCMVideoCodecType_JPEG: CMVideoCodecType = fourcc(b"jpeg");
163pub const kCMVideoCodecType_JPEG_OpenDML: CMVideoCodecType = fourcc(b"dmb1");
164pub const kCMVideoCodecType_SorensonVideo: CMVideoCodecType = fourcc(b"SVQ1");
165pub const kCMVideoCodecType_SorensonVideo3: CMVideoCodecType = fourcc(b"SVQ3");
166pub const kCMVideoCodecType_H263: CMVideoCodecType = fourcc(b"h263");
167pub const kCMVideoCodecType_H264: CMVideoCodecType = fourcc(b"avc1");
168pub const kCMVideoCodecType_HEVC: CMVideoCodecType = fourcc(b"hvc1");
169pub const kCMVideoCodecType_HEVCWithAlpha: CMVideoCodecType = fourcc(b"muxa");
170pub const kCMVideoCodecType_DolbyVisionHEVC: CMVideoCodecType = fourcc(b"dvh1");
171pub const kCMVideoCodecType_MPEG4Video: CMVideoCodecType = fourcc(b"mp4v");
172pub const kCMVideoCodecType_MPEG2Video: CMVideoCodecType = fourcc(b"mp2v");
173pub const kCMVideoCodecType_MPEG1Video: CMVideoCodecType = fourcc(b"mp1v");
174pub const kCMVideoCodecType_VP9: CMVideoCodecType = fourcc(b"vp09");
175pub const kCMVideoCodecType_DVCNTSC: CMVideoCodecType = fourcc(b"dvc ");
176pub const kCMVideoCodecType_DVCPAL: CMVideoCodecType = fourcc(b"dvcp");
177pub const kCMVideoCodecType_DVCProPAL: CMVideoCodecType = fourcc(b"dvpp");
178pub const kCMVideoCodecType_DVCPro50NTSC: CMVideoCodecType = fourcc(b"dv5n");
179pub const kCMVideoCodecType_DVCPro50PAL: CMVideoCodecType = fourcc(b"dv5p");
180pub const kCMVideoCodecType_DVCPROHD720p60: CMVideoCodecType = fourcc(b"dvhp");
181pub const kCMVideoCodecType_DVCPROHD720p50: CMVideoCodecType = fourcc(b"dvhq");
182pub const kCMVideoCodecType_DVCPROHD1080i60: CMVideoCodecType = fourcc(b"dvh6");
183pub const kCMVideoCodecType_DVCPROHD1080i50: CMVideoCodecType = fourcc(b"dvh5");
184pub const kCMVideoCodecType_DVCPROHD1080p30: CMVideoCodecType = fourcc(b"dvh3");
185pub const kCMVideoCodecType_DVCPROHD1080p25: CMVideoCodecType = fourcc(b"dvh2");
186pub const kCMVideoCodecType_AppleProRes4444XQ: CMVideoCodecType = fourcc(b"ap4x");
187pub const kCMVideoCodecType_AppleProRes4444: CMVideoCodecType = fourcc(b"ap4h");
188pub const kCMVideoCodecType_AppleProRes422HQ: CMVideoCodecType = fourcc(b"apch");
189pub const kCMVideoCodecType_AppleProRes422: CMVideoCodecType = fourcc(b"apcn");
190pub const kCMVideoCodecType_AppleProRes422LT: CMVideoCodecType = fourcc(b"apcs");
191pub const kCMVideoCodecType_AppleProRes422Proxy: CMVideoCodecType = fourcc(b"apco");
192pub const kCMVideoCodecType_AppleProResRAW: CMVideoCodecType = fourcc(b"aprn");
193pub const kCMVideoCodecType_AppleProResRAWHQ: CMVideoCodecType = fourcc(b"aprh");
194pub const kCMVideoCodecType_DisparityHEVC: CMVideoCodecType = fourcc(b"dish");
195pub const kCMVideoCodecType_DepthHEVC: CMVideoCodecType = fourcc(b"deph");
196pub const kCMVideoCodecType_AV1: CMVideoCodecType = fourcc(b"av01");
197
198#[repr(C, packed(4))]
199#[derive(Clone, Copy, Debug, Default, PartialEq)]
200pub struct CMVideoDimensions {
201 pub width: i32,
202 pub height: i32,
203}
204
205extern "C" {
206 pub static kCMFormatDescriptionExtension_FormatName: CFStringRef;
207 pub static kCMFormatDescriptionExtension_Depth: CFStringRef;
208 pub static kCMFormatDescriptionExtension_CleanAperture: CFStringRef;
209 pub static kCMFormatDescriptionKey_CleanApertureWidth: CFStringRef;
210 pub static kCMFormatDescriptionKey_CleanApertureHeight: CFStringRef;
211 pub static kCMFormatDescriptionKey_CleanApertureHorizontalOffset: CFStringRef;
212 pub static kCMFormatDescriptionKey_CleanApertureVerticalOffset: CFStringRef;
213 pub static kCMFormatDescriptionKey_CleanApertureWidthRational: CFStringRef;
214 pub static kCMFormatDescriptionKey_CleanApertureHeightRational: CFStringRef;
215 pub static kCMFormatDescriptionKey_CleanApertureHorizontalOffsetRational: CFStringRef;
216 pub static kCMFormatDescriptionKey_CleanApertureVerticalOffsetRational: CFStringRef;
217 pub static kCMFormatDescriptionExtension_FieldCount: CFStringRef;
218 pub static kCMFormatDescriptionFieldDetail_TemporalTopFirst: CFStringRef;
219 pub static kCMFormatDescriptionFieldDetail_TemporalBottomFirst: CFStringRef;
220 pub static kCMFormatDescriptionFieldDetail_SpatialFirstLineEarly: CFStringRef;
221 pub static kCMFormatDescriptionFieldDetail_SpatialFirstLineLate: CFStringRef;
222 pub static kCMFormatDescriptionExtension_PixelAspectRatio: CFStringRef;
223 pub static kCMFormatDescriptionKey_PixelAspectRatioHorizontalSpacing: CFStringRef;
224 pub static kCMFormatDescriptionKey_PixelAspectRatioVerticalSpacing: CFStringRef;
225 pub static kCMFormatDescriptionExtension_ColorPrimaries: CFStringRef;
226 pub static kCMFormatDescriptionColorPrimaries_ITU_R_709_2: CFStringRef;
227 pub static kCMFormatDescriptionColorPrimaries_EBU_3213: CFStringRef;
228 pub static kCMFormatDescriptionColorPrimaries_SMPTE_C: CFStringRef;
229 pub static kCMFormatDescriptionColorPrimaries_DCI_P3: CFStringRef;
230 pub static kCMFormatDescriptionColorPrimaries_P3_D65: CFStringRef;
231 pub static kCMFormatDescriptionColorPrimaries_ITU_R_2020: CFStringRef;
232 pub static kCMFormatDescriptionColorPrimaries_P22: CFStringRef;
233 pub static kCMFormatDescriptionExtension_TransferFunction: CFStringRef;
234 pub static kCMFormatDescriptionTransferFunction_ITU_R_709_2: CFStringRef;
235 pub static kCMFormatDescriptionTransferFunction_SMPTE_240M_1995: CFStringRef;
236 pub static kCMFormatDescriptionTransferFunction_UseGamma: CFStringRef;
237 pub static kCMFormatDescriptionTransferFunction_ITU_R_2020: CFStringRef;
238 pub static kCMFormatDescriptionTransferFunction_SMPTE_ST_428_1: CFStringRef;
239 pub static kCMFormatDescriptionTransferFunction_SMPTE_ST_2084_PQ: CFStringRef;
240 pub static kCMFormatDescriptionTransferFunction_ITU_R_2100_HLG: CFStringRef;
241 pub static kCMFormatDescriptionTransferFunction_Linear: CFStringRef;
242 pub static kCMFormatDescriptionTransferFunction_sRGB: CFStringRef;
243 pub static kCMFormatDescriptionExtension_GammaLevel: CFStringRef;
244 pub static kCMFormatDescriptionExtension_YCbCrMatrix: CFStringRef;
245 pub static kCMFormatDescriptionYCbCrMatrix_ITU_R_709_2: CFStringRef;
246 pub static kCMFormatDescriptionYCbCrMatrix_ITU_R_601_4: CFStringRef;
247 pub static kCMFormatDescriptionYCbCrMatrix_SMPTE_240M_1995: CFStringRef;
248 pub static kCMFormatDescriptionYCbCrMatrix_ITU_R_2020: CFStringRef;
249 pub static kCMFormatDescriptionExtension_FullRangeVideo: CFStringRef;
250 pub static kCMFormatDescriptionExtension_ICCProfile: CFStringRef;
251 pub static kCMFormatDescriptionExtension_BytesPerRow: CFStringRef;
252 pub static kCMFormatDescriptionExtension_ChromaLocationTopField: CFStringRef;
253 pub static kCMFormatDescriptionExtension_ChromaLocationBottomField: CFStringRef;
254 pub static kCMFormatDescriptionChromaLocation_Left: CFStringRef;
255 pub static kCMFormatDescriptionChromaLocation_Center: CFStringRef;
256 pub static kCMFormatDescriptionChromaLocation_TopLeft: CFStringRef;
257 pub static kCMFormatDescriptionChromaLocation_Top: CFStringRef;
258 pub static kCMFormatDescriptionChromaLocation_BottomLeft: CFStringRef;
259 pub static kCMFormatDescriptionChromaLocation_Bottom: CFStringRef;
260 pub static kCMFormatDescriptionChromaLocation_DV420: CFStringRef;
261 pub static kCMFormatDescriptionConformsToMPEG2VideoProfile: CFStringRef;
262 pub static kCMFormatDescriptionExtension_ProtectedContentOriginalFormat: CFStringRef;
263}
264
265pub const kCMMPEG2VideoProfile_HDV_720p30: i32 = fourcc(b"hdv1") as i32;
266pub const kCMMPEG2VideoProfile_HDV_1080i60: i32 = fourcc(b"hdv2") as i32;
267pub const kCMMPEG2VideoProfile_HDV_1080i50: i32 = fourcc(b"hdv3") as i32;
268pub const kCMMPEG2VideoProfile_HDV_720p24: i32 = fourcc(b"hdv4") as i32;
269pub const kCMMPEG2VideoProfile_HDV_720p25: i32 = fourcc(b"hdv5") as i32;
270pub const kCMMPEG2VideoProfile_HDV_1080p24: i32 = fourcc(b"hdv6") as i32;
271pub const kCMMPEG2VideoProfile_HDV_1080p25: i32 = fourcc(b"hdv7") as i32;
272pub const kCMMPEG2VideoProfile_HDV_1080p30: i32 = fourcc(b"hdv8") as i32;
273pub const kCMMPEG2VideoProfile_HDV_720p60: i32 = fourcc(b"hdv9") as i32;
274pub const kCMMPEG2VideoProfile_HDV_720p50: i32 = fourcc(b"hdva") as i32;
275pub const kCMMPEG2VideoProfile_XDCAM_HD_1080i60_VBR35: i32 = fourcc(b"xdv2") as i32;
276pub const kCMMPEG2VideoProfile_XDCAM_HD_1080i50_VBR35: i32 = fourcc(b"xdv3") as i32;
277pub const kCMMPEG2VideoProfile_XDCAM_HD_1080p24_VBR35: i32 = fourcc(b"xdv6") as i32;
278pub const kCMMPEG2VideoProfile_XDCAM_HD_1080p25_VBR35: i32 = fourcc(b"xdv7") as i32;
279pub const kCMMPEG2VideoProfile_XDCAM_HD_1080p30_VBR35: i32 = fourcc(b"xdv8") as i32;
280pub const kCMMPEG2VideoProfile_XDCAM_EX_720p24_VBR35: i32 = fourcc(b"xdv4") as i32;
281pub const kCMMPEG2VideoProfile_XDCAM_EX_720p25_VBR35: i32 = fourcc(b"xdv5") as i32;
282pub const kCMMPEG2VideoProfile_XDCAM_EX_720p30_VBR35: i32 = fourcc(b"xdv1") as i32;
283pub const kCMMPEG2VideoProfile_XDCAM_EX_720p50_VBR35: i32 = fourcc(b"xdva") as i32;
284pub const kCMMPEG2VideoProfile_XDCAM_EX_720p60_VBR35: i32 = fourcc(b"xdv9") as i32;
285pub const kCMMPEG2VideoProfile_XDCAM_EX_1080i60_VBR35: i32 = fourcc(b"xdvb") as i32;
286pub const kCMMPEG2VideoProfile_XDCAM_EX_1080i50_VBR35: i32 = fourcc(b"xdvc") as i32;
287pub const kCMMPEG2VideoProfile_XDCAM_EX_1080p24_VBR35: i32 = fourcc(b"xdvd") as i32;
288pub const kCMMPEG2VideoProfile_XDCAM_EX_1080p25_VBR35: i32 = fourcc(b"xdve") as i32;
289pub const kCMMPEG2VideoProfile_XDCAM_EX_1080p30_VBR35: i32 = fourcc(b"xdvf") as i32;
290pub const kCMMPEG2VideoProfile_XDCAM_HD422_720p50_CBR50: i32 = fourcc(b"xd5a") as i32;
291pub const kCMMPEG2VideoProfile_XDCAM_HD422_720p60_CBR50: i32 = fourcc(b"xd59") as i32;
292pub const kCMMPEG2VideoProfile_XDCAM_HD422_1080i60_CBR50: i32 = fourcc(b"xd5b") as i32;
293pub const kCMMPEG2VideoProfile_XDCAM_HD422_1080i50_CBR50: i32 = fourcc(b"xd5c") as i32;
294pub const kCMMPEG2VideoProfile_XDCAM_HD422_1080p24_CBR50: i32 = fourcc(b"xd5d") as i32;
295pub const kCMMPEG2VideoProfile_XDCAM_HD422_1080p25_CBR50: i32 = fourcc(b"xd5e") as i32;
296pub const kCMMPEG2VideoProfile_XDCAM_HD422_1080p30_CBR50: i32 = fourcc(b"xd5f") as i32;
297pub const kCMMPEG2VideoProfile_XDCAM_HD_540p: i32 = fourcc(b"xdhd") as i32;
298pub const kCMMPEG2VideoProfile_XDCAM_HD422_540p: i32 = fourcc(b"xdh2") as i32;
299pub const kCMMPEG2VideoProfile_XDCAM_HD422_720p24_CBR50: i32 = fourcc(b"xd54") as i32;
300pub const kCMMPEG2VideoProfile_XDCAM_HD422_720p25_CBR50: i32 = fourcc(b"xd55") as i32;
301pub const kCMMPEG2VideoProfile_XDCAM_HD422_720p30_CBR50: i32 = fourcc(b"xd51") as i32;
302pub const kCMMPEG2VideoProfile_XF: i32 = fourcc(b"xfz1") as i32;
303
304extern "C" {
305 pub static kCMFormatDescriptionExtension_TemporalQuality: CFStringRef;
306 pub static kCMFormatDescriptionExtension_SpatialQuality: CFStringRef;
307 pub static kCMFormatDescriptionExtension_VerbatimImageDescription: CFStringRef;
308 pub static kCMFormatDescriptionExtension_Version: CFStringRef;
309 pub static kCMFormatDescriptionExtension_RevisionLevel: CFStringRef;
310 pub static kCMFormatDescriptionExtension_Vendor: CFStringRef;
311 pub static kCMFormatDescriptionVendor_Apple: CFStringRef;
312 pub static kCMFormatDescriptionExtension_MasteringDisplayColorVolume: CFStringRef;
313 pub static kCMFormatDescriptionExtension_ContentLightLevelInfo: CFStringRef;
314 pub static kCMFormatDescriptionExtension_ContentColorVolume: CFStringRef;
315 pub static kCMFormatDescriptionExtension_AlternativeTransferCharacteristics: CFStringRef;
316 pub static kCMFormatDescriptionExtension_AuxiliaryTypeInfo: CFStringRef;
317 pub static kCMFormatDescriptionExtension_AlphaChannelMode: CFStringRef;
318 pub static kCMFormatDescriptionAlphaChannelMode_StraightAlpha: CFStringRef;
319 pub static kCMFormatDescriptionAlphaChannelMode_PremultipliedAlpha: CFStringRef;
320 pub static kCMFormatDescriptionExtension_ContainsAlphaChannel: CFStringRef;
321 pub static kCMFormatDescriptionExtension_BitsPerComponent: CFStringRef;
322 pub static kCMFormatDescriptionExtension_HorizontalFieldOfView: CFStringRef;
323 pub static kCMFormatDescriptionExtension_HeroEye: CFStringRef;
324 pub static kCMFormatDescriptionHeroEye_Left: CFStringRef;
325 pub static kCMFormatDescriptionHeroEye_Right: CFStringRef;
326 pub static kCMFormatDescriptionExtension_StereoCameraBaseline: CFStringRef;
327 pub static kCMFormatDescriptionExtension_HorizontalDisparityAdjustment: CFStringRef;
328
329 pub fn CMVideoFormatDescriptionCreate(
330 allocator: CFAllocatorRef,
331 codecType: CMVideoCodecType,
332 width: i32,
333 height: i32,
334 extensions: CFDictionaryRef,
335 formatDescriptionOut: *mut CMVideoFormatDescriptionRef,
336 ) -> OSStatus;
337 pub fn CMVideoFormatDescriptionCreateForImageBuffer(
338 allocator: CFAllocatorRef,
339 imageBuffer: CVImageBufferRef,
340 formatDescriptionOut: *mut CMVideoFormatDescriptionRef,
341 ) -> OSStatus;
342 pub fn CMVideoFormatDescriptionCreateFromH264ParameterSets(
343 allocator: CFAllocatorRef,
344 parameterSetCount: size_t,
345 parameterSetPointers: *const *const u8,
346 parameterSetSizes: *const size_t,
347 NALUnitHeaderLength: c_int,
348 formatDescriptionOut: *mut CMFormatDescriptionRef,
349 ) -> OSStatus;
350 pub fn CMVideoFormatDescriptionCreateFromHEVCParameterSets(
351 allocator: CFAllocatorRef,
352 parameterSetCount: size_t,
353 parameterSetPointers: *const *const u8,
354 parameterSetSizes: *const size_t,
355 NALUnitHeaderLength: c_int,
356 extensions: CFDictionaryRef,
357 formatDescriptionOut: *mut CMFormatDescriptionRef,
358 ) -> OSStatus;
359 pub fn CMVideoFormatDescriptionGetH264ParameterSetAtIndex(
360 videoDesc: CMFormatDescriptionRef,
361 parameterSetIndex: size_t,
362 parameterSetPointerOut: *mut *const u8,
363 parameterSetSizeOut: *mut size_t,
364 parameterSetCountOut: *mut size_t,
365 NALUnitHeaderLengthOut: *mut c_int,
366 ) -> OSStatus;
367 pub fn CMVideoFormatDescriptionGetHEVCParameterSetAtIndex(
368 videoDesc: CMFormatDescriptionRef,
369 parameterSetIndex: size_t,
370 parameterSetPointerOut: *mut *const u8,
371 parameterSetSizeOut: *mut size_t,
372 parameterSetCountOut: *mut size_t,
373 NALUnitHeaderLengthOut: *mut c_int,
374 ) -> OSStatus;
375 pub fn CMVideoFormatDescriptionGetDimensions(videoDesc: CMVideoFormatDescriptionRef) -> CMVideoDimensions;
376 pub fn CMVideoFormatDescriptionGetPresentationDimensions(
377 videoDesc: CMVideoFormatDescriptionRef,
378 usePixelAspectRatio: Boolean,
379 useCleanAperture: Boolean,
380 ) -> CGSize;
381 pub fn CMVideoFormatDescriptionGetCleanAperture(videoDesc: CMVideoFormatDescriptionRef, originIsAtTopLeft: Boolean) -> CGRect;
382 pub fn CMVideoFormatDescriptionGetExtensionKeysCommonWithImageBuffers() -> CFArrayRef;
383 pub fn CMVideoFormatDescriptionMatchesImageBuffer(videoDesc: CMVideoFormatDescriptionRef, imageBuffer: CVImageBufferRef) -> Boolean;
384 pub fn CMVideoFormatDescriptionCopyTagCollectionArray(
385 formatDescription: CMVideoFormatDescriptionRef,
386 tagCollectionsOut: *mut CFArrayRef,
387 ) -> OSStatus;
388}
389
390pub type CMTaggedBufferGroupFormatDescriptionRef = CMFormatDescriptionRef;
391
392pub type CMTaggedBufferGroupFormatType = FourCharCode;
393
394pub const kCMTaggedBufferGroupFormatType_TaggedBufferGroup: CMTaggedBufferGroupFormatType = fourcc(b"tbgr");
395
396pub type CMMuxedFormatDescriptionRef = CMFormatDescriptionRef;
397
398pub type CMMuxedStreamType = FourCharCode;
399
400pub const kCMMuxedStreamType_MPEG1System: CMMuxedStreamType = fourcc(b"mp1s");
401pub const kCMMuxedStreamType_MPEG2Transport: CMMuxedStreamType = fourcc(b"mp2t");
402pub const kCMMuxedStreamType_MPEG2Program: CMMuxedStreamType = fourcc(b"mp2p");
403pub const kCMMuxedStreamType_DV: CMMuxedStreamType = fourcc(b"dv ");
404pub const kCMMuxedStreamType_EmbeddedDeviceScreenRecording: CMMuxedStreamType = fourcc(b"isr ");
405
406extern "C" {
407 pub fn CMMuxedFormatDescriptionCreate(
408 allocator: CFAllocatorRef,
409 muxType: CMMuxedStreamType,
410 extensions: CFDictionaryRef,
411 formatDescriptionOut: *mut CMMuxedFormatDescriptionRef,
412 ) -> OSStatus;
413}
414
415pub type CMClosedCaptionFormatDescriptionRef = CMFormatDescriptionRef;
416
417pub type CMClosedCaptionFormatType = FourCharCode;
418
419pub const kCMClosedCaptionFormatType_CEA608: CMClosedCaptionFormatType = fourcc(b"c608");
420pub const kCMClosedCaptionFormatType_CEA708: CMClosedCaptionFormatType = fourcc(b"c708");
421pub const kCMClosedCaptionFormatType_ATSC: CMClosedCaptionFormatType = fourcc(b"atcc");
422
423pub type CMTextFormatDescriptionRef = CMFormatDescriptionRef;
424
425pub type CMTextFormatType = FourCharCode;
426
427pub const kCMTextFormatType_QTText: CMTextFormatType = fourcc(b"text");
428pub const kCMTextFormatType_3GText: CMTextFormatType = fourcc(b"tx3g");
429
430pub type CMTextDisplayFlags = u32;
431
432pub const kCMTextDisplayFlag_scrollIn: CMTextDisplayFlags = 0x00000020;
433pub const kCMTextDisplayFlag_scrollOut: CMTextDisplayFlags = 0x00000040;
434pub const kCMTextDisplayFlag_scrollDirectionMask: CMTextDisplayFlags = 0x00000180;
435pub const kCMTextDisplayFlag_scrollDirection_bottomToTop: CMTextDisplayFlags = 0x00000000;
436pub const kCMTextDisplayFlag_scrollDirection_rightToLeft: CMTextDisplayFlags = 0x00000080;
437pub const kCMTextDisplayFlag_scrollDirection_topToBottom: CMTextDisplayFlags = 0x00000100;
438pub const kCMTextDisplayFlag_scrollDirection_leftToRight: CMTextDisplayFlags = 0x00000180;
439pub const kCMTextDisplayFlag_continuousKaraoke: CMTextDisplayFlags = 0x00000800;
440pub const kCMTextDisplayFlag_writeTextVertically: CMTextDisplayFlags = 0x00020000;
441pub const kCMTextDisplayFlag_fillTextRegion: CMTextDisplayFlags = 0x00040000;
442pub const kCMTextDisplayFlag_obeySubtitleFormatting: CMTextDisplayFlags = 0x20000000;
443pub const kCMTextDisplayFlag_forcedSubtitlesPresent: CMTextDisplayFlags = 0x40000000;
444pub const kCMTextDisplayFlag_allSubtitlesForced: CMTextDisplayFlags = 0x80000000;
445
446pub type CMTextJustificationValue = i8;
447
448pub const kCMTextJustification_left_top: CMTextJustificationValue = 0;
449pub const kCMTextJustification_centered: CMTextJustificationValue = 1;
450pub const kCMTextJustification_bottom_right: CMTextJustificationValue = -1;
451
452extern "C" {
453 pub static kCMTextFormatDescriptionExtension_DisplayFlags: CFStringRef;
454 pub static kCMTextFormatDescriptionExtension_BackgroundColor: CFStringRef;
455 pub static kCMTextFormatDescriptionColor_Red: CFStringRef;
456 pub static kCMTextFormatDescriptionColor_Green: CFStringRef;
457 pub static kCMTextFormatDescriptionColor_Blue: CFStringRef;
458 pub static kCMTextFormatDescriptionColor_Alpha: CFStringRef;
459 pub static kCMTextFormatDescriptionExtension_DefaultTextBox: CFStringRef;
460 pub static kCMTextFormatDescriptionRect_Top: CFStringRef;
461 pub static kCMTextFormatDescriptionRect_Left: CFStringRef;
462 pub static kCMTextFormatDescriptionRect_Bottom: CFStringRef;
463 pub static kCMTextFormatDescriptionRect_Right: CFStringRef;
464 pub static kCMTextFormatDescriptionExtension_DefaultStyle: CFStringRef;
465 pub static kCMTextFormatDescriptionStyle_StartChar: CFStringRef;
466 pub static kCMTextFormatDescriptionStyle_Font: CFStringRef;
467 pub static kCMTextFormatDescriptionStyle_FontFace: CFStringRef;
468 pub static kCMTextFormatDescriptionStyle_ForegroundColor: CFStringRef;
469 pub static kCMTextFormatDescriptionStyle_FontSize: CFStringRef;
470 pub static kCMTextFormatDescriptionExtension_HorizontalJustification: CFStringRef;
471 pub static kCMTextFormatDescriptionExtension_VerticalJustification: CFStringRef;
472 pub static kCMTextFormatDescriptionStyle_EndChar: CFStringRef;
473 pub static kCMTextFormatDescriptionExtension_FontTable: CFStringRef;
474 pub static kCMTextFormatDescriptionExtension_TextJustification: CFStringRef;
475 pub static kCMTextFormatDescriptionStyle_Height: CFStringRef;
476 pub static kCMTextFormatDescriptionStyle_Ascent: CFStringRef;
477 pub static kCMTextFormatDescriptionExtension_DefaultFontName: CFStringRef;
478 pub static kCMFormatDescriptionExtension_AmbientViewingEnvironment: CFStringRef;
479
480 pub fn CMTextFormatDescriptionGetDisplayFlags(desc: CMFormatDescriptionRef, displayFlagsOut: *mut CMTextDisplayFlags) -> OSStatus;
481 pub fn CMTextFormatDescriptionGetJustification(
482 desc: CMFormatDescriptionRef,
483 horizontaJustificationlOut: *mut CMTextJustificationValue,
484 verticalJustificationOut: *mut CMTextJustificationValue,
485 ) -> OSStatus;
486 pub fn CMTextFormatDescriptionGetDefaultTextBox(
487 desc: CMFormatDescriptionRef,
488 originIsAtTopLeft: Boolean,
489 heightOfTextTrack: CGFloat,
490 defaultTextBoxOut: *mut CGRect,
491 ) -> OSStatus;
492 pub fn CMTextFormatDescriptionGetDefaultStyle(
493 desc: CMFormatDescriptionRef,
494 localFontIDOut: *mut u16,
495 boldOut: *mut Boolean,
496 italicOut: *mut Boolean,
497 underlineOut: *mut Boolean,
498 fontSizeOut: *mut CGFloat,
499 colorComponentsOut: *mut [CGFloat; 4usize],
500 ) -> OSStatus;
501 pub fn CMTextFormatDescriptionGetFontName(desc: CMFormatDescriptionRef, localFontID: u16, fontNameOut: *mut CFStringRef) -> OSStatus;
502}
503
504pub type CMSubtitleFormatType = FourCharCode;
505
506pub const kCMSubtitleFormatType_3GText: CMSubtitleFormatType = fourcc(b"tx3g");
507pub const kCMSubtitleFormatType_WebVTT: CMSubtitleFormatType = fourcc(b"wvtt");
508
509pub type CMTimeCodeFormatDescriptionRef = CMFormatDescriptionRef;
510
511pub type CMTimeCodeFormatType = FourCharCode;
512
513pub const kCMTimeCodeFormatType_TimeCode32: CMTimeCodeFormatType = fourcc(b"tmcd");
514pub const kCMTimeCodeFormatType_TimeCode64: CMTimeCodeFormatType = fourcc(b"tc64");
515pub const kCMTimeCodeFormatType_Counter32: CMTimeCodeFormatType = fourcc(b"cn32");
516pub const kCMTimeCodeFormatType_Counter64: CMTimeCodeFormatType = fourcc(b"cn64");
517
518pub const kCMTimeCodeFlag_DropFrame: u32 = 1 << 0;
519pub const kCMTimeCodeFlag_24HourMax: u32 = 1 << 1;
520pub const kCMTimeCodeFlag_NegTimesOK: u32 = 1 << 2;
521
522extern "C" {
523 pub fn CMTimeCodeFormatDescriptionCreate(
524 allocator: CFAllocatorRef,
525 timeCodeFormatType: CMTimeCodeFormatType,
526 frameDuration: CMTime,
527 frameQuanta: u32,
528 flags: u32,
529 extensions: CFDictionaryRef,
530 formatDescriptionOut: *mut CMTimeCodeFormatDescriptionRef,
531 ) -> OSStatus;
532 pub fn CMTimeCodeFormatDescriptionGetFrameDuration(desc: CMTimeCodeFormatDescriptionRef) -> CMTime;
533 pub fn CMTimeCodeFormatDescriptionGetFrameQuanta(desc: CMTimeCodeFormatDescriptionRef) -> u32;
534 pub fn CMTimeCodeFormatDescriptionGetTimeCodeFlags(desc: CMTimeCodeFormatDescriptionRef) -> u32;
535
536 pub static kCMTimeCodeFormatDescriptionExtension_SourceReferenceName: CFStringRef;
537 pub static kCMTimeCodeFormatDescriptionKey_Value: CFStringRef;
538 pub static kCMTimeCodeFormatDescriptionKey_LangCode: CFStringRef;
539}
540
541pub type CMMetadataFormatDescriptionRef = CMFormatDescriptionRef;
542
543pub type CMMetadataFormatType = FourCharCode;
544
545pub const kCMMetadataFormatType_ICY: CMMetadataFormatType = fourcc(b"icy ");
546pub const kCMMetadataFormatType_ID3: CMMetadataFormatType = fourcc(b"id3 ");
547pub const kCMMetadataFormatType_Boxed: CMMetadataFormatType = fourcc(b"mebx");
548pub const kCMMetadataFormatType_EMSG: CMMetadataFormatType = fourcc(b"emsg");
549
550extern "C" {
551 pub static kCMFormatDescriptionExtensionKey_MetadataKeyTable: CFStringRef;
552 pub static kCMMetadataFormatDescriptionKey_Namespace: CFStringRef;
553 pub static kCMMetadataFormatDescriptionKey_Value: CFStringRef;
554 pub static kCMMetadataFormatDescriptionKey_LocalID: CFStringRef;
555 pub static kCMMetadataFormatDescriptionKey_DataType: CFStringRef;
556 pub static kCMMetadataFormatDescriptionKey_DataTypeNamespace: CFStringRef;
557 pub static kCMMetadataFormatDescriptionKey_ConformingDataTypes: CFStringRef;
558 pub static kCMMetadataFormatDescriptionKey_LanguageTag: CFStringRef;
559 pub static kCMMetadataFormatDescriptionKey_StructuralDependency: CFStringRef;
560 pub static kCMMetadataFormatDescriptionKey_SetupData: CFStringRef;
561 pub static kCMMetadataFormatDescription_StructuralDependencyKey_DependencyIsInvalidFlag: CFStringRef;
562 pub static kCMMetadataFormatDescriptionMetadataSpecificationKey_Identifier: CFStringRef;
563 pub static kCMMetadataFormatDescriptionMetadataSpecificationKey_DataType: CFStringRef;
564 pub static kCMMetadataFormatDescriptionMetadataSpecificationKey_ExtendedLanguageTag: CFStringRef;
565 pub static kCMMetadataFormatDescriptionMetadataSpecificationKey_StructuralDependency: CFStringRef;
566 pub static kCMMetadataFormatDescriptionMetadataSpecificationKey_SetupData: CFStringRef;
567
568 pub fn CMMetadataFormatDescriptionCreateWithKeys(
569 allocator: CFAllocatorRef,
570 metadataType: CMMetadataFormatType,
571 keys: CFArrayRef,
572 formatDescriptionOut: *mut CMMetadataFormatDescriptionRef,
573 ) -> OSStatus;
574 pub fn CMMetadataFormatDescriptionCreateWithMetadataSpecifications(
575 allocator: CFAllocatorRef,
576 metadataType: CMMetadataFormatType,
577 metadataSpecifications: CFArrayRef,
578 formatDescriptionOut: *mut CMMetadataFormatDescriptionRef,
579 ) -> OSStatus;
580 pub fn CMMetadataFormatDescriptionCreateWithMetadataFormatDescriptionAndMetadataSpecifications(
581 allocator: CFAllocatorRef,
582 sourceDescription: CMMetadataFormatDescriptionRef,
583 metadataSpecifications: CFArrayRef,
584 formatDescriptionOut: *mut CMMetadataFormatDescriptionRef,
585 ) -> OSStatus;
586 pub fn CMMetadataFormatDescriptionCreateByMergingMetadataFormatDescriptions(
587 allocator: CFAllocatorRef,
588 sourceDescription: CMMetadataFormatDescriptionRef,
589 otherSourceDescription: CMMetadataFormatDescriptionRef,
590 formatDescriptionOut: *mut CMMetadataFormatDescriptionRef,
591 ) -> OSStatus;
592 pub fn CMMetadataFormatDescriptionGetKeyWithLocalID(desc: CMMetadataFormatDescriptionRef, localKeyID: OSType) -> CFDictionaryRef;
593 pub fn CMMetadataFormatDescriptionGetIdentifiers(desc: CMMetadataFormatDescriptionRef) -> CFArrayRef;
594}
595
596#[cfg(feature = "objc")]
597unsafe impl RefEncode for opaqueCMFormatDescription {
598 const ENCODING_REF: Encoding = Encoding::Pointer(&Encoding::Struct("opaqueCMFormatDescription", &[]));
599}
600
601pub trait TCMFormatDescription: TCFType {
602 #[inline]
603 fn as_format_description(&self) -> CMFormatDescription {
604 unsafe { CMFormatDescription::wrap_under_get_rule(self.as_concrete_TypeRef().as_void_ptr() as CMFormatDescriptionRef) }
605 }
606
607 #[inline]
608 fn into_format_description(self) -> CMFormatDescription
609 where
610 Self: Sized,
611 {
612 let reference = self.as_concrete_TypeRef().as_void_ptr() as CMFormatDescriptionRef;
613 forget(self);
614 unsafe { CMFormatDescription::wrap_under_create_rule(reference) }
615 }
616}
617
618impl CMFormatDescription {
619 #[inline]
620 pub fn downcast<T: TCMFormatDescription>(&self) -> Option<T> {
621 if self.instance_of::<T>() {
622 unsafe { Some(T::wrap_under_get_rule(T::Ref::from_void_ptr(self.as_concrete_TypeRef() as *const c_void))) }
623 } else {
624 None
625 }
626 }
627
628 #[inline]
629 pub fn downcast_into<T: TCMFormatDescription>(self) -> Option<T> {
630 if self.instance_of::<T>() {
631 unsafe {
632 let reference = T::Ref::from_void_ptr(self.as_concrete_TypeRef() as *const c_void);
633 forget(self);
634 Some(T::wrap_under_create_rule(reference))
635 }
636 } else {
637 None
638 }
639 }
640}
641
642declare_TCFType!(CMFormatDescription, CMFormatDescriptionRef);
643impl_TCFType!(CMFormatDescription, CMFormatDescriptionRef, CMFormatDescriptionGetTypeID);
644impl_CFTypeDescription!(CMFormatDescription);
645
646impl CMFormatDescription {
647 #[inline]
648 pub fn new(media_type: CMMediaType, media_subtype: FourCharCode, extensions: Option<&CFDictionary<CFString, CFType>>) -> Result<Self, OSStatus> {
649 let mut format_description: CMFormatDescriptionRef = null_mut();
650 let status = unsafe {
651 CMFormatDescriptionCreate(
652 kCFAllocatorDefault,
653 media_type,
654 media_subtype,
655 extensions.map_or(null(), |exts| exts.as_concrete_TypeRef()),
656 &mut format_description,
657 )
658 };
659 if status == 0 {
660 Ok(unsafe { TCFType::wrap_under_create_rule(format_description) })
661 } else {
662 Err(status)
663 }
664 }
665
666 #[inline]
667 pub fn equal(&self, other: &Self) -> bool {
668 unsafe { CMFormatDescriptionEqual(self.as_concrete_TypeRef(), other.as_concrete_TypeRef()) != 0 }
669 }
670
671 #[inline]
672 pub fn equal_ignoring_extension_keys(
673 &self,
674 other: &Self,
675 extension_keys_to_ignore: &CFType,
676 sample_description_extension_atom_keys_to_ignore: &CFType,
677 ) -> bool {
678 unsafe {
679 CMFormatDescriptionEqualIgnoringExtensionKeys(
680 self.as_concrete_TypeRef(),
681 other.as_concrete_TypeRef(),
682 extension_keys_to_ignore.as_concrete_TypeRef(),
683 sample_description_extension_atom_keys_to_ignore.as_concrete_TypeRef(),
684 ) != 0
685 }
686 }
687
688 #[inline]
689 pub fn get_media_type(&self) -> CMMediaType {
690 unsafe { CMFormatDescriptionGetMediaType(self.as_concrete_TypeRef()) }
691 }
692
693 #[inline]
694 pub fn get_media_subtype(&self) -> FourCharCode {
695 unsafe { CMFormatDescriptionGetMediaSubType(self.as_concrete_TypeRef()) }
696 }
697
698 #[inline]
699 pub fn get_extensions(&self) -> Option<CFDictionary<CFString, CFType>> {
700 unsafe {
701 let extensions = CMFormatDescriptionGetExtensions(self.as_concrete_TypeRef());
702 if extensions.is_null() {
703 None
704 } else {
705 Some(TCFType::wrap_under_get_rule(extensions))
706 }
707 }
708 }
709
710 #[inline]
711 pub fn get_extension(&self, extension_key: &CFString) -> Option<CFPropertyList> {
712 unsafe {
713 let extension = CMFormatDescriptionGetExtension(self.as_concrete_TypeRef(), extension_key.as_concrete_TypeRef());
714 if extension.is_null() {
715 None
716 } else {
717 Some(CFPropertyList::wrap_under_get_rule(extension))
718 }
719 }
720 }
721}
722
723impl TCMFormatDescription for CMAudioFormatDescription {}
724
725declare_TCFType!(CMAudioFormatDescription, CMAudioFormatDescriptionRef);
726impl_TCFType!(CMAudioFormatDescription, CMAudioFormatDescriptionRef, CMFormatDescriptionGetTypeID);
727impl_CFTypeDescription!(CMAudioFormatDescription);
728
729impl CMAudioFormatDescription {
730 #[inline]
731 pub fn new(
732 asbd: &AudioStreamBasicDescription,
733 layout: &AudioChannelLayout,
734 magic_cookie: &[u8],
735 extensions: Option<&CFDictionary<CFString, CFType>>,
736 ) -> Result<Self, OSStatus> {
737 let mut format_description: CMAudioFormatDescriptionRef = null_mut();
738 let status = unsafe {
739 CMAudioFormatDescriptionCreate(
740 kCFAllocatorDefault,
741 asbd,
742 size_of_val(layout),
743 layout,
744 magic_cookie.len(),
745 magic_cookie.as_ptr() as *const _,
746 extensions.map_or(null(), |exts| exts.as_concrete_TypeRef()),
747 &mut format_description,
748 )
749 };
750 if status == 0 {
751 Ok(unsafe { TCFType::wrap_under_create_rule(format_description) })
752 } else {
753 Err(status)
754 }
755 }
756
757 #[inline]
758 pub fn get_codec_type(&self) -> CMAudioCodecType {
759 unsafe { CMFormatDescriptionGetMediaSubType(self.as_concrete_TypeRef()) }
760 }
761
762 #[inline]
763 pub fn get_stream_basic_description(&self) -> Option<&AudioStreamBasicDescription> {
764 unsafe {
765 let asbd = CMAudioFormatDescriptionGetStreamBasicDescription(self.as_concrete_TypeRef());
766 if asbd.is_null() {
767 None
768 } else {
769 Some(&*asbd)
770 }
771 }
772 }
773
774 #[inline]
775 pub fn get_magic_cookie(&self) -> Option<&[u8]> {
776 unsafe {
777 let mut size = 0;
778 let cookie = CMAudioFormatDescriptionGetMagicCookie(self.as_concrete_TypeRef(), &mut size);
779 if cookie.is_null() {
780 None
781 } else {
782 Some(from_raw_parts(cookie as *const u8, size))
783 }
784 }
785 }
786
787 #[inline]
788 pub fn get_channel_layout(&self) -> Option<(&AudioChannelLayout, usize)> {
789 unsafe {
790 let mut size = 0;
791 let layout = CMAudioFormatDescriptionGetChannelLayout(self.as_concrete_TypeRef(), &mut size);
792 if layout.is_null() {
793 None
794 } else {
795 Some((&*layout, size))
796 }
797 }
798 }
799
800 #[inline]
801 pub fn get_format_list(&self) -> Option<&[AudioFormatListItem]> {
802 unsafe {
803 let mut size = 0;
804 let list = CMAudioFormatDescriptionGetFormatList(self.as_concrete_TypeRef(), &mut size);
805 if list.is_null() {
806 None
807 } else {
808 Some(from_raw_parts(list, size))
809 }
810 }
811 }
812
813 #[inline]
814 pub fn get_richest_decodable_format(&self) -> Option<&AudioFormatListItem> {
815 unsafe {
816 let format = CMAudioFormatDescriptionGetRichestDecodableFormat(self.as_concrete_TypeRef());
817 if format.is_null() {
818 None
819 } else {
820 Some(&*format)
821 }
822 }
823 }
824
825 #[inline]
826 pub fn get_most_compatible_format(&self) -> Option<&AudioFormatListItem> {
827 unsafe {
828 let format = CMAudioFormatDescriptionGetMostCompatibleFormat(self.as_concrete_TypeRef());
829 if format.is_null() {
830 None
831 } else {
832 Some(&*format)
833 }
834 }
835 }
836
837 #[inline]
838 pub fn new_summary(format_description_array: &CFArray<CMAudioFormatDescription>, flags: u32) -> Result<Self, OSStatus> {
839 let mut format_description: CMAudioFormatDescriptionRef = null_mut();
840 let status = unsafe {
841 CMAudioFormatDescriptionCreateSummary(kCFAllocatorDefault, format_description_array.as_concrete_TypeRef(), flags, &mut format_description)
842 };
843 if status == 0 {
844 Ok(unsafe { TCFType::wrap_under_create_rule(format_description) })
845 } else {
846 Err(status)
847 }
848 }
849
850 #[inline]
851 pub fn equal(&self, other: &Self, eequality_mask: CMAudioFormatDescriptionMask) -> (bool, CMAudioFormatDescriptionMask) {
852 let mut mask = 0;
853 let equal = unsafe { CMAudioFormatDescriptionEqual(self.as_concrete_TypeRef(), other.as_concrete_TypeRef(), eequality_mask, &mut mask) != 0 };
854 (equal, mask)
855 }
856}
857
858impl TCMFormatDescription for CMVideoFormatDescription {}
859
860declare_TCFType!(CMVideoFormatDescription, CMVideoFormatDescriptionRef);
861impl_TCFType!(CMVideoFormatDescription, CMVideoFormatDescriptionRef, CMFormatDescriptionGetTypeID);
862impl_CFTypeDescription!(CMVideoFormatDescription);
863
864impl CMVideoFormatDescription {
865 #[inline]
866 pub fn new(codec_type: CMVideoCodecType, width: i32, height: i32, extensions: Option<&CFDictionary<CFString, CFType>>) -> Result<Self, OSStatus> {
867 let mut format_description: CMVideoFormatDescriptionRef = null_mut();
868 let status = unsafe {
869 CMVideoFormatDescriptionCreate(
870 kCFAllocatorDefault,
871 codec_type,
872 width,
873 height,
874 extensions.as_ref().map_or(null(), |exts| exts.as_concrete_TypeRef()),
875 &mut format_description,
876 )
877 };
878 if status == 0 {
879 Ok(unsafe { TCFType::wrap_under_create_rule(format_description) })
880 } else {
881 Err(status)
882 }
883 }
884
885 #[inline]
886 pub fn from_image_buffer(image_buffer: &CVImageBuffer) -> Result<Self, OSStatus> {
887 let mut format_description: CMVideoFormatDescriptionRef = null_mut();
888 let status =
889 unsafe { CMVideoFormatDescriptionCreateForImageBuffer(kCFAllocatorDefault, image_buffer.as_concrete_TypeRef(), &mut format_description) };
890 if status == 0 {
891 Ok(unsafe { TCFType::wrap_under_create_rule(format_description) })
892 } else {
893 Err(status)
894 }
895 }
896
897 #[inline]
898 pub fn from_h264_parameter_sets(parameter_sets: &[&[u8]], nal_unit_header_length: i32) -> Result<Self, OSStatus> {
899 let mut format_description: CMVideoFormatDescriptionRef = null_mut();
900 let status = unsafe {
901 CMVideoFormatDescriptionCreateFromH264ParameterSets(
902 kCFAllocatorDefault,
903 parameter_sets.len(),
904 parameter_sets.iter().map(|data| data.as_ptr()).collect::<Vec<_>>().as_ptr(),
905 parameter_sets.iter().map(|data| data.len()).collect::<Vec<_>>().as_ptr(),
906 nal_unit_header_length,
907 &mut format_description,
908 )
909 };
910 if status == 0 {
911 Ok(unsafe { TCFType::wrap_under_create_rule(format_description) })
912 } else {
913 Err(status)
914 }
915 }
916
917 #[inline]
918 pub fn from_hevc_parameter_sets(
919 parameter_sets: &[&[u8]],
920 nal_unit_header_length: i32,
921 extensions: &CFDictionary<CFString, CFType>,
922 ) -> Result<Self, OSStatus> {
923 let mut format_description: CMVideoFormatDescriptionRef = null_mut();
924 let status = unsafe {
925 CMVideoFormatDescriptionCreateFromHEVCParameterSets(
926 kCFAllocatorDefault,
927 parameter_sets.len(),
928 parameter_sets.iter().map(|data| data.as_ptr()).collect::<Vec<_>>().as_ptr(),
929 parameter_sets.iter().map(|data| data.len()).collect::<Vec<_>>().as_ptr(),
930 nal_unit_header_length,
931 extensions.as_concrete_TypeRef(),
932 &mut format_description,
933 )
934 };
935 if status == 0 {
936 Ok(unsafe { TCFType::wrap_under_create_rule(format_description) })
937 } else {
938 Err(status)
939 }
940 }
941
942 #[inline]
943 pub fn get_h264_parameter_set_at_index(&self, parameter_set_index: usize) -> Result<(&[u8], usize, i32), OSStatus> {
944 let mut parameter_set_pointer = null();
945 let mut parameter_set_size = 0;
946 let mut parameter_set_count = 0;
947 let mut nal_unit_header_length = 0;
948 let status = unsafe {
949 CMVideoFormatDescriptionGetH264ParameterSetAtIndex(
950 self.as_concrete_TypeRef(),
951 parameter_set_index,
952 &mut parameter_set_pointer,
953 &mut parameter_set_size,
954 &mut parameter_set_count,
955 &mut nal_unit_header_length,
956 )
957 };
958 if status == 0 {
959 Ok((unsafe { from_raw_parts(parameter_set_pointer, parameter_set_size) }, parameter_set_count, nal_unit_header_length))
960 } else {
961 Err(status)
962 }
963 }
964
965 #[inline]
966 pub fn get_hevc_parameter_set_at_index(&self, parameter_set_index: usize) -> Result<(&[u8], usize, i32), OSStatus> {
967 let mut parameter_set_pointer = null();
968 let mut parameter_set_size = 0;
969 let mut parameter_set_count = 0;
970 let mut nal_unit_header_length = 0;
971 let status = unsafe {
972 CMVideoFormatDescriptionGetHEVCParameterSetAtIndex(
973 self.as_concrete_TypeRef(),
974 parameter_set_index,
975 &mut parameter_set_pointer,
976 &mut parameter_set_size,
977 &mut parameter_set_count,
978 &mut nal_unit_header_length,
979 )
980 };
981 if status == 0 {
982 Ok((unsafe { from_raw_parts(parameter_set_pointer, parameter_set_size) }, parameter_set_count, nal_unit_header_length))
983 } else {
984 Err(status)
985 }
986 }
987
988 #[inline]
989 pub fn get_codec_type(&self) -> CMVideoCodecType {
990 unsafe { CMFormatDescriptionGetMediaSubType(self.as_concrete_TypeRef()) }
991 }
992
993 #[inline]
994 pub fn get_dimensions(&self) -> CMVideoDimensions {
995 unsafe { CMVideoFormatDescriptionGetDimensions(self.as_concrete_TypeRef()) }
996 }
997
998 #[inline]
999 pub fn get_presentation_dimensions(&self, use_pixel_aspect_ratio: bool, use_clean_aperture: bool) -> CGSize {
1000 unsafe { CMVideoFormatDescriptionGetPresentationDimensions(self.as_concrete_TypeRef(), use_pixel_aspect_ratio as _, use_clean_aperture as _) }
1001 }
1002
1003 #[inline]
1004 pub fn get_clean_aperture(&self, origin_is_at_top_left: bool) -> CGRect {
1005 unsafe { CMVideoFormatDescriptionGetCleanAperture(self.as_concrete_TypeRef(), origin_is_at_top_left as _) }
1006 }
1007
1008 #[inline]
1009 pub fn get_extension_keys_common_with_image_buffers() -> CFArray<CFString> {
1010 unsafe { TCFType::wrap_under_create_rule(CMVideoFormatDescriptionGetExtensionKeysCommonWithImageBuffers()) }
1011 }
1012
1013 #[inline]
1014 pub fn matches_image_buffer(&self, image_buffer: &CVImageBuffer) -> bool {
1015 unsafe { CMVideoFormatDescriptionMatchesImageBuffer(self.as_concrete_TypeRef(), image_buffer.as_concrete_TypeRef()) != 0 }
1016 }
1017}
1018
1019impl TCMFormatDescription for CMMuxedFormatDescription {}
1020
1021declare_TCFType!(CMMuxedFormatDescription, CMMuxedFormatDescriptionRef);
1022impl_TCFType!(CMMuxedFormatDescription, CMMuxedFormatDescriptionRef, CMFormatDescriptionGetTypeID);
1023impl_CFTypeDescription!(CMMuxedFormatDescription);
1024
1025impl CMMuxedFormatDescription {
1026 #[inline]
1027 pub fn new(mux_type: CMMuxedStreamType, extensions: &CFDictionary<CFString, CFType>) -> Result<Self, OSStatus> {
1028 let mut format_description: CMMuxedFormatDescriptionRef = null_mut();
1029 let status =
1030 unsafe { CMMuxedFormatDescriptionCreate(kCFAllocatorDefault, mux_type, extensions.as_concrete_TypeRef(), &mut format_description) };
1031 if status == 0 {
1032 Ok(unsafe { TCFType::wrap_under_create_rule(format_description) })
1033 } else {
1034 Err(status)
1035 }
1036 }
1037
1038 #[inline]
1039 pub fn get_stream_type(&self) -> CMMuxedStreamType {
1040 unsafe { CMFormatDescriptionGetMediaSubType(self.as_concrete_TypeRef()) }
1041 }
1042}
1043
1044impl TCMFormatDescription for CMClosedCaptionFormatDescription {}
1045
1046declare_TCFType!(CMClosedCaptionFormatDescription, CMClosedCaptionFormatDescriptionRef);
1047impl_TCFType!(CMClosedCaptionFormatDescription, CMClosedCaptionFormatDescriptionRef, CMFormatDescriptionGetTypeID);
1048impl_CFTypeDescription!(CMClosedCaptionFormatDescription);
1049
1050impl CMClosedCaptionFormatDescription {
1051 #[inline]
1052 pub fn new(format_type: CMClosedCaptionFormatType, extensions: Option<&CFDictionary<CFString, CFType>>) -> Result<Self, OSStatus> {
1053 let mut format_description: CMClosedCaptionFormatDescriptionRef = null_mut();
1054 let status = unsafe {
1055 CMFormatDescriptionCreate(
1056 kCFAllocatorDefault,
1057 kCMMediaType_ClosedCaption,
1058 format_type,
1059 extensions.map_or(null(), |exts| exts.as_concrete_TypeRef()),
1060 &mut format_description,
1061 )
1062 };
1063 if status == 0 {
1064 Ok(unsafe { TCFType::wrap_under_create_rule(format_description) })
1065 } else {
1066 Err(status)
1067 }
1068 }
1069
1070 #[inline]
1071 pub fn get_format_type(&self) -> CMClosedCaptionFormatType {
1072 unsafe { CMFormatDescriptionGetMediaSubType(self.as_concrete_TypeRef()) }
1073 }
1074}
1075
1076impl TCMFormatDescription for CMTextFormatDescription {}
1077
1078declare_TCFType!(CMTextFormatDescription, CMTextFormatDescriptionRef);
1079impl_TCFType!(CMTextFormatDescription, CMTextFormatDescriptionRef, CMFormatDescriptionGetTypeID);
1080impl_CFTypeDescription!(CMTextFormatDescription);
1081
1082impl CMTextFormatDescription {
1083 #[inline]
1084 pub fn new(format_type: CMTextFormatType, extensions: Option<&CFDictionary<CFString, CFType>>) -> Result<Self, OSStatus> {
1085 let mut format_description: CMTextFormatDescriptionRef = null_mut();
1086 let status = unsafe {
1087 CMFormatDescriptionCreate(
1088 kCFAllocatorDefault,
1089 kCMMediaType_Text,
1090 format_type,
1091 extensions.map_or(null(), |exts| exts.as_concrete_TypeRef()),
1092 &mut format_description,
1093 )
1094 };
1095 if status == 0 {
1096 Ok(unsafe { TCFType::wrap_under_create_rule(format_description) })
1097 } else {
1098 Err(status)
1099 }
1100 }
1101
1102 #[inline]
1103 pub fn get_format_type(&self) -> CMTextFormatType {
1104 unsafe { CMFormatDescriptionGetMediaSubType(self.as_concrete_TypeRef()) }
1105 }
1106
1107 #[inline]
1108 pub fn get_display_flags(&self) -> Result<CMTextDisplayFlags, OSStatus> {
1109 let mut display_flags = 0;
1110 let status = unsafe { CMTextFormatDescriptionGetDisplayFlags(self.as_concrete_TypeRef(), &mut display_flags) };
1111 if status == 0 {
1112 Ok(display_flags)
1113 } else {
1114 Err(status)
1115 }
1116 }
1117
1118 #[inline]
1119 pub fn get_justification(&self) -> Result<(CMTextJustificationValue, CMTextJustificationValue), OSStatus> {
1120 let mut horizontal_justification = 0;
1121 let mut vertical_justification = 0;
1122 let status = unsafe {
1123 CMTextFormatDescriptionGetJustification(self.as_concrete_TypeRef(), &mut horizontal_justification, &mut vertical_justification)
1124 };
1125 if status == 0 {
1126 Ok((horizontal_justification, vertical_justification))
1127 } else {
1128 Err(status)
1129 }
1130 }
1131
1132 #[inline]
1133 pub fn get_default_text_box(&self, origin_is_at_top_left: bool, height_of_text_track: CGFloat) -> Result<CGRect, OSStatus> {
1134 let mut default_text_box = CGRect::default();
1135 let status = unsafe {
1136 CMTextFormatDescriptionGetDefaultTextBox(
1137 self.as_concrete_TypeRef(),
1138 origin_is_at_top_left as _,
1139 height_of_text_track,
1140 &mut default_text_box,
1141 )
1142 };
1143 if status == 0 {
1144 Ok(default_text_box)
1145 } else {
1146 Err(status)
1147 }
1148 }
1149
1150 #[inline]
1151 pub fn get_default_style(&self) -> Result<(u16, bool, bool, bool, CGFloat, [CGFloat; 4]), OSStatus> {
1152 let mut local_font_id = 0;
1153 let mut bold: Boolean = 0;
1154 let mut italic: Boolean = 0;
1155 let mut underline: Boolean = 0;
1156 let mut font_size = 0.0;
1157 let mut color_components = [0.0; 4];
1158 let status = unsafe {
1159 CMTextFormatDescriptionGetDefaultStyle(
1160 self.as_concrete_TypeRef(),
1161 &mut local_font_id,
1162 &mut bold,
1163 &mut italic,
1164 &mut underline,
1165 &mut font_size,
1166 &mut color_components,
1167 )
1168 };
1169 if status == 0 {
1170 Ok((local_font_id, bold != 0, italic != 0, underline != 0, font_size, color_components))
1171 } else {
1172 Err(status)
1173 }
1174 }
1175
1176 #[inline]
1177 pub fn get_font_name(&self, local_font_id: u16) -> Result<CFString, OSStatus> {
1178 let mut font_name = null();
1179 let status = unsafe { CMTextFormatDescriptionGetFontName(self.as_concrete_TypeRef(), local_font_id, &mut font_name) };
1180 if status == 0 {
1181 Ok(unsafe { TCFType::wrap_under_create_rule(font_name) })
1182 } else {
1183 Err(status)
1184 }
1185 }
1186}
1187
1188impl TCMFormatDescription for CMTimeCodeFormatDescription {}
1189
1190declare_TCFType!(CMTimeCodeFormatDescription, CMTimeCodeFormatDescriptionRef);
1191impl_TCFType!(CMTimeCodeFormatDescription, CMTimeCodeFormatDescriptionRef, CMFormatDescriptionGetTypeID);
1192impl_CFTypeDescription!(CMTimeCodeFormatDescription);
1193
1194impl CMTimeCodeFormatDescription {
1195 #[inline]
1196 pub fn new(
1197 time_code_format_type: CMTimeCodeFormatType,
1198 frame_duration: CMTime,
1199 frame_quanta: u32,
1200 flags: u32,
1201 extensions: Option<&CFDictionary<CFString, CFType>>,
1202 ) -> Result<Self, OSStatus> {
1203 let mut format_description: CMTimeCodeFormatDescriptionRef = null_mut();
1204 let status = unsafe {
1205 CMTimeCodeFormatDescriptionCreate(
1206 kCFAllocatorDefault,
1207 time_code_format_type,
1208 frame_duration,
1209 frame_quanta,
1210 flags,
1211 extensions.map_or(null(), |exts| exts.as_concrete_TypeRef()),
1212 &mut format_description,
1213 )
1214 };
1215 if status == 0 {
1216 Ok(unsafe { TCFType::wrap_under_create_rule(format_description) })
1217 } else {
1218 Err(status)
1219 }
1220 }
1221
1222 #[inline]
1223 pub fn get_format_type(&self) -> CMTimeCodeFormatType {
1224 unsafe { CMFormatDescriptionGetMediaSubType(self.as_concrete_TypeRef()) }
1225 }
1226
1227 #[inline]
1228 pub fn get_frame_duration(&self) -> CMTime {
1229 unsafe { CMTimeCodeFormatDescriptionGetFrameDuration(self.as_concrete_TypeRef()) }
1230 }
1231
1232 #[inline]
1233 pub fn get_frame_quanta(&self) -> u32 {
1234 unsafe { CMTimeCodeFormatDescriptionGetFrameQuanta(self.as_concrete_TypeRef()) }
1235 }
1236
1237 #[inline]
1238 pub fn get_time_code_flags(&self) -> u32 {
1239 unsafe { CMTimeCodeFormatDescriptionGetTimeCodeFlags(self.as_concrete_TypeRef()) }
1240 }
1241}
1242
1243impl TCMFormatDescription for CMMetadataFormatDescription {}
1244
1245declare_TCFType!(CMMetadataFormatDescription, CMMetadataFormatDescriptionRef);
1246impl_TCFType!(CMMetadataFormatDescription, CMMetadataFormatDescriptionRef, CMFormatDescriptionGetTypeID);
1247impl_CFTypeDescription!(CMMetadataFormatDescription);
1248
1249impl CMMetadataFormatDescription {
1250 #[inline]
1251 pub fn new_with_keys(metadata_type: CMMetadataFormatType, keys: Option<&CFArray<CFString>>) -> Result<Self, OSStatus> {
1252 let mut format_description: CMMetadataFormatDescriptionRef = null_mut();
1253 let status = unsafe {
1254 CMMetadataFormatDescriptionCreateWithKeys(
1255 kCFAllocatorDefault,
1256 metadata_type,
1257 keys.map_or(null(), |keys| keys.as_concrete_TypeRef()),
1258 &mut format_description,
1259 )
1260 };
1261 if status == 0 {
1262 Ok(unsafe { TCFType::wrap_under_create_rule(format_description) })
1263 } else {
1264 Err(status)
1265 }
1266 }
1267
1268 #[inline]
1269 pub fn new_with_metadata_specifications(
1270 metadata_type: CMMetadataFormatType,
1271 metadata_specifications: &CFArray<CFDictionary<CFString, CFType>>,
1272 ) -> Result<Self, OSStatus> {
1273 let mut format_description: CMMetadataFormatDescriptionRef = null_mut();
1274 let status = unsafe {
1275 CMMetadataFormatDescriptionCreateWithMetadataSpecifications(
1276 kCFAllocatorDefault,
1277 metadata_type,
1278 metadata_specifications.as_concrete_TypeRef(),
1279 &mut format_description,
1280 )
1281 };
1282 if status == 0 {
1283 Ok(unsafe { TCFType::wrap_under_create_rule(format_description) })
1284 } else {
1285 Err(status)
1286 }
1287 }
1288
1289 #[inline]
1290 pub fn new_with_metadata_format_description_and_metadata_specifications(
1291 source_description: &CMMetadataFormatDescription,
1292 metadata_specifications: &CFArray<CFDictionary<CFString, CFType>>,
1293 ) -> Result<Self, OSStatus> {
1294 let mut format_description: CMMetadataFormatDescriptionRef = null_mut();
1295 let status = unsafe {
1296 CMMetadataFormatDescriptionCreateWithMetadataFormatDescriptionAndMetadataSpecifications(
1297 kCFAllocatorDefault,
1298 source_description.as_concrete_TypeRef(),
1299 metadata_specifications.as_concrete_TypeRef(),
1300 &mut format_description,
1301 )
1302 };
1303 if status == 0 {
1304 Ok(unsafe { TCFType::wrap_under_create_rule(format_description) })
1305 } else {
1306 Err(status)
1307 }
1308 }
1309
1310 #[inline]
1311 pub fn new_by_merging_metadata_format_descriptions(
1312 source_description: &CMMetadataFormatDescription,
1313 other_source_description: &CMMetadataFormatDescription,
1314 ) -> Result<Self, OSStatus> {
1315 let mut format_description: CMMetadataFormatDescriptionRef = null_mut();
1316 let status = unsafe {
1317 CMMetadataFormatDescriptionCreateByMergingMetadataFormatDescriptions(
1318 kCFAllocatorDefault,
1319 source_description.as_concrete_TypeRef(),
1320 other_source_description.as_concrete_TypeRef(),
1321 &mut format_description,
1322 )
1323 };
1324 if status == 0 {
1325 Ok(unsafe { TCFType::wrap_under_create_rule(format_description) })
1326 } else {
1327 Err(status)
1328 }
1329 }
1330
1331 #[inline]
1332 pub fn get_key_with_local_id(&self, local_key_id: OSType) -> Option<CFDictionary<CFString, CFType>> {
1333 unsafe {
1334 let key = CMMetadataFormatDescriptionGetKeyWithLocalID(self.as_concrete_TypeRef(), local_key_id);
1335 if key.is_null() {
1336 None
1337 } else {
1338 Some(TCFType::wrap_under_get_rule(key))
1339 }
1340 }
1341 }
1342
1343 #[inline]
1344 pub fn get_identifiers(&self) -> Option<CFArray<CFString>> {
1345 unsafe {
1346 let identifiers = CMMetadataFormatDescriptionGetIdentifiers(self.as_concrete_TypeRef());
1347 if identifiers.is_null() {
1348 None
1349 } else {
1350 Some(TCFType::wrap_under_get_rule(identifiers))
1351 }
1352 }
1353 }
1354}