webrtc_sys/
desktop_capturer.rs1use cxx::UniquePtr;
16use ffi::CaptureResult;
17
18use crate::{desktop_capturer::ffi::DesktopFrame, impl_thread_safety};
19
20#[cxx::bridge(namespace = "livekit_ffi")]
21pub mod ffi {
22 #[derive(Clone)]
23 struct Source {
24 id: u64,
25 title: String,
26 display_id: i64,
27 }
28
29 #[derive(Debug, PartialEq)]
30 enum SourceType {
31 Screen,
32 Window,
33 Generic,
34 }
35
36 #[derive(Clone, Debug)]
37 struct DesktopCapturerOptions {
38 source_type: SourceType,
39 include_cursor: bool,
40 allow_sck_system_picker: bool,
41 }
42
43 enum CaptureResult {
44 Success,
45 ErrorTemporary,
46 ErrorPermanent,
47 }
48
49 unsafe extern "C++" {
50 include!("livekit/desktop_capturer.h");
51
52 type DesktopCapturer;
53 type DesktopFrame;
54
55 fn new_desktop_capturer(options: DesktopCapturerOptions) -> UniquePtr<DesktopCapturer>;
56 fn capture_frame(self: &DesktopCapturer);
57 fn get_source_list(self: &DesktopCapturer) -> Vec<Source>;
58 fn select_source(self: &DesktopCapturer, id: u64) -> bool;
59 fn start(self: Pin<&mut DesktopCapturer>, callback: Box<DesktopCapturerCallbackWrapper>);
60
61 fn width(self: &DesktopFrame) -> i32;
62 fn height(self: &DesktopFrame) -> i32;
63 fn stride(self: &DesktopFrame) -> i32;
64 fn left(self: &DesktopFrame) -> i32;
65 fn top(self: &DesktopFrame) -> i32;
66 fn data(self: &DesktopFrame) -> *const u8;
67 }
68
69 extern "Rust" {
70 type DesktopCapturerCallbackWrapper;
71
72 fn on_capture_result(
73 self: &mut DesktopCapturerCallbackWrapper,
74 result: CaptureResult,
75 frame: UniquePtr<DesktopFrame>,
76 );
77 }
78}
79
80impl_thread_safety!(ffi::DesktopCapturer, Send + Sync);
81
82#[derive(Debug, PartialEq)]
83pub enum CaptureError {
84 Temporary,
85 Permanent,
86}
87
88pub trait DesktopCapturerCallback: Send {
89 fn on_capture_result(&mut self, result: Result<UniquePtr<DesktopFrame>, CaptureError>);
90}
91
92pub struct DesktopCapturerCallbackWrapper {
93 callback: Box<dyn DesktopCapturerCallback>,
94}
95
96impl DesktopCapturerCallbackWrapper {
97 pub fn new(callback: Box<dyn DesktopCapturerCallback>) -> Self {
98 Self { callback }
99 }
100
101 fn on_capture_result(&mut self, result: CaptureResult, frame: UniquePtr<DesktopFrame>) {
102 match result {
103 CaptureResult::Success => self.callback.on_capture_result(Ok(frame)),
104 CaptureResult::ErrorTemporary => {
105 self.callback.on_capture_result(Err(CaptureError::Temporary))
106 }
107 CaptureResult::ErrorPermanent => {
108 self.callback.on_capture_result(Err(CaptureError::Permanent))
109 }
110 _ => self.callback.on_capture_result(Err(CaptureError::Permanent)),
111 }
112 }
113}