diff --git a/src/capturer/engine/mac/apple_sys.rs b/src/capturer/engine/mac/apple_sys.rs index 7ecf3b4..349f268 100644 --- a/src/capturer/engine/mac/apple_sys.rs +++ b/src/capturer/engine/mac/apple_sys.rs @@ -1,3 +1,5 @@ +#![allow(non_upper_case_globals)] + pub use screencapturekit_sys::os_types::base::*; #[repr(C)] diff --git a/src/capturer/engine/mac/mod.rs b/src/capturer/engine/mac/mod.rs index b76e4fa..41f0ba0 100644 --- a/src/capturer/engine/mac/mod.rs +++ b/src/capturer/engine/mac/mod.rs @@ -1,7 +1,6 @@ use std::cmp; use std::sync::mpsc; -use core_video_sys::{CVPixelBufferGetPixelFormatType, CVPixelBufferRef}; use pixelformat::get_pts_in_nanoseconds; use screencapturekit::{ cm_sample_buffer::CMSampleBuffer, @@ -13,20 +12,13 @@ use screencapturekit::{ sc_stream_configuration::{PixelFormat, SCStreamConfiguration}, sc_types::SCFrameStatus, }; +use screencapturekit_sys::os_types::base::{CMTime, CMTimeScale}; use screencapturekit_sys::os_types::geometry::{CGPoint, CGRect, CGSize}; -use screencapturekit_sys::{ - cm_sample_buffer_ref::CMSampleBufferGetImageBuffer, - os_types::base::{CMTime, CMTimeScale}, -}; use crate::frame::{Frame, FrameType}; use crate::targets::Target; use crate::{ - capturer::RawCapturer, - frame::{Frame, FrameType}, -}; -use crate::{ - capturer::{Area, Options, Point, RawCapturer, Resolution, Size}, + capturer::{Area, Options, Point, Resolution, Size}, frame::BGRAFrame, targets, }; @@ -46,12 +38,11 @@ impl StreamErrorHandler for ErrorHandler { pub struct Capturer { pub tx: mpsc::Sender, - pub output_type: FrameType, } impl Capturer { - pub fn new(tx: mpsc::Sender, output_type: FrameType) -> Self { - Capturer { tx, output_type } + pub fn new(tx: mpsc::Sender) -> Self { + Capturer { tx } } } @@ -99,14 +90,13 @@ pub fn create_capturer(options: &Options, tx: mpsc::Sender) -> SCSt .into_iter() .filter(|window| { excluded_targets - .into_iter() - .find(|excluded_target| match excluded_target { + .iter() + .any(|excluded_target| match excluded_target { Target::Window(excluded_window) => { excluded_window.id == window.window_id } _ => false, }) - .is_some() }) .collect(); @@ -156,10 +146,7 @@ pub fn create_capturer(options: &Options, tx: mpsc::Sender) -> SCSt }; let mut stream = SCStream::new(filter, stream_config, ErrorHandler); - stream.add_output( - Capturer::new(tx, options.output_type), - SCStreamOutputType::Screen, - ); + stream.add_output(Capturer::new(tx), SCStreamOutputType::Screen); stream } @@ -217,8 +204,8 @@ pub fn get_crop_area(options: &Options) -> Area { y: val.origin.y, }, size: Size { - width: input_width as f64, - height: input_height as f64, + width: input_width, + height: input_height, }, } }) @@ -236,49 +223,43 @@ pub fn process_sample_buffer( of_type: SCStreamOutputType, output_type: FrameType, ) -> Option { - match of_type { - SCStreamOutputType::Screen => { - let frame_status = &sample.frame_status; - - match frame_status { - SCFrameStatus::Complete | SCFrameStatus::Started => unsafe { - return Some(match output_type { - FrameType::YUVFrame => { - let yuvframe = pixelformat::create_yuv_frame(sample).unwrap(); - Frame::YUVFrame(yuvframe) - } - FrameType::RGB => { - let rgbframe = pixelformat::create_rgb_frame(sample).unwrap(); - Frame::RGB(rgbframe) - } - FrameType::BGR0 => { - let bgrframe = pixelformat::create_bgr_frame(sample).unwrap(); - Frame::BGR0(bgrframe) - } - FrameType::BGRAFrame => { - let bgraframe = pixelformat::create_bgra_frame(sample).unwrap(); - Frame::BGRA(bgraframe) - } - }); - }, - SCFrameStatus::Idle => { - // Quick hack - just send an empty frame, and the caller can figure out how to handle it - match output_type { - FrameType::BGRAFrame => { - return Some(Frame::BGRA(BGRAFrame { - display_time: get_pts_in_nanoseconds(&sample), - width: 0, - height: 0, - data: vec![], - })); - } - _ => {} + if let SCStreamOutputType::Screen = of_type { + let frame_status = &sample.frame_status; + + match frame_status { + SCFrameStatus::Complete | SCFrameStatus::Started => unsafe { + return Some(match output_type { + FrameType::YUVFrame => { + let yuvframe = pixelformat::create_yuv_frame(sample).unwrap(); + Frame::YUVFrame(yuvframe) } + FrameType::RGB => { + let rgbframe = pixelformat::create_rgb_frame(sample).unwrap(); + Frame::RGB(rgbframe) + } + FrameType::BGR0 => { + let bgrframe = pixelformat::create_bgr_frame(sample).unwrap(); + Frame::BGR0(bgrframe) + } + FrameType::BGRAFrame => { + let bgraframe = pixelformat::create_bgra_frame(sample).unwrap(); + Frame::BGRA(bgraframe) + } + }); + }, + SCFrameStatus::Idle => { + // Quick hack - just send an empty frame, and the caller can figure out how to handle it + if let FrameType::BGRAFrame = output_type { + return Some(Frame::BGRA(BGRAFrame { + display_time: get_pts_in_nanoseconds(&sample), + width: 0, + height: 0, + data: vec![], + })); } - _ => {} } + _ => {} } - _ => {} } None diff --git a/src/capturer/engine/mac/pixel_buffer.rs b/src/capturer/engine/mac/pixel_buffer.rs index 70bbae9..af6956f 100644 --- a/src/capturer/engine/mac/pixel_buffer.rs +++ b/src/capturer/engine/mac/pixel_buffer.rs @@ -170,9 +170,9 @@ impl RawCapturer<'_> { pub unsafe fn sample_buffer_to_pixel_buffer(sample_buffer: &CMSampleBuffer) -> CVPixelBufferRef { let buffer_ref = &(*sample_buffer.sys_ref); - let pixel_buffer = CMSampleBufferGetImageBuffer(buffer_ref) as CVPixelBufferRef; + - pixel_buffer + CMSampleBufferGetImageBuffer(buffer_ref) as CVPixelBufferRef } pub unsafe fn pixel_buffer_bounds(pixel_buffer: CVPixelBufferRef) -> (usize, usize) { diff --git a/src/capturer/engine/mac/pixelformat.rs b/src/capturer/engine/mac/pixelformat.rs index 7ce0705..949e4f5 100644 --- a/src/capturer/engine/mac/pixelformat.rs +++ b/src/capturer/engine/mac/pixelformat.rs @@ -1,9 +1,7 @@ use std::{mem, slice}; -use screencapturekit::{cm_sample_buffer::CMSampleBuffer, cv_pixel_buffer::CVPixelBuffer}; -use screencapturekit_sys::cm_sample_buffer_ref::{ - CMSampleBufferGetImageBuffer, CMSampleBufferGetSampleAttachmentsArray, -}; +use screencapturekit::cm_sample_buffer::CMSampleBuffer; +use screencapturekit_sys::cm_sample_buffer_ref::CMSampleBufferGetSampleAttachmentsArray; use super::{ apple_sys::*, @@ -61,7 +59,7 @@ pub unsafe fn create_yuv_frame(sample_buffer: CMSampleBuffer) -> Option) -> Engine { #[cfg(target_os = "macos")] { - let mac = mac::create_capturer(&options, tx); - return Engine { + let mac = mac::create_capturer(options, tx); + Engine { mac, options: (*options).clone(), - }; + } } #[cfg(target_os = "windows")] diff --git a/src/capturer/mod.rs b/src/capturer/mod.rs index 2ad23d3..9e3f9ab 100644 --- a/src/capturer/mod.rs +++ b/src/capturer/mod.rs @@ -1,6 +1,6 @@ mod engine; -use std::sync::mpsc; +use std::{error::Error, sync::mpsc}; use engine::ChannelItem; @@ -28,12 +28,12 @@ pub enum Resolution { impl Resolution { fn value(&self, aspect_ratio: f32) -> [u32; 2] { match *self { - Resolution::_480p => [640, ((640 as f32) / aspect_ratio).floor() as u32], - Resolution::_720p => [1280, ((1280 as f32) / aspect_ratio).floor() as u32], - Resolution::_1080p => [1920, ((1920 as f32) / aspect_ratio).floor() as u32], - Resolution::_1440p => [2560, ((2560 as f32) / aspect_ratio).floor() as u32], - Resolution::_2160p => [3840, ((3840 as f32) / aspect_ratio).floor() as u32], - Resolution::_4320p => [7680, ((7680 as f32) / aspect_ratio).floor() as u32], + Resolution::_480p => [640, (640_f32 / aspect_ratio).floor() as u32], + Resolution::_720p => [1280, (1280_f32 / aspect_ratio).floor() as u32], + Resolution::_1080p => [1920, (1920_f32 / aspect_ratio).floor() as u32], + Resolution::_1440p => [2560, (2560_f32 / aspect_ratio).floor() as u32], + Resolution::_2160p => [3840, (3840_f32 / aspect_ratio).floor() as u32], + Resolution::_4320p => [7680, (7680_f32 / aspect_ratio).floor() as u32], Resolution::Captured => { panic!(".value should not be called when Resolution type is Captured") } @@ -78,11 +78,25 @@ pub struct Capturer { rx: mpsc::Receiver, } +#[derive(Debug)] pub enum CapturerBuildError { NotSupported, PermissionNotGranted, } +impl std::fmt::Display for CapturerBuildError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + CapturerBuildError::NotSupported => write!(f, "Screen capturing is not supported"), + CapturerBuildError::PermissionNotGranted => { + write!(f, "Permission to capture the screen is not granted") + } + } + } +} + +impl Error for CapturerBuildError {} + impl Capturer { /// Create a new capturer instance with the provided options #[deprecated( diff --git a/src/frame/mod.rs b/src/frame/mod.rs index cd37e08..77797b7 100644 --- a/src/frame/mod.rs +++ b/src/frame/mod.rs @@ -101,7 +101,7 @@ pub fn remove_alpha_channel(frame_data: Vec) -> Vec { dst[2] = src[2]; } - return data; + data } pub fn convert_bgra_to_rgb(frame_data: Vec) -> Vec { @@ -116,24 +116,24 @@ pub fn convert_bgra_to_rgb(frame_data: Vec) -> Vec { dst[2] = src[0]; } - return data; + data } pub fn get_cropped_data(data: Vec, cur_width: i32, height: i32, width: i32) -> Vec { if data.len() as i32 != height * cur_width * 4 { - return data; + data } else { let mut cropped_data: Vec = vec![0; (4 * height * width).try_into().unwrap()]; let mut cropped_data_index = 0; - for i in 0..data.len() { + for (i, item) in data.iter().enumerate() { let x = i as i32 % (cur_width * 4); if x < (width * 4) { - cropped_data[cropped_data_index] = data[i]; + cropped_data[cropped_data_index] = *item; cropped_data_index += 1; } } - return cropped_data; + cropped_data } } diff --git a/src/utils/mac/mod.rs b/src/utils/mac/mod.rs index afb7f73..ae3adc4 100644 --- a/src/utils/mac/mod.rs +++ b/src/utils/mac/mod.rs @@ -2,11 +2,11 @@ use core_graphics_helmer_fork::access::ScreenCaptureAccess; use sysinfo::System; pub fn has_permission() -> bool { - ScreenCaptureAccess::default().preflight() + ScreenCaptureAccess.preflight() } pub fn request_permission() -> bool { - ScreenCaptureAccess::default().request() + ScreenCaptureAccess.request() } pub fn is_supported() -> bool {