core_video/
pixel_buffer_io_surface.rs1use 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}