objc2_video_toolbox/generated/
VTCompressionSession.rs

1//! This file has been automatically generated by `objc2`'s `header-translator`.
2//! DO NOT EDIT
3use core::cell::UnsafeCell;
4use core::ffi::*;
5use core::marker::{PhantomData, PhantomPinned};
6use core::ptr::NonNull;
7#[cfg(feature = "objc2")]
8use objc2::__framework_prelude::*;
9use objc2_core_foundation::*;
10#[cfg(feature = "objc2-core-media")]
11use objc2_core_media::*;
12#[cfg(feature = "objc2-core-video")]
13use objc2_core_video::*;
14
15use crate::*;
16
17/// A reference to a Video Toolbox Compression Session.
18///
19/// A compression session supports the compression of a sequence of video frames.
20/// The session reference is a reference-counted CF object.
21/// To create a compression session, call VTCompressionSessionCreate;
22/// then you can optionally configure the session using VTSessionSetProperty;
23/// then to encode frames, call VTCompressionSessionEncodeFrame.
24/// To force completion of some or all pending frames, call VTCompressionSessionCompleteFrames.
25/// When you are done with the session, you should call VTCompressionSessionInvalidate
26/// to tear it down and CFRelease to release your object reference.
27///
28/// See also [Apple's documentation](https://developer.apple.com/documentation/videotoolbox/vtcompressionsession?language=objc)
29#[doc(alias = "VTCompressionSessionRef")]
30#[repr(C)]
31pub struct VTCompressionSession {
32    inner: [u8; 0],
33    _p: UnsafeCell<PhantomData<(*const UnsafeCell<()>, PhantomPinned)>>,
34}
35
36cf_type!(
37    unsafe impl VTCompressionSession {}
38);
39#[cfg(feature = "objc2")]
40cf_objc2_type!(
41    unsafe impl RefEncode<"OpaqueVTCompressionSession"> for VTCompressionSession {}
42);
43
44/// Prototype for callback invoked when frame compression is complete.
45///
46/// When you create a compression session, you pass in a callback function to be called
47/// for compressed frames.  This function will be called in decode order (which is not
48/// necessarily the same as display order).
49///
50/// Parameter `outputCallbackRefCon`: The callback's reference value.
51///
52/// Parameter `sourceFrameRefCon`: The frame's reference value, copied from the sourceFrameRefCon argument to
53/// VTCompressionSessionEncodeFrame.
54///
55/// Parameter `status`: noErr if compression was successful; an error code if compression was not successful.
56///
57/// Parameter `infoFlags`: Contains information about the encode operation.
58/// The kVTEncodeInfo_Asynchronous bit may be set if the encode ran asynchronously.
59/// The kVTEncodeInfo_FrameDropped bit may be set if the frame was dropped.
60///
61/// Parameter `sampleBuffer`: Contains the compressed frame, if compression was successful and the frame was not dropped;
62/// otherwise, NULL.
63///
64/// See also [Apple's documentation](https://developer.apple.com/documentation/videotoolbox/vtcompressionoutputcallback?language=objc)
65#[cfg(all(feature = "VTErrors", feature = "objc2-core-media"))]
66pub type VTCompressionOutputCallback = Option<
67    unsafe extern "C-unwind" fn(
68        *mut c_void,
69        *mut c_void,
70        OSStatus,
71        VTEncodeInfoFlags,
72        *mut CMSampleBuffer,
73    ),
74>;
75
76extern "C" {
77    /// Specifies a particular video encoder by its ID string.
78    ///
79    /// To specify a particular video encoder when creating a compression session, pass an
80    /// encoderSpecification CFDictionary containing this key and the EncoderID as its value.
81    /// The EncoderID CFString may be obtained from the kVTVideoEncoderList_EncoderID entry in
82    /// the array returned by VTCopyVideoEncoderList.
83    ///
84    /// See also [Apple's documentation](https://developer.apple.com/documentation/videotoolbox/kvtvideoencoderspecification_encoderid?language=objc)
85    pub static kVTVideoEncoderSpecification_EncoderID: &'static CFString;
86}
87
88impl VTCompressionSession {
89    /// Creates a session for compressing video frames.
90    ///
91    /// Compressed frames will be emitted through calls to outputCallback.
92    ///
93    /// Parameter `allocator`: An allocator for the session.  Pass NULL to use the default allocator.
94    ///
95    /// Parameter `width`: The width of frames, in pixels.
96    /// If the video encoder cannot support the provided width and height it may change them.
97    ///
98    /// Parameter `height`: The height of frames in pixels.
99    ///
100    /// Parameter `codecType`: The codec type.
101    ///
102    /// Parameter `encoderSpecification`: Specifies a particular video encoder that must be used.
103    /// Pass NULL to let the video toolbox choose a encoder.
104    ///
105    /// Parameter `sourceImageBufferAttributes`: Required attributes for source pixel buffers, used when creating a pixel buffer pool
106    /// for source frames.  If you do not want the Video Toolbox to create one for you, pass NULL.
107    /// (Using pixel buffers not allocated by the Video Toolbox may increase the chance that
108    /// it will be necessary to copy image data.)
109    ///
110    /// Parameter `compressedDataAllocator`: An allocator for the compressed data.  Pass NULL to use the default allocator.
111    /// Note: on MacOS 10.12 and later, using a compressedDataAllocator may trigger an extra buffer copy.
112    ///
113    /// Parameter `outputCallback`: The callback to be called with compressed frames.
114    /// This function may be called asynchronously, on a different thread from the one that calls VTCompressionSessionEncodeFrame.
115    /// Pass NULL if and only if you will be calling VTCompressionSessionEncodeFrameWithOutputHandler for encoding frames.
116    ///
117    /// Parameter `outputCallbackRefCon`: Client-defined reference value for the output callback.
118    ///
119    /// Parameter `compressionSessionOut`: Points to a variable to receive the new compression session.
120    ///
121    /// # Safety
122    ///
123    /// - `encoder_specification` generics must be of the correct type.
124    /// - `source_image_buffer_attributes` generics must be of the correct type.
125    /// - `output_callback` must be implemented correctly.
126    /// - `output_callback_ref_con` must be a valid pointer or null.
127    /// - `compression_session_out` must be a valid pointer.
128    #[doc(alias = "VTCompressionSessionCreate")]
129    #[cfg(all(feature = "VTErrors", feature = "objc2-core-media"))]
130    #[inline]
131    pub unsafe fn create(
132        allocator: Option<&CFAllocator>,
133        width: i32,
134        height: i32,
135        codec_type: CMVideoCodecType,
136        encoder_specification: Option<&CFDictionary>,
137        source_image_buffer_attributes: Option<&CFDictionary>,
138        compressed_data_allocator: Option<&CFAllocator>,
139        output_callback: VTCompressionOutputCallback,
140        output_callback_ref_con: *mut c_void,
141        compression_session_out: NonNull<*mut VTCompressionSession>,
142    ) -> OSStatus {
143        extern "C-unwind" {
144            fn VTCompressionSessionCreate(
145                allocator: Option<&CFAllocator>,
146                width: i32,
147                height: i32,
148                codec_type: CMVideoCodecType,
149                encoder_specification: Option<&CFDictionary>,
150                source_image_buffer_attributes: Option<&CFDictionary>,
151                compressed_data_allocator: Option<&CFAllocator>,
152                output_callback: VTCompressionOutputCallback,
153                output_callback_ref_con: *mut c_void,
154                compression_session_out: NonNull<*mut VTCompressionSession>,
155            ) -> OSStatus;
156        }
157        unsafe {
158            VTCompressionSessionCreate(
159                allocator,
160                width,
161                height,
162                codec_type,
163                encoder_specification,
164                source_image_buffer_attributes,
165                compressed_data_allocator,
166                output_callback,
167                output_callback_ref_con,
168                compression_session_out,
169            )
170        }
171    }
172
173    /// Tears down a compression session.
174    ///
175    /// When you are done with a compression session you created, call VTCompressionSessionInvalidate
176    /// to tear it down and then CFRelease to release your object reference.
177    /// When a compression session's retain count reaches zero, it is automatically invalidated, but
178    /// since sessions may be retained by multiple parties, it can be hard to predict when this will happen.
179    /// Calling VTCompressionSessionInvalidate ensures a deterministic, orderly teardown.
180    #[doc(alias = "VTCompressionSessionInvalidate")]
181    #[inline]
182    pub unsafe fn invalidate(&self) {
183        extern "C-unwind" {
184            fn VTCompressionSessionInvalidate(session: &VTCompressionSession);
185        }
186        unsafe { VTCompressionSessionInvalidate(self) }
187    }
188}
189
190unsafe impl ConcreteType for VTCompressionSession {
191    /// Returns the CFTypeID for compression sessions.
192    #[doc(alias = "VTCompressionSessionGetTypeID")]
193    #[inline]
194    fn type_id() -> CFTypeID {
195        extern "C-unwind" {
196            fn VTCompressionSessionGetTypeID() -> CFTypeID;
197        }
198        unsafe { VTCompressionSessionGetTypeID() }
199    }
200}
201
202impl VTCompressionSession {
203    /// Returns a pool that can provide ideal source pixel buffers for a compression session.
204    ///
205    /// The compression session creates this pixel buffer pool based on
206    /// the compressor's pixel buffer attributes and any pixel buffer
207    /// attributes passed in to VTCompressionSessionCreate.  If the
208    /// source pixel buffer attributes and the compressor pixel buffer
209    /// attributes cannot be reconciled, the pool is based on the source
210    /// pixel buffer attributes and the Video Toolbox converts each CVImageBuffer
211    /// internally.
212    /// <BR
213    /// >
214    /// While clients can call VTCompressionSessionGetPixelBufferPool once
215    /// and retain the resulting pool, the call is cheap enough that it's OK
216    /// to call it once per frame.  If a change of session properties causes
217    /// the compressor's pixel buffer attributes to change, it's possible that
218    /// VTCompressionSessionGetPixelBufferPool might return a different pool.
219    #[doc(alias = "VTCompressionSessionGetPixelBufferPool")]
220    #[cfg(feature = "objc2-core-video")]
221    #[inline]
222    pub unsafe fn pixel_buffer_pool(&self) -> Option<CFRetained<CVPixelBufferPool>> {
223        extern "C-unwind" {
224            fn VTCompressionSessionGetPixelBufferPool(
225                session: &VTCompressionSession,
226            ) -> Option<NonNull<CVPixelBufferPool>>;
227        }
228        let ret = unsafe { VTCompressionSessionGetPixelBufferPool(self) };
229        ret.map(|ret| unsafe { CFRetained::retain(ret) })
230    }
231
232    /// You can optionally call this function to provide the encoder with an opportunity to perform
233    /// any necessary resource allocation before it begins encoding frames.
234    ///
235    /// This optional call can be used to provide the encoder an opportunity to allocate
236    /// any resources necessary before it begins encoding frames.  If this isn't called, any
237    /// necessary resources will be allocated on the first VTCompressionSessionEncodeFrame call.
238    /// Extra calls to this function will have no effect.
239    ///
240    /// Parameter `session`: The compression session.
241    #[doc(alias = "VTCompressionSessionPrepareToEncodeFrames")]
242    #[inline]
243    pub unsafe fn prepare_to_encode_frames(&self) -> OSStatus {
244        extern "C-unwind" {
245            fn VTCompressionSessionPrepareToEncodeFrames(
246                session: &VTCompressionSession,
247            ) -> OSStatus;
248        }
249        unsafe { VTCompressionSessionPrepareToEncodeFrames(self) }
250    }
251
252    /// Call this function to present frames to the compression session.
253    /// Encoded frames may or may not be output before the function returns.
254    ///
255    /// The client should not modify the pixel data after making this call.
256    /// The session and/or encoder will retain the image buffer as long as necessary.
257    ///
258    /// Parameter `session`: The compression session.
259    ///
260    /// Parameter `imageBuffer`: A CVImageBuffer containing a video frame to be compressed.
261    /// Must have a nonzero reference count.
262    ///
263    /// Parameter `presentationTimeStamp`: The presentation timestamp for this frame, to be attached to the sample buffer.
264    /// Each presentation timestamp passed to a session must be greater than the previous one.
265    ///
266    /// Parameter `duration`: The presentation duration for this frame, to be attached to the sample buffer.
267    /// If you do not have duration information, pass kCMTimeInvalid.
268    ///
269    /// Parameter `frameProperties`: Contains key/value pairs specifying additional properties for encoding this frame.
270    /// Note that some session properties may also be changed between frames.
271    /// Such changes have effect on subsequently encoded frames.
272    ///
273    /// Parameter `sourceFrameRefcon`: Your reference value for the frame, which will be passed to the output callback function.
274    ///
275    /// Parameter `infoFlagsOut`: Points to a VTEncodeInfoFlags to receive information about the encode operation.
276    /// The kVTEncodeInfo_Asynchronous bit may be set if the encode is (or was) running
277    /// asynchronously.
278    /// The kVTEncodeInfo_FrameDropped bit may be set if the frame was dropped (synchronously).
279    /// Pass NULL if you do not want to receive this information.
280    ///
281    /// # Safety
282    ///
283    /// - `frame_properties` generics must be of the correct type.
284    /// - `source_frame_refcon` must be a valid pointer or null.
285    /// - `info_flags_out` must be a valid pointer or null.
286    #[doc(alias = "VTCompressionSessionEncodeFrame")]
287    #[cfg(all(
288        feature = "VTErrors",
289        feature = "objc2-core-media",
290        feature = "objc2-core-video"
291    ))]
292    #[inline]
293    pub unsafe fn encode_frame(
294        &self,
295        image_buffer: &CVImageBuffer,
296        presentation_time_stamp: CMTime,
297        duration: CMTime,
298        frame_properties: Option<&CFDictionary>,
299        source_frame_refcon: *mut c_void,
300        info_flags_out: *mut VTEncodeInfoFlags,
301    ) -> OSStatus {
302        extern "C-unwind" {
303            fn VTCompressionSessionEncodeFrame(
304                session: &VTCompressionSession,
305                image_buffer: &CVImageBuffer,
306                presentation_time_stamp: CMTime,
307                duration: CMTime,
308                frame_properties: Option<&CFDictionary>,
309                source_frame_refcon: *mut c_void,
310                info_flags_out: *mut VTEncodeInfoFlags,
311            ) -> OSStatus;
312        }
313        unsafe {
314            VTCompressionSessionEncodeFrame(
315                self,
316                image_buffer,
317                presentation_time_stamp,
318                duration,
319                frame_properties,
320                source_frame_refcon,
321                info_flags_out,
322            )
323        }
324    }
325}
326
327/// Prototype for block invoked when frame compression is complete.
328///
329/// When you encode a frame, you pass in a callback block to be called
330/// for that compressed frame.  This block will be called in decode order (which is not
331/// necessarily the same as display order).
332///
333/// Parameter `status`: noErr if compression was successful; an error code if compression was not successful.
334///
335/// Parameter `infoFlags`: Contains information about the encode operation.
336/// The kVTEncodeInfo_Asynchronous bit may be set if the encode ran asynchronously.
337/// The kVTEncodeInfo_FrameDropped bit may be set if the frame was dropped.
338///
339/// Parameter `sampleBuffer`: Contains the compressed frame, if compression was successful and the frame was not dropped;
340/// otherwise, NULL.
341///
342/// See also [Apple's documentation](https://developer.apple.com/documentation/videotoolbox/vtcompressionoutputhandler?language=objc)
343#[cfg(all(feature = "VTErrors", feature = "block2", feature = "objc2-core-media"))]
344pub type VTCompressionOutputHandler =
345    *mut block2::DynBlock<dyn Fn(OSStatus, VTEncodeInfoFlags, *mut CMSampleBuffer)>;
346
347impl VTCompressionSession {
348    /// Call this function to present frames to the compression session.
349    /// Encoded frames may or may not be output before the function returns.
350    ///
351    /// The client should not modify the pixel data after making this call.
352    /// The session and/or encoder will retain the image buffer as long as necessary.
353    /// Cannot be called with a session created with a VTCompressionOutputCallback.
354    ///
355    /// Parameter `session`: The compression session.
356    ///
357    /// Parameter `imageBuffer`: A CVImageBuffer containing a video frame to be compressed.
358    /// Must have a nonzero reference count.
359    ///
360    /// Parameter `presentationTimeStamp`: The presentation timestamp for this frame, to be attached to the sample buffer.
361    /// Each presentation timestamp passed to a session must be greater than the previous one.
362    ///
363    /// Parameter `duration`: The presentation duration for this frame, to be attached to the sample buffer.
364    /// If you do not have duration information, pass kCMTimeInvalid.
365    ///
366    /// Parameter `frameProperties`: Contains key/value pairs specifying additional properties for encoding this frame.
367    /// Note that some session properties may also be changed between frames.
368    /// Such changes have effect on subsequently encoded frames.
369    ///
370    /// Parameter `infoFlagsOut`: Points to a VTEncodeInfoFlags to receive information about the encode operation.
371    /// The kVTEncodeInfo_Asynchronous bit may be set if the encode is (or was) running
372    /// asynchronously.
373    /// The kVTEncodeInfo_FrameDropped bit may be set if the frame was dropped (synchronously).
374    /// Pass NULL if you do not want to receive this information.
375    ///
376    /// Parameter `outputHandler`: The block to be called when encoding the frame is completed.
377    /// This block may be called asynchronously, on a different thread from the one that calls VTCompressionSessionEncodeFrameWithOutputHandler.
378    ///
379    /// # Safety
380    ///
381    /// - `frame_properties` generics must be of the correct type.
382    /// - `info_flags_out` must be a valid pointer or null.
383    /// - `output_handler` must be a valid pointer.
384    #[doc(alias = "VTCompressionSessionEncodeFrameWithOutputHandler")]
385    #[cfg(all(
386        feature = "VTErrors",
387        feature = "block2",
388        feature = "objc2-core-media",
389        feature = "objc2-core-video"
390    ))]
391    #[inline]
392    pub unsafe fn encode_frame_with_output_handler(
393        &self,
394        image_buffer: &CVImageBuffer,
395        presentation_time_stamp: CMTime,
396        duration: CMTime,
397        frame_properties: Option<&CFDictionary>,
398        info_flags_out: *mut VTEncodeInfoFlags,
399        output_handler: VTCompressionOutputHandler,
400    ) -> OSStatus {
401        extern "C-unwind" {
402            fn VTCompressionSessionEncodeFrameWithOutputHandler(
403                session: &VTCompressionSession,
404                image_buffer: &CVImageBuffer,
405                presentation_time_stamp: CMTime,
406                duration: CMTime,
407                frame_properties: Option<&CFDictionary>,
408                info_flags_out: *mut VTEncodeInfoFlags,
409                output_handler: VTCompressionOutputHandler,
410            ) -> OSStatus;
411        }
412        unsafe {
413            VTCompressionSessionEncodeFrameWithOutputHandler(
414                self,
415                image_buffer,
416                presentation_time_stamp,
417                duration,
418                frame_properties,
419                info_flags_out,
420                output_handler,
421            )
422        }
423    }
424
425    /// Forces the compression session to complete encoding frames.
426    ///
427    /// If completeUntilPresentationTimeStamp is numeric, frames with presentation timestamps
428    /// up to and including this timestamp will be emitted before the function returns.
429    /// If completeUntilPresentationTimeStamp is non-numeric, all pending frames
430    /// will be emitted before the function returns.
431    #[doc(alias = "VTCompressionSessionCompleteFrames")]
432    #[cfg(feature = "objc2-core-media")]
433    #[inline]
434    pub unsafe fn complete_frames(
435        &self,
436        complete_until_presentation_time_stamp: CMTime,
437    ) -> OSStatus {
438        extern "C-unwind" {
439            fn VTCompressionSessionCompleteFrames(
440                session: &VTCompressionSession,
441                complete_until_presentation_time_stamp: CMTime,
442            ) -> OSStatus;
443        }
444        unsafe { VTCompressionSessionCompleteFrames(self, complete_until_presentation_time_stamp) }
445    }
446}
447
448/// Indicates whether the current system supports stereo MV-HEVC encode.
449///
450/// This call returning true does not guarantee that encode resources will be available at all times.
451#[inline]
452pub unsafe extern "C-unwind" fn VTIsStereoMVHEVCEncodeSupported() -> bool {
453    extern "C-unwind" {
454        fn VTIsStereoMVHEVCEncodeSupported() -> Boolean;
455    }
456    let ret = unsafe { VTIsStereoMVHEVCEncodeSupported() };
457    ret != 0
458}
459
460impl VTCompressionSession {
461    /// Call this function to present a multi-image frame to the compression session.
462    /// Encoded frames may or may not be output before the function returns.
463    ///
464    /// The client should not modify the pixel data after making this call.
465    /// The session and/or encoder will retain the image buffer as long as necessary.
466    ///
467    /// Parameter `session`: The compression session.
468    ///
469    /// Parameter `taggedBufferGroup`: A CMTaggedBufferGroup containing the multiple images for a video frame to be compressed.
470    ///
471    /// Parameter `presentationTimeStamp`: The presentation timestamp for this frame, to be attached to the sample buffer.
472    /// Each presentation timestamp passed to a session must be greater than the previous one.
473    ///
474    /// Parameter `duration`: The presentation duration for this frame, to be attached to the sample buffer.
475    /// If you do not have duration information, pass kCMTimeInvalid.
476    ///
477    /// Parameter `frameProperties`: Contains key/value pairs specifying additional properties for encoding this frame.
478    /// Note that some session properties may also be changed between frames.
479    /// Such changes have effect on subsequently encoded frames.
480    ///
481    /// Parameter `sourceFrameRefcon`: Your reference value for the frame, which will be passed to the output callback function.
482    ///
483    /// Parameter `infoFlagsOut`: Points to a VTEncodeInfoFlags to receive information about the encode operation.
484    /// The kVTEncodeInfo_Asynchronous bit may be set if the encode is (or was) running
485    /// asynchronously.
486    /// The kVTEncodeInfo_FrameDropped bit may be set if the frame was dropped (synchronously).
487    /// Pass NULL if you do not want to receive this information.
488    ///
489    /// # Safety
490    ///
491    /// - `frame_properties` generics must be of the correct type.
492    /// - `source_frame_refcon` must be a valid pointer or null.
493    /// - `info_flags_out` must be a valid pointer or null.
494    #[doc(alias = "VTCompressionSessionEncodeMultiImageFrame")]
495    #[cfg(all(feature = "VTErrors", feature = "objc2-core-media"))]
496    #[inline]
497    pub unsafe fn encode_multi_image_frame(
498        &self,
499        tagged_buffer_group: &CMTaggedBufferGroup,
500        presentation_time_stamp: CMTime,
501        duration: CMTime,
502        frame_properties: Option<&CFDictionary>,
503        source_frame_refcon: *mut c_void,
504        info_flags_out: *mut VTEncodeInfoFlags,
505    ) -> OSStatus {
506        extern "C-unwind" {
507            fn VTCompressionSessionEncodeMultiImageFrame(
508                session: &VTCompressionSession,
509                tagged_buffer_group: &CMTaggedBufferGroup,
510                presentation_time_stamp: CMTime,
511                duration: CMTime,
512                frame_properties: Option<&CFDictionary>,
513                source_frame_refcon: *mut c_void,
514                info_flags_out: *mut VTEncodeInfoFlags,
515            ) -> OSStatus;
516        }
517        unsafe {
518            VTCompressionSessionEncodeMultiImageFrame(
519                self,
520                tagged_buffer_group,
521                presentation_time_stamp,
522                duration,
523                frame_properties,
524                source_frame_refcon,
525                info_flags_out,
526            )
527        }
528    }
529
530    /// Call this function to present a multi-image frame to the compression session.
531    /// Encoded frames may or may not be output before the function returns.
532    ///
533    /// The client should not modify the pixel data after making this call.
534    /// The session and/or encoder will retain the image buffer as long as necessary.
535    /// Cannot be called with a session created with a VTCompressionOutputCallback.
536    ///
537    /// Parameter `session`: The compression session.
538    ///
539    /// Parameter `taggedBufferGroup`: A CMTaggedBufferGroup containing the multiple images for a video frame to be compressed.
540    ///
541    /// Parameter `presentationTimeStamp`: The presentation timestamp for this frame, to be attached to the sample buffer.
542    /// Each presentation timestamp passed to a session must be greater than the previous one.
543    ///
544    /// Parameter `duration`: The presentation duration for this frame, to be attached to the sample buffer.
545    /// If you do not have duration information, pass kCMTimeInvalid.
546    ///
547    /// Parameter `frameProperties`: Contains key/value pairs specifying additional properties for encoding this frame.
548    /// Note that some session properties may also be changed between frames.
549    /// Such changes have effect on subsequently encoded frames.
550    ///
551    /// Parameter `infoFlagsOut`: Points to a VTEncodeInfoFlags to receive information about the encode operation.
552    /// The kVTEncodeInfo_Asynchronous bit may be set if the encode is (or was) running
553    /// asynchronously.
554    /// The kVTEncodeInfo_FrameDropped bit may be set if the frame was dropped (synchronously).
555    /// Pass NULL if you do not want to receive this information.
556    ///
557    /// Parameter `outputHandler`: The block to be called when encoding the frame is completed.
558    /// This block may be called asynchronously, on a different thread from the one that calls VTCompressionSessionEncodeMultiImageFrameWithOutputHandler.
559    ///
560    /// # Safety
561    ///
562    /// - `frame_properties` generics must be of the correct type.
563    /// - `info_flags_out` must be a valid pointer or null.
564    /// - `output_handler` must be a valid pointer.
565    #[doc(alias = "VTCompressionSessionEncodeMultiImageFrameWithOutputHandler")]
566    #[cfg(all(feature = "VTErrors", feature = "block2", feature = "objc2-core-media"))]
567    #[inline]
568    pub unsafe fn encode_multi_image_frame_with_output_handler(
569        &self,
570        tagged_buffer_group: &CMTaggedBufferGroup,
571        presentation_time_stamp: CMTime,
572        duration: CMTime,
573        frame_properties: Option<&CFDictionary>,
574        info_flags_out: *mut VTEncodeInfoFlags,
575        output_handler: VTCompressionOutputHandler,
576    ) -> OSStatus {
577        extern "C-unwind" {
578            fn VTCompressionSessionEncodeMultiImageFrameWithOutputHandler(
579                session: &VTCompressionSession,
580                tagged_buffer_group: &CMTaggedBufferGroup,
581                presentation_time_stamp: CMTime,
582                duration: CMTime,
583                frame_properties: Option<&CFDictionary>,
584                info_flags_out: *mut VTEncodeInfoFlags,
585                output_handler: VTCompressionOutputHandler,
586            ) -> OSStatus;
587        }
588        unsafe {
589            VTCompressionSessionEncodeMultiImageFrameWithOutputHandler(
590                self,
591                tagged_buffer_group,
592                presentation_time_stamp,
593                duration,
594                frame_properties,
595                info_flags_out,
596                output_handler,
597            )
598        }
599    }
600}
601
602/// [Apple's documentation](https://developer.apple.com/documentation/videotoolbox/vtcompressionsessionoptionflags?language=objc)
603// NS_OPTIONS
604#[repr(transparent)]
605#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
606pub struct VTCompressionSessionOptionFlags(pub u32);
607bitflags::bitflags! {
608    impl VTCompressionSessionOptionFlags: u32 {
609        #[doc(alias = "kVTCompressionSessionBeginFinalPass")]
610        const BeginFinalPass = 1<<0;
611    }
612}
613
614#[cfg(feature = "objc2")]
615unsafe impl Encode for VTCompressionSessionOptionFlags {
616    const ENCODING: Encoding = u32::ENCODING;
617}
618
619#[cfg(feature = "objc2")]
620unsafe impl RefEncode for VTCompressionSessionOptionFlags {
621    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
622}
623
624impl VTCompressionSession {
625    /// Call to announce the start of a specific compression pass.
626    ///
627    /// During multi-pass encoding, this function must be called before VTCompressionSessionEncodeFrame.
628    /// It is an error to call this function when multi-pass encoding has not been enabled by setting kVTCompressionPropertyKey_MultiPassStorage.
629    ///
630    /// Parameter `beginPassFlags`: Pass kVTCompressionSessionBeginFinalPass to inform the encoder that the pass must be the final pass.
631    ///
632    /// # Safety
633    ///
634    /// `reserved` must be a valid pointer or null.
635    #[doc(alias = "VTCompressionSessionBeginPass")]
636    #[inline]
637    pub unsafe fn begin_pass(
638        &self,
639        begin_pass_flags: VTCompressionSessionOptionFlags,
640        reserved: *mut u32,
641    ) -> OSStatus {
642        extern "C-unwind" {
643            fn VTCompressionSessionBeginPass(
644                session: &VTCompressionSession,
645                begin_pass_flags: VTCompressionSessionOptionFlags,
646                reserved: *mut u32,
647            ) -> OSStatus;
648        }
649        unsafe { VTCompressionSessionBeginPass(self, begin_pass_flags, reserved) }
650    }
651
652    /// Call to announce the end of a pass.
653    ///
654    /// VTCompressionSessionEndPass can take a long time, since the video encoder may perform significant processing between passes.
655    /// VTCompressionSessionEndPass will indicate via the furtherPassesRequestedOut argument whether the video encoder would like to perform another pass.  There is no particular bound on the number of passes the video encoder may request, but the client is free to disregard this request and use the last-emitted set of frames.
656    /// It is an error to call this function when multi-pass encoding has not been enabled by setting kVTCompressionPropertyKey_MultiPassStorage.
657    ///
658    /// Parameter `furtherPassesRequestedOut`: Points to a Boolean that will be set to true if the video encoder would like to perform another pass, false otherwise.
659    /// You may pass NULL to indicate that the client is certain to use this as the final pass, in which case the video encoder can skip that evaluation step.
660    ///
661    /// # Safety
662    ///
663    /// - `further_passes_requested_out` must be a valid pointer or null.
664    /// - `reserved` must be a valid pointer or null.
665    #[doc(alias = "VTCompressionSessionEndPass")]
666    #[inline]
667    pub unsafe fn end_pass(
668        &self,
669        further_passes_requested_out: *mut Boolean,
670        reserved: *mut u32,
671    ) -> OSStatus {
672        extern "C-unwind" {
673            fn VTCompressionSessionEndPass(
674                session: &VTCompressionSession,
675                further_passes_requested_out: *mut Boolean,
676                reserved: *mut u32,
677            ) -> OSStatus;
678        }
679        unsafe { VTCompressionSessionEndPass(self, further_passes_requested_out, reserved) }
680    }
681
682    /// Retrieves the time ranges for the next pass.
683    ///
684    /// If VTCompressionSessionEndPass sets *furtherPassesRequestedOut to true, call VTCompressionSessionGetTimeRangesForNextPass to find out the time ranges for the next pass.  Source frames outside these time ranges should be skipped.
685    /// Each time range is considered to include any frame at its start time and not to include any frame at its end time.
686    /// It is an error to call this function when multi-pass encoding has not been enabled by setting kVTCompressionPropertyKey_MultiPassStorage, or when VTCompressionSessionEndPass did not set *furtherPassesRequestedOut to true.
687    ///
688    /// Parameter `timeRangeCountOut`: Points to a CMItemCount to receive the number of CMTimeRanges.
689    ///
690    /// Parameter `timeRangeArrayOut`: Points to a const CMTimeRange * to receive a pointer to a C array of CMTimeRanges.
691    /// The storage for this array belongs to the VTCompressionSession and should not be modified.
692    /// The pointer will be valid until the next call to VTCompressionSessionEndPass, or until the VTCompressionSession is invalidated or finalized.
693    ///
694    /// # Safety
695    ///
696    /// - `time_range_count_out` must be a valid pointer.
697    /// - `time_range_array_out` must be a valid pointer.
698    #[doc(alias = "VTCompressionSessionGetTimeRangesForNextPass")]
699    #[cfg(feature = "objc2-core-media")]
700    #[inline]
701    pub unsafe fn time_ranges_for_next_pass(
702        &self,
703        time_range_count_out: NonNull<CMItemCount>,
704        time_range_array_out: NonNull<*const CMTimeRange>,
705    ) -> OSStatus {
706        extern "C-unwind" {
707            fn VTCompressionSessionGetTimeRangesForNextPass(
708                session: &VTCompressionSession,
709                time_range_count_out: NonNull<CMItemCount>,
710                time_range_array_out: NonNull<*const CMTimeRange>,
711            ) -> OSStatus;
712        }
713        unsafe {
714            VTCompressionSessionGetTimeRangesForNextPass(
715                self,
716                time_range_count_out,
717                time_range_array_out,
718            )
719        }
720    }
721}
722
723extern "C-unwind" {
724    #[cfg(all(feature = "VTErrors", feature = "objc2-core-media"))]
725    #[deprecated = "renamed to `VTCompressionSession::create`"]
726    pub fn VTCompressionSessionCreate(
727        allocator: Option<&CFAllocator>,
728        width: i32,
729        height: i32,
730        codec_type: CMVideoCodecType,
731        encoder_specification: Option<&CFDictionary>,
732        source_image_buffer_attributes: Option<&CFDictionary>,
733        compressed_data_allocator: Option<&CFAllocator>,
734        output_callback: VTCompressionOutputCallback,
735        output_callback_ref_con: *mut c_void,
736        compression_session_out: NonNull<*mut VTCompressionSession>,
737    ) -> OSStatus;
738}
739
740extern "C-unwind" {
741    #[deprecated = "renamed to `VTCompressionSession::invalidate`"]
742    pub fn VTCompressionSessionInvalidate(session: &VTCompressionSession);
743}
744
745#[cfg(feature = "objc2-core-video")]
746#[deprecated = "renamed to `VTCompressionSession::pixel_buffer_pool`"]
747#[inline]
748pub unsafe extern "C-unwind" fn VTCompressionSessionGetPixelBufferPool(
749    session: &VTCompressionSession,
750) -> Option<CFRetained<CVPixelBufferPool>> {
751    extern "C-unwind" {
752        fn VTCompressionSessionGetPixelBufferPool(
753            session: &VTCompressionSession,
754        ) -> Option<NonNull<CVPixelBufferPool>>;
755    }
756    let ret = unsafe { VTCompressionSessionGetPixelBufferPool(session) };
757    ret.map(|ret| unsafe { CFRetained::retain(ret) })
758}
759
760extern "C-unwind" {
761    #[deprecated = "renamed to `VTCompressionSession::prepare_to_encode_frames`"]
762    pub fn VTCompressionSessionPrepareToEncodeFrames(session: &VTCompressionSession) -> OSStatus;
763}
764
765extern "C-unwind" {
766    #[cfg(all(
767        feature = "VTErrors",
768        feature = "objc2-core-media",
769        feature = "objc2-core-video"
770    ))]
771    #[deprecated = "renamed to `VTCompressionSession::encode_frame`"]
772    pub fn VTCompressionSessionEncodeFrame(
773        session: &VTCompressionSession,
774        image_buffer: &CVImageBuffer,
775        presentation_time_stamp: CMTime,
776        duration: CMTime,
777        frame_properties: Option<&CFDictionary>,
778        source_frame_refcon: *mut c_void,
779        info_flags_out: *mut VTEncodeInfoFlags,
780    ) -> OSStatus;
781}
782
783extern "C-unwind" {
784    #[cfg(all(
785        feature = "VTErrors",
786        feature = "block2",
787        feature = "objc2-core-media",
788        feature = "objc2-core-video"
789    ))]
790    #[deprecated = "renamed to `VTCompressionSession::encode_frame_with_output_handler`"]
791    pub fn VTCompressionSessionEncodeFrameWithOutputHandler(
792        session: &VTCompressionSession,
793        image_buffer: &CVImageBuffer,
794        presentation_time_stamp: CMTime,
795        duration: CMTime,
796        frame_properties: Option<&CFDictionary>,
797        info_flags_out: *mut VTEncodeInfoFlags,
798        output_handler: VTCompressionOutputHandler,
799    ) -> OSStatus;
800}
801
802extern "C-unwind" {
803    #[cfg(feature = "objc2-core-media")]
804    #[deprecated = "renamed to `VTCompressionSession::complete_frames`"]
805    pub fn VTCompressionSessionCompleteFrames(
806        session: &VTCompressionSession,
807        complete_until_presentation_time_stamp: CMTime,
808    ) -> OSStatus;
809}
810
811extern "C-unwind" {
812    #[cfg(all(feature = "VTErrors", feature = "objc2-core-media"))]
813    #[deprecated = "renamed to `VTCompressionSession::encode_multi_image_frame`"]
814    pub fn VTCompressionSessionEncodeMultiImageFrame(
815        session: &VTCompressionSession,
816        tagged_buffer_group: &CMTaggedBufferGroup,
817        presentation_time_stamp: CMTime,
818        duration: CMTime,
819        frame_properties: Option<&CFDictionary>,
820        source_frame_refcon: *mut c_void,
821        info_flags_out: *mut VTEncodeInfoFlags,
822    ) -> OSStatus;
823}
824
825extern "C-unwind" {
826    #[cfg(all(feature = "VTErrors", feature = "block2", feature = "objc2-core-media"))]
827    #[deprecated = "renamed to `VTCompressionSession::encode_multi_image_frame_with_output_handler`"]
828    pub fn VTCompressionSessionEncodeMultiImageFrameWithOutputHandler(
829        session: &VTCompressionSession,
830        tagged_buffer_group: &CMTaggedBufferGroup,
831        presentation_time_stamp: CMTime,
832        duration: CMTime,
833        frame_properties: Option<&CFDictionary>,
834        info_flags_out: *mut VTEncodeInfoFlags,
835        output_handler: VTCompressionOutputHandler,
836    ) -> OSStatus;
837}
838
839extern "C-unwind" {
840    #[deprecated = "renamed to `VTCompressionSession::begin_pass`"]
841    pub fn VTCompressionSessionBeginPass(
842        session: &VTCompressionSession,
843        begin_pass_flags: VTCompressionSessionOptionFlags,
844        reserved: *mut u32,
845    ) -> OSStatus;
846}
847
848extern "C-unwind" {
849    #[deprecated = "renamed to `VTCompressionSession::end_pass`"]
850    pub fn VTCompressionSessionEndPass(
851        session: &VTCompressionSession,
852        further_passes_requested_out: *mut Boolean,
853        reserved: *mut u32,
854    ) -> OSStatus;
855}
856
857extern "C-unwind" {
858    #[cfg(feature = "objc2-core-media")]
859    #[deprecated = "renamed to `VTCompressionSession::time_ranges_for_next_pass`"]
860    pub fn VTCompressionSessionGetTimeRangesForNextPass(
861        session: &VTCompressionSession,
862        time_range_count_out: NonNull<CMItemCount>,
863        time_range_array_out: NonNull<*const CMTimeRange>,
864    ) -> OSStatus;
865}