mirror of
https://github.com/weyne85/rustdesk.git
synced 2025-10-29 17:00:05 +00:00
source code
This commit is contained in:
125
libs/scrap/src/common/quartz.rs
Normal file
125
libs/scrap/src/common/quartz.rs
Normal file
@@ -0,0 +1,125 @@
|
||||
use crate::quartz;
|
||||
use std::marker::PhantomData;
|
||||
use std::sync::{Arc, Mutex, TryLockError};
|
||||
use std::{io, mem, ops};
|
||||
|
||||
pub struct Capturer {
|
||||
inner: quartz::Capturer,
|
||||
frame: Arc<Mutex<Option<quartz::Frame>>>,
|
||||
use_yuv: bool,
|
||||
i420: Vec<u8>,
|
||||
}
|
||||
|
||||
impl Capturer {
|
||||
pub fn new(display: Display, use_yuv: bool) -> io::Result<Capturer> {
|
||||
let frame = Arc::new(Mutex::new(None));
|
||||
|
||||
let f = frame.clone();
|
||||
let inner = quartz::Capturer::new(
|
||||
display.0,
|
||||
display.width(),
|
||||
display.height(),
|
||||
if use_yuv {
|
||||
quartz::PixelFormat::YCbCr420Full
|
||||
} else {
|
||||
quartz::PixelFormat::Argb8888
|
||||
},
|
||||
Default::default(),
|
||||
move |inner| {
|
||||
if let Ok(mut f) = f.lock() {
|
||||
*f = Some(inner);
|
||||
}
|
||||
},
|
||||
)
|
||||
.map_err(|_| io::Error::from(io::ErrorKind::Other))?;
|
||||
|
||||
Ok(Capturer {
|
||||
inner,
|
||||
frame,
|
||||
use_yuv,
|
||||
i420: Vec::new(),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn width(&self) -> usize {
|
||||
self.inner.width()
|
||||
}
|
||||
|
||||
pub fn height(&self) -> usize {
|
||||
self.inner.height()
|
||||
}
|
||||
|
||||
pub fn frame<'a>(&'a mut self, _timeout_ms: u32) -> io::Result<Frame<'a>> {
|
||||
match self.frame.try_lock() {
|
||||
Ok(mut handle) => {
|
||||
let mut frame = None;
|
||||
mem::swap(&mut frame, &mut handle);
|
||||
|
||||
match frame {
|
||||
Some(mut frame) => {
|
||||
if self.use_yuv {
|
||||
frame.nv12_to_i420(self.width(), self.height(), &mut self.i420);
|
||||
}
|
||||
Ok(Frame(frame, PhantomData))
|
||||
}
|
||||
|
||||
None => Err(io::ErrorKind::WouldBlock.into()),
|
||||
}
|
||||
}
|
||||
|
||||
Err(TryLockError::WouldBlock) => Err(io::ErrorKind::WouldBlock.into()),
|
||||
|
||||
Err(TryLockError::Poisoned(..)) => Err(io::ErrorKind::Other.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Frame<'a>(quartz::Frame, PhantomData<&'a [u8]>);
|
||||
|
||||
impl<'a> ops::Deref for Frame<'a> {
|
||||
type Target = [u8];
|
||||
fn deref(&self) -> &[u8] {
|
||||
&*self.0
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Display(quartz::Display);
|
||||
|
||||
impl Display {
|
||||
pub fn primary() -> io::Result<Display> {
|
||||
Ok(Display(quartz::Display::primary()))
|
||||
}
|
||||
|
||||
pub fn all() -> io::Result<Vec<Display>> {
|
||||
Ok(quartz::Display::online()
|
||||
.map_err(|_| io::Error::from(io::ErrorKind::Other))?
|
||||
.into_iter()
|
||||
.map(Display)
|
||||
.collect())
|
||||
}
|
||||
|
||||
pub fn width(&self) -> usize {
|
||||
self.0.width()
|
||||
}
|
||||
|
||||
pub fn height(&self) -> usize {
|
||||
self.0.height()
|
||||
}
|
||||
|
||||
pub fn name(&self) -> String {
|
||||
self.0.id().to_string()
|
||||
}
|
||||
|
||||
pub fn is_online(&self) -> bool {
|
||||
self.0.is_online()
|
||||
}
|
||||
|
||||
pub fn origin(&self) -> (usize, usize) {
|
||||
let o = self.0.bounds().origin;
|
||||
(o.x as usize, o.y as usize)
|
||||
}
|
||||
|
||||
pub fn is_primary(&self) -> bool {
|
||||
self.0.is_primary()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user