-
Notifications
You must be signed in to change notification settings - Fork 46
Expand file tree
/
Copy path06_iosurface.rs
More file actions
95 lines (79 loc) · 3.28 KB
/
Copy path06_iosurface.rs
File metadata and controls
95 lines (79 loc) · 3.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
//! `IOSurface` Access
//!
//! Demonstrates zero-copy GPU buffer access via `IOSurface`.
//! This example shows:
//! - Checking if buffer is `IOSurface`-backed
//! - Accessing `IOSurface` properties
//! - Locking and reading `IOSurface` data
use screencapturekit::cm::CMSampleBufferExt;
use screencapturekit::cm::IOSurfaceLockOptions;
use screencapturekit::cv::PixelBufferCursorExt;
use screencapturekit::prelude::*;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
struct Handler {
count: Arc<AtomicUsize>,
}
impl SCStreamOutputTrait for Handler {
fn did_output_sample_buffer(&self, sample: CMSampleBuffer, output_type: SCStreamOutputType) {
if matches!(output_type, SCStreamOutputType::Screen) {
let n = self.count.fetch_add(1, Ordering::Relaxed);
if n % 60 == 0 {
if let Some(pixel_buffer) = sample.image_buffer() {
// Check if IOSurface-backed
if pixel_buffer.is_backed_by_io_surface() {
if let Some(iosurface) = pixel_buffer.io_surface() {
println!("\n📹 Frame {n} - IOSurface");
println!(
" Dimensions: {}x{}",
iosurface.width(),
iosurface.height()
);
println!(" Pixel format: 0x{:08X}", iosurface.pixel_format());
println!(" Bytes per row: {}", iosurface.bytes_per_row());
println!(" In use: {}", iosurface.is_in_use());
// Lock and access data
if let Ok(guard) = iosurface.lock(IOSurfaceLockOptions::READ_ONLY) {
let mut cursor = guard.cursor();
// Read first pixel
if let Ok(pixel) = cursor.read_pixel() {
println!(" First pixel: {pixel:?}");
}
println!(" ✅ IOSurface access successful");
}
}
} else {
println!("⚠️ Frame {n} - Not IOSurface-backed");
}
}
}
}
}
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("🎨 IOSurface Access\n");
let content = SCShareableContent::get()?;
let display = content
.displays()
.into_iter()
.next()
.ok_or("No displays found")?;
let filter = SCContentFilter::create()
.with_display(&display)
.with_excluding_windows(&[])
.build();
let config = SCStreamConfiguration::new()
.with_width(1920)
.with_height(1080)
.with_pixel_format(PixelFormat::BGRA);
let count = Arc::new(AtomicUsize::new(0));
let handler = Handler { count };
let mut stream = SCStream::new(&filter, &config);
stream.add_output_handler(handler, SCStreamOutputType::Screen);
println!("Starting capture...\n");
stream.start_capture()?;
std::thread::sleep(std::time::Duration::from_secs(5));
stream.stop_capture()?;
println!("\n✅ Done");
Ok(())
}