core_video/
pixel_buffer_io_surface.rs

1use std::ptr::{null, null_mut};
2
3use core_foundation::{
4    base::{kCFAllocatorDefault, CFAllocatorRef, CFType, TCFType},
5    dictionary::{CFDictionary, CFDictionaryRef},
6    string::{CFString, CFStringRef},
7};
8use io_surface::IOSurface;
9
10use crate::{
11    io_surface::IOSurfaceRef,
12    pixel_buffer::{CVPixelBuffer, CVPixelBufferRef},
13    r#return::{kCVReturnSuccess, CVReturn},
14};
15
16extern "C" {
17    pub static kCVPixelBufferIOSurfaceOpenGLTextureCompatibilityKey: CFStringRef;
18    pub static kCVPixelBufferIOSurfaceOpenGLFBOCompatibilityKey: CFStringRef;
19    pub static kCVPixelBufferIOSurfaceCoreAnimationCompatibilityKey: CFStringRef;
20    pub static kCVPixelBufferIOSurfaceOpenGLESTextureCompatibilityKey: CFStringRef;
21    pub static kCVPixelBufferIOSurfaceOpenGLESFBOCompatibilityKey: CFStringRef;
22
23    pub fn CVPixelBufferGetIOSurface(pixelBuffer: CVPixelBufferRef) -> IOSurfaceRef;
24    pub fn CVPixelBufferCreateWithIOSurface(
25        allocator: CFAllocatorRef,
26        surface: IOSurfaceRef,
27        pixelBufferAttributes: CFDictionaryRef,
28        pixelBufferOut: *mut CVPixelBufferRef,
29    ) -> CVReturn;
30}
31
32pub enum CVPixelBufferIOSurfaceKeys {
33    OpenGLTextureCompatibility,
34    OpenGLFBOCompatibility,
35    CoreAnimationCompatibility,
36    OpenGLESTextureCompatibility,
37    OpenGLESFBOCompatibility,
38}
39
40impl From<CVPixelBufferIOSurfaceKeys> for CFStringRef {
41    fn from(key: CVPixelBufferIOSurfaceKeys) -> Self {
42        unsafe {
43            match key {
44                CVPixelBufferIOSurfaceKeys::OpenGLTextureCompatibility => kCVPixelBufferIOSurfaceOpenGLTextureCompatibilityKey,
45                CVPixelBufferIOSurfaceKeys::OpenGLFBOCompatibility => kCVPixelBufferIOSurfaceOpenGLFBOCompatibilityKey,
46                CVPixelBufferIOSurfaceKeys::CoreAnimationCompatibility => kCVPixelBufferIOSurfaceCoreAnimationCompatibilityKey,
47                CVPixelBufferIOSurfaceKeys::OpenGLESTextureCompatibility => kCVPixelBufferIOSurfaceOpenGLESTextureCompatibilityKey,
48                CVPixelBufferIOSurfaceKeys::OpenGLESFBOCompatibility => kCVPixelBufferIOSurfaceOpenGLESFBOCompatibilityKey,
49            }
50        }
51    }
52}
53
54impl From<CVPixelBufferIOSurfaceKeys> for CFString {
55    fn from(key: CVPixelBufferIOSurfaceKeys) -> Self {
56        unsafe { CFString::wrap_under_get_rule(CFStringRef::from(key)) }
57    }
58}
59
60impl CVPixelBuffer {
61    #[inline]
62    pub fn from_io_surface(io_surface: &IOSurface, options: Option<&CFDictionary<CFString, CFType>>) -> Result<CVPixelBuffer, CVReturn> {
63        let mut pixel_buffer: CVPixelBufferRef = null_mut();
64        let status = unsafe {
65            CVPixelBufferCreateWithIOSurface(
66                kCFAllocatorDefault,
67                io_surface.as_concrete_TypeRef(),
68                options.map_or(null(), |options| options.as_concrete_TypeRef()),
69                &mut pixel_buffer,
70            )
71        };
72        if status == kCVReturnSuccess {
73            Ok(unsafe { TCFType::wrap_under_create_rule(pixel_buffer) })
74        } else {
75            Err(status)
76        }
77    }
78
79    #[inline]
80    pub fn get_io_surface(&self) -> Option<IOSurface> {
81        unsafe {
82            let surface = CVPixelBufferGetIOSurface(self.as_concrete_TypeRef());
83            if surface.is_null() {
84                None
85            } else {
86                Some(TCFType::wrap_under_create_rule(surface))
87            }
88        }
89    }
90}