1
1
use std:: cmp;
2
2
use std:: sync:: mpsc;
3
3
4
+ use pixelformat:: get_pts_in_nanoseconds;
4
5
use screencapturekit:: {
5
6
cm_sample_buffer:: CMSampleBuffer ,
6
7
sc_content_filter:: { InitParams , SCContentFilter } ,
@@ -16,13 +17,16 @@ use screencapturekit_sys::os_types::geometry::{CGPoint, CGRect, CGSize};
16
17
17
18
use crate :: frame:: { Frame , FrameType } ;
18
19
use crate :: targets:: Target ;
19
- use crate :: { capturer:: Resolution , targets} ;
20
20
use crate :: {
21
- capturer:: { Area , Options , Point , Size } ,
21
+ capturer:: { Area , Options , Point , Resolution , Size } ,
22
22
frame:: BGRAFrame ,
23
+ targets,
23
24
} ;
24
25
26
+ use super :: ChannelItem ;
27
+
25
28
mod apple_sys;
29
+ mod pixel_buffer;
26
30
mod pixelformat;
27
31
28
32
struct ErrorHandler ;
@@ -33,69 +37,22 @@ impl StreamErrorHandler for ErrorHandler {
33
37
}
34
38
35
39
pub struct Capturer {
36
- pub tx : mpsc:: Sender < Frame > ,
37
- pub output_type : FrameType ,
40
+ pub tx : mpsc:: Sender < ChannelItem > ,
38
41
}
39
42
40
43
impl Capturer {
41
- pub fn new ( tx : mpsc:: Sender < Frame > , output_type : FrameType ) -> Self {
42
- Capturer { tx, output_type }
44
+ pub fn new ( tx : mpsc:: Sender < ChannelItem > ) -> Self {
45
+ Capturer { tx }
43
46
}
44
47
}
45
48
46
49
impl StreamOutput for Capturer {
47
50
fn did_output_sample_buffer ( & self , sample : CMSampleBuffer , of_type : SCStreamOutputType ) {
48
- match of_type {
49
- SCStreamOutputType :: Screen => {
50
- let frame_status = & sample. frame_status ;
51
-
52
- match frame_status {
53
- SCFrameStatus :: Complete | SCFrameStatus :: Started => unsafe {
54
- let frame = match self . output_type {
55
- FrameType :: YUVFrame => {
56
- let yuvframe = pixelformat:: create_yuv_frame ( sample) . unwrap ( ) ;
57
- Frame :: YUVFrame ( yuvframe)
58
- }
59
- FrameType :: RGB => {
60
- let rgbframe = pixelformat:: create_rgb_frame ( sample) . unwrap ( ) ;
61
- Frame :: RGB ( rgbframe)
62
- }
63
- FrameType :: BGR0 => {
64
- let bgrframe = pixelformat:: create_bgr_frame ( sample) . unwrap ( ) ;
65
- Frame :: BGR0 ( bgrframe)
66
- }
67
- FrameType :: BGRAFrame => {
68
- let bgraframe = pixelformat:: create_bgra_frame ( sample) . unwrap ( ) ;
69
- Frame :: BGRA ( bgraframe)
70
- }
71
- } ;
72
- self . tx . send ( frame) . unwrap_or ( ( ) ) ;
73
- } ,
74
- SCFrameStatus :: Idle => {
75
- // Quick hack - just send an empty frame, and the caller can figure out how to handle it
76
- match self . output_type {
77
- FrameType :: BGRAFrame => {
78
- let display_time = pixelformat:: get_pts_in_nanoseconds ( & sample) ;
79
- let frame = BGRAFrame {
80
- display_time,
81
- width : 0 ,
82
- height : 0 ,
83
- data : vec ! [ ] ,
84
- } ;
85
- self . tx . send ( Frame :: BGRA ( frame) ) . unwrap_or ( ( ) ) ;
86
- }
87
- _ => { }
88
- }
89
- }
90
- _ => { }
91
- }
92
- }
93
- _ => { }
94
- }
51
+ self . tx . send ( ( sample, of_type) ) . unwrap_or ( ( ) ) ;
95
52
}
96
53
}
97
54
98
- pub fn create_capturer ( options : & Options , tx : mpsc:: Sender < Frame > ) -> SCStream {
55
+ pub fn create_capturer ( options : & Options , tx : mpsc:: Sender < ChannelItem > ) -> SCStream {
99
56
// If no target is specified, capture the main display
100
57
let target = options
101
58
. target
@@ -133,14 +90,13 @@ pub fn create_capturer(options: &Options, tx: mpsc::Sender<Frame>) -> SCStream {
133
90
. into_iter ( )
134
91
. filter ( |window| {
135
92
excluded_targets
136
- . into_iter ( )
137
- . find ( |excluded_target| match excluded_target {
93
+ . iter ( )
94
+ . any ( |excluded_target| match excluded_target {
138
95
Target :: Window ( excluded_window) => {
139
96
excluded_window. id == window. window_id
140
97
}
141
98
_ => false ,
142
99
} )
143
- . is_some ( )
144
100
} )
145
101
. collect ( ) ;
146
102
@@ -190,10 +146,7 @@ pub fn create_capturer(options: &Options, tx: mpsc::Sender<Frame>) -> SCStream {
190
146
} ;
191
147
192
148
let mut stream = SCStream :: new ( filter, stream_config, ErrorHandler ) ;
193
- stream. add_output (
194
- Capturer :: new ( tx, options. output_type ) ,
195
- SCStreamOutputType :: Screen ,
196
- ) ;
149
+ stream. add_output ( Capturer :: new ( tx) , SCStreamOutputType :: Screen ) ;
197
150
198
151
stream
199
152
}
@@ -251,8 +204,8 @@ pub fn get_crop_area(options: &Options) -> Area {
251
204
y : val. origin . y ,
252
205
} ,
253
206
size : Size {
254
- width : input_width as f64 ,
255
- height : input_height as f64 ,
207
+ width : input_width,
208
+ height : input_height,
256
209
} ,
257
210
}
258
211
} )
@@ -264,3 +217,50 @@ pub fn get_crop_area(options: &Options) -> Area {
264
217
} ,
265
218
} )
266
219
}
220
+
221
+ pub fn process_sample_buffer (
222
+ sample : CMSampleBuffer ,
223
+ of_type : SCStreamOutputType ,
224
+ output_type : FrameType ,
225
+ ) -> Option < Frame > {
226
+ if let SCStreamOutputType :: Screen = of_type {
227
+ let frame_status = & sample. frame_status ;
228
+
229
+ match frame_status {
230
+ SCFrameStatus :: Complete | SCFrameStatus :: Started => unsafe {
231
+ return Some ( match output_type {
232
+ FrameType :: YUVFrame => {
233
+ let yuvframe = pixelformat:: create_yuv_frame ( sample) . unwrap ( ) ;
234
+ Frame :: YUVFrame ( yuvframe)
235
+ }
236
+ FrameType :: RGB => {
237
+ let rgbframe = pixelformat:: create_rgb_frame ( sample) . unwrap ( ) ;
238
+ Frame :: RGB ( rgbframe)
239
+ }
240
+ FrameType :: BGR0 => {
241
+ let bgrframe = pixelformat:: create_bgr_frame ( sample) . unwrap ( ) ;
242
+ Frame :: BGR0 ( bgrframe)
243
+ }
244
+ FrameType :: BGRAFrame => {
245
+ let bgraframe = pixelformat:: create_bgra_frame ( sample) . unwrap ( ) ;
246
+ Frame :: BGRA ( bgraframe)
247
+ }
248
+ } ) ;
249
+ } ,
250
+ SCFrameStatus :: Idle => {
251
+ // Quick hack - just send an empty frame, and the caller can figure out how to handle it
252
+ if let FrameType :: BGRAFrame = output_type {
253
+ return Some ( Frame :: BGRA ( BGRAFrame {
254
+ display_time : get_pts_in_nanoseconds ( & sample) ,
255
+ width : 0 ,
256
+ height : 0 ,
257
+ data : vec ! [ ] ,
258
+ } ) ) ;
259
+ }
260
+ }
261
+ _ => { }
262
+ }
263
+ }
264
+
265
+ None
266
+ }
0 commit comments