diff --git a/crates/capture/build.rs b/crates/capture/build.rs index 482e6487ce..7adb758dde 100644 --- a/crates/capture/build.rs +++ b/crates/capture/build.rs @@ -1,9 +1,7 @@ use std::{env, path::PathBuf, process::Command}; fn main() { - println!("cargo:rustc-link-lib=framework=CoreMedia"); println!("cargo:rustc-link-lib=framework=ScreenCaptureKit"); - println!("cargo:rustc-link-lib=framework=System"); println!("cargo:rustc-env=MACOSX_DEPLOYMENT_TARGET=12.3"); let sdk_path = String::from_utf8( @@ -21,7 +19,6 @@ fn main() { .header("src/bindings.h") .clang_arg(format!("-isysroot{}", sdk_path)) .clang_arg("-xobjective-c") - .allowlist_function("CMTimeMake") .allowlist_function("dispatch_queue_create") .allowlist_type("SCStreamOutputType") .allowlist_type("SCFrameStatus") diff --git a/crates/capture/src/bindings.h b/crates/capture/src/bindings.h index 45ac30446b..5e3c525891 100644 --- a/crates/capture/src/bindings.h +++ b/crates/capture/src/bindings.h @@ -1,3 +1,2 @@ -#import #import #import diff --git a/crates/capture/src/main.rs b/crates/capture/src/main.rs index 36efe369f9..0a05471f4f 100644 --- a/crates/capture/src/main.rs +++ b/crates/capture/src/main.rs @@ -7,7 +7,6 @@ use cocoa::{ foundation::{NSArray, NSString, NSUInteger}, }; use core_foundation::{base::TCFType, number::CFNumberRef, string::CFStringRef}; -use core_media::{CMSampleBuffer, CMSampleBufferRef}; use futures::StreamExt; use gpui::{ actions, @@ -17,7 +16,10 @@ use gpui::{ Menu, MenuItem, ViewContext, }; use log::LevelFilter; -use media::core_video::{self, CVImageBuffer}; +use media::{ + core_media::{CMSampleBuffer, CMSampleBufferRef, CMTimeMake}, + core_video::{self, CVImageBuffer}, +}; use objc::{ class, declare::ClassDecl, @@ -125,7 +127,7 @@ impl ScreenCaptureView { let config: id = msg_send![config, init]; let _: () = msg_send![config, setWidth: display_width * 2]; let _: () = msg_send![config, setHeight: display_height * 2]; - let _: () = msg_send![config, setMinimumFrameInterval: bindings::CMTimeMake(1, 60)]; + let _: () = msg_send![config, setMinimumFrameInterval: CMTimeMake(1, 60)]; let _: () = msg_send![config, setQueueDepth: 6]; let _: () = msg_send![config, setShowsCursor: YES]; let _: () = msg_send![ @@ -238,59 +240,3 @@ extern "C" fn sample_output( fn quit(_: &Quit, cx: &mut gpui::MutableAppContext) { cx.platform().quit(); } - -mod core_media { - #![allow(non_snake_case)] - - use crate::core_video::{CVImageBuffer, CVImageBufferRef}; - use core_foundation::{ - array::{CFArray, CFArrayRef}, - base::{CFTypeID, TCFType}, - declare_TCFType, - dictionary::CFDictionary, - impl_CFTypeDescription, impl_TCFType, - string::CFString, - }; - use std::ffi::c_void; - - #[repr(C)] - pub struct __CMSampleBuffer(c_void); - // The ref type must be a pointer to the underlying struct. - pub type CMSampleBufferRef = *const __CMSampleBuffer; - - declare_TCFType!(CMSampleBuffer, CMSampleBufferRef); - impl_TCFType!(CMSampleBuffer, CMSampleBufferRef, CMSampleBufferGetTypeID); - impl_CFTypeDescription!(CMSampleBuffer); - - impl CMSampleBuffer { - pub fn attachments(&self) -> Vec> { - unsafe { - let attachments = - CMSampleBufferGetSampleAttachmentsArray(self.as_concrete_TypeRef(), true); - CFArray::::wrap_under_get_rule(attachments) - .into_iter() - .map(|attachments| { - CFDictionary::wrap_under_get_rule(attachments.as_concrete_TypeRef()) - }) - .collect() - } - } - - pub fn image_buffer(&self) -> CVImageBuffer { - unsafe { - CVImageBuffer::wrap_under_get_rule(CMSampleBufferGetImageBuffer( - self.as_concrete_TypeRef(), - )) - } - } - } - - extern "C" { - fn CMSampleBufferGetTypeID() -> CFTypeID; - fn CMSampleBufferGetSampleAttachmentsArray( - buffer: CMSampleBufferRef, - create_if_necessary: bool, - ) -> CFArrayRef; - fn CMSampleBufferGetImageBuffer(buffer: CMSampleBufferRef) -> CVImageBufferRef; - } -} diff --git a/crates/media/build.rs b/crates/media/build.rs index 50834ebe7f..0e610113d2 100644 --- a/crates/media/build.rs +++ b/crates/media/build.rs @@ -16,6 +16,7 @@ fn main() { .header("src/bindings.h") .clang_arg(format!("-isysroot{}", sdk_path)) .clang_arg("-xobjective-c") + .allowlist_function("CMTimeMake") .allowlist_var("kCVPixelFormatType_.*") .allowlist_var("kCVReturn.*") .parse_callbacks(Box::new(bindgen::CargoCallbacks)) diff --git a/crates/media/src/bindings.h b/crates/media/src/bindings.h index 4e19d2701d..3a4689f708 100644 --- a/crates/media/src/bindings.h +++ b/crates/media/src/bindings.h @@ -1,2 +1,3 @@ +#import #import #import diff --git a/crates/media/src/media.rs b/crates/media/src/media.rs index 42a6eabac7..86ba8d393e 100644 --- a/crates/media/src/media.rs +++ b/crates/media/src/media.rs @@ -31,7 +31,8 @@ pub mod core_video { #![allow(non_snake_case)] use super::*; - pub use crate::bindings::*; + pub use crate::bindings::kCVPixelFormatType_32BGRA; + use crate::bindings::{kCVReturnSuccess, CVReturn, OSType}; use anyhow::{anyhow, Result}; use core_foundation::{ base::kCFAllocatorDefault, dictionary::CFDictionaryRef, mach_port::CFAllocatorRef, @@ -189,3 +190,61 @@ pub mod core_video { fn CVMetalTextureGetTexture(texture: CVMetalTextureRef) -> *mut c_void; } } + +pub mod core_media { + #![allow(non_snake_case)] + + pub use crate::bindings::CMTimeMake; + use crate::core_video::{CVImageBuffer, CVImageBufferRef}; + use core_foundation::{ + array::{CFArray, CFArrayRef}, + base::{CFTypeID, TCFType}, + declare_TCFType, + dictionary::CFDictionary, + impl_CFTypeDescription, impl_TCFType, + string::CFString, + }; + use std::ffi::c_void; + + #[repr(C)] + pub struct __CMSampleBuffer(c_void); + // The ref type must be a pointer to the underlying struct. + pub type CMSampleBufferRef = *const __CMSampleBuffer; + + declare_TCFType!(CMSampleBuffer, CMSampleBufferRef); + impl_TCFType!(CMSampleBuffer, CMSampleBufferRef, CMSampleBufferGetTypeID); + impl_CFTypeDescription!(CMSampleBuffer); + + impl CMSampleBuffer { + pub fn attachments(&self) -> Vec> { + unsafe { + let attachments = + CMSampleBufferGetSampleAttachmentsArray(self.as_concrete_TypeRef(), true); + CFArray::::wrap_under_get_rule(attachments) + .into_iter() + .map(|attachments| { + CFDictionary::wrap_under_get_rule(attachments.as_concrete_TypeRef()) + }) + .collect() + } + } + + pub fn image_buffer(&self) -> CVImageBuffer { + unsafe { + CVImageBuffer::wrap_under_get_rule(CMSampleBufferGetImageBuffer( + self.as_concrete_TypeRef(), + )) + } + } + } + + #[link(name = "CoreMedia", kind = "framework")] + extern "C" { + fn CMSampleBufferGetTypeID() -> CFTypeID; + fn CMSampleBufferGetSampleAttachmentsArray( + buffer: CMSampleBufferRef, + create_if_necessary: bool, + ) -> CFArrayRef; + fn CMSampleBufferGetImageBuffer(buffer: CMSampleBufferRef) -> CVImageBufferRef; + } +}