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