diff --git a/Cargo.lock b/Cargo.lock
index c91272112..be6c13915 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -378,9 +378,12 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "bytes"
-version = "1.1.0"
+version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
+checksum = "f0b3de4a0c5e67e16066a0715723abd91edc2f9001d09c46e1dca929351e130e"
+dependencies = [
+ "serde 1.0.139",
+]
[[package]]
name = "cache-padded"
@@ -3964,6 +3967,7 @@ dependencies = [
"async-process",
"async-trait",
"base64",
+ "bytes",
"cc",
"cfg-if 1.0.0",
"clap 3.2.12",
diff --git a/libs/scrap/examples/capture_mag.rs b/libs/scrap/examples/capture_mag.rs
index c0505141e..81b2d8573 100644
--- a/libs/scrap/examples/capture_mag.rs
+++ b/libs/scrap/examples/capture_mag.rs
@@ -4,7 +4,7 @@ extern crate scrap;
use std::fs::File;
#[cfg(windows)]
-use scrap::CapturerMag;
+use scrap::{CapturerMag, TraitCapturer};
use scrap::{i420_to_rgb, Display};
fn main() {
diff --git a/libs/scrap/examples/ffplay.rs b/libs/scrap/examples/ffplay.rs
index 2c685b931..b8fe16e35 100644
--- a/libs/scrap/examples/ffplay.rs
+++ b/libs/scrap/examples/ffplay.rs
@@ -3,7 +3,7 @@ use std::time::Duration;
extern crate scrap;
fn main() {
- use scrap::{Capturer, Display};
+ use scrap::{Capturer, Display, TraitCapturer};
use std::io::ErrorKind::WouldBlock;
use std::io::Write;
use std::process::{Command, Stdio};
diff --git a/libs/scrap/examples/record-screen.rs b/libs/scrap/examples/record-screen.rs
index e099a8d1e..5df97838e 100644
--- a/libs/scrap/examples/record-screen.rs
+++ b/libs/scrap/examples/record-screen.rs
@@ -18,7 +18,7 @@ use webm::mux;
use webm::mux::Track;
use scrap::vpxcodec as vpx_encode;
-use scrap::{Capturer, Display, STRIDE_ALIGN};
+use scrap::{TraitCapturer, Capturer, Display, STRIDE_ALIGN};
const USAGE: &'static str = "
Simple WebM screen capture.
diff --git a/libs/scrap/examples/screenshot.rs b/libs/scrap/examples/screenshot.rs
index b6bf8a1d9..636768eb8 100644
--- a/libs/scrap/examples/screenshot.rs
+++ b/libs/scrap/examples/screenshot.rs
@@ -6,7 +6,7 @@ use std::io::ErrorKind::WouldBlock;
use std::thread;
use std::time::Duration;
-use scrap::{i420_to_rgb, Capturer, Display};
+use scrap::{i420_to_rgb, Capturer, Display, TraitCapturer};
fn main() {
let n = Display::all().unwrap().len();
diff --git a/libs/scrap/src/common/android.rs b/libs/scrap/src/common/android.rs
index 8322da3cd..e15752d8e 100644
--- a/libs/scrap/src/common/android.rs
+++ b/libs/scrap/src/common/android.rs
@@ -32,8 +32,12 @@ impl Capturer {
pub fn height(&self) -> usize {
self.display.height() as usize
}
+}
- pub fn frame<'a>(&'a mut self, _timeout: Duration) -> io::Result> {
+impl TraitCapturer for Capturer {
+ fn set_use_yuv(&mut self, _use_yuv: bool) {}
+
+ fn frame<'a>(&'a mut self, _timeout: Duration) -> io::Result> {
if let Some(buf) = get_video_raw() {
crate::would_block_if_equal(&mut self.saved_raw_data, buf)?;
rgba_to_i420(self.width(), self.height(), buf, &mut self.bgra);
diff --git a/libs/scrap/src/common/dxgi.rs b/libs/scrap/src/common/dxgi.rs
index 855ac7ac3..963f39de1 100644
--- a/libs/scrap/src/common/dxgi.rs
+++ b/libs/scrap/src/common/dxgi.rs
@@ -1,7 +1,12 @@
-use crate::dxgi;
-use std::io::ErrorKind::{NotFound, TimedOut, WouldBlock};
-use std::time::Duration;
-use std::{io, ops};
+use crate::{common::TraitCapturer, dxgi};
+use std::{
+ io::{
+ self,
+ ErrorKind::{NotFound, TimedOut, WouldBlock},
+ },
+ ops,
+ time::Duration,
+};
pub struct Capturer {
inner: dxgi::Capturer,
@@ -21,18 +26,6 @@ impl Capturer {
})
}
- pub fn set_use_yuv(&mut self, use_yuv: bool) {
- self.inner.set_use_yuv(use_yuv);
- }
-
- pub fn is_gdi(&self) -> bool {
- self.inner.is_gdi()
- }
-
- pub fn set_gdi(&mut self) -> bool {
- self.inner.set_gdi()
- }
-
pub fn cancel_gdi(&mut self) {
self.inner.cancel_gdi()
}
@@ -44,14 +37,28 @@ impl Capturer {
pub fn height(&self) -> usize {
self.height
}
+}
- pub fn frame<'a>(&'a mut self, timeout: Duration) -> io::Result> {
+impl TraitCapturer for Capturer {
+ fn set_use_yuv(&mut self, use_yuv: bool) {
+ self.inner.set_use_yuv(use_yuv);
+ }
+
+ fn frame<'a>(&'a mut self, timeout: Duration) -> io::Result> {
match self.inner.frame(timeout.as_millis() as _) {
Ok(frame) => Ok(Frame(frame)),
Err(ref error) if error.kind() == TimedOut => Err(WouldBlock.into()),
Err(error) => Err(error),
}
}
+
+ fn is_gdi(&self) -> bool {
+ self.inner.is_gdi()
+ }
+
+ fn set_gdi(&mut self) -> bool {
+ self.inner.set_gdi()
+ }
}
pub struct Frame<'a>(&'a [u8]);
@@ -134,10 +141,6 @@ impl CapturerMag {
})
}
- pub fn set_use_yuv(&mut self, use_yuv: bool) {
- self.inner.set_use_yuv(use_yuv)
- }
-
pub fn exclude(&mut self, cls: &str, name: &str) -> io::Result {
self.inner.exclude(cls, name)
}
@@ -145,8 +148,23 @@ impl CapturerMag {
pub fn get_rect(&self) -> ((i32, i32), usize, usize) {
self.inner.get_rect()
}
- pub fn frame<'a>(&'a mut self, _timeout_ms: Duration) -> io::Result> {
+}
+
+impl TraitCapturer for CapturerMag {
+ fn set_use_yuv(&mut self, use_yuv: bool) {
+ self.inner.set_use_yuv(use_yuv)
+ }
+
+ fn frame<'a>(&'a mut self, _timeout_ms: Duration) -> io::Result> {
self.inner.frame(&mut self.data)?;
Ok(Frame(&self.data))
}
+
+ fn is_gdi(&self) -> bool {
+ false
+ }
+
+ fn set_gdi(&mut self) -> bool {
+ false
+ }
}
diff --git a/libs/scrap/src/common/linux.rs b/libs/scrap/src/common/linux.rs
index 8498ab7ff..866fb851a 100644
--- a/libs/scrap/src/common/linux.rs
+++ b/libs/scrap/src/common/linux.rs
@@ -1,6 +1,7 @@
use crate::common::{
wayland,
x11::{self, Frame},
+ TraitCapturer,
};
use std::{io, time::Duration};
@@ -17,13 +18,6 @@ impl Capturer {
})
}
- pub fn set_use_yuv(&mut self, use_yuv: bool) {
- match self {
- Capturer::X11(d) => d.set_use_yuv(use_yuv),
- Capturer::WAYLAND(d) => d.set_use_yuv(use_yuv),
- }
- }
-
pub fn width(&self) -> usize {
match self {
Capturer::X11(d) => d.width(),
@@ -37,8 +31,17 @@ impl Capturer {
Capturer::WAYLAND(d) => d.height(),
}
}
+}
- pub fn frame<'a>(&'a mut self, timeout: Duration) -> io::Result> {
+impl TraitCapturer for Capturer {
+ fn set_use_yuv(&mut self, use_yuv: bool) {
+ match self {
+ Capturer::X11(d) => d.set_use_yuv(use_yuv),
+ Capturer::WAYLAND(d) => d.set_use_yuv(use_yuv),
+ }
+ }
+
+ fn frame<'a>(&'a mut self, timeout: Duration) -> io::Result> {
match self {
Capturer::X11(d) => d.frame(timeout),
Capturer::WAYLAND(d) => d.frame(timeout),
diff --git a/libs/scrap/src/common/mod.rs b/libs/scrap/src/common/mod.rs
index 9115bfd3a..4a9ade58d 100644
--- a/libs/scrap/src/common/mod.rs
+++ b/libs/scrap/src/common/mod.rs
@@ -49,3 +49,13 @@ pub fn would_block_if_equal(old: &mut Vec, b: &[u8]) -> std::io::Result<()
old.copy_from_slice(b);
Ok(())
}
+
+pub trait TraitCapturer {
+ fn set_use_yuv(&mut self, use_yuv: bool);
+ fn frame<'a>(&'a mut self, timeout: std::time::Duration) -> std::io::Result>;
+
+ #[cfg(windows)]
+ fn is_gdi(&self) -> bool;
+ #[cfg(windows)]
+ fn set_gdi(&mut self) -> bool;
+}
diff --git a/libs/scrap/src/common/quartz.rs b/libs/scrap/src/common/quartz.rs
index 46ac1b56d..b4ecf898b 100644
--- a/libs/scrap/src/common/quartz.rs
+++ b/libs/scrap/src/common/quartz.rs
@@ -50,8 +50,14 @@ impl Capturer {
pub fn height(&self) -> usize {
self.inner.height()
}
+}
- pub fn frame<'a>(&'a mut self, _timeout_ms: std::time::Duration) -> io::Result> {
+impl TraitCapturer for Capturer {
+ fn set_use_yuv(&mut self, use_yuv: bool) {
+ self.use_yuv = use_yuv;
+ }
+
+ fn frame<'a>(&'a mut self, _timeout_ms: std::time::Duration) -> io::Result> {
match self.frame.try_lock() {
Ok(mut handle) => {
let mut frame = None;
diff --git a/libs/scrap/src/common/wayland.rs b/libs/scrap/src/common/wayland.rs
index 05bb08744..e33cbe745 100644
--- a/libs/scrap/src/common/wayland.rs
+++ b/libs/scrap/src/common/wayland.rs
@@ -1,4 +1,4 @@
-use crate::common::x11::Frame;
+use crate::common::{x11::Frame, TraitCapturer};
use crate::wayland::{capturable::*, *};
use std::{io, time::Duration};
@@ -14,10 +14,6 @@ impl Capturer {
Ok(Capturer(display, r, yuv, Default::default()))
}
- pub fn set_use_yuv(&mut self, use_yuv: bool) {
- self.2 = use_yuv;
- }
-
pub fn width(&self) -> usize {
self.0.width()
}
@@ -25,8 +21,14 @@ impl Capturer {
pub fn height(&self) -> usize {
self.0.height()
}
+}
- pub fn frame<'a>(&'a mut self, timeout: Duration) -> io::Result> {
+impl TraitCapturer for Capturer {
+ fn set_use_yuv(&mut self, use_yuv: bool) {
+ self.2 = use_yuv;
+ }
+
+ fn frame<'a>(&'a mut self, timeout: Duration) -> io::Result> {
match self.1.capture(timeout.as_millis() as _).map_err(map_err)? {
PixelProvider::BGR0(w, h, x) => Ok(Frame(if self.2 {
crate::common::bgra_to_i420(w as _, h as _, &x, &mut self.3);
diff --git a/libs/scrap/src/common/x11.rs b/libs/scrap/src/common/x11.rs
index c1a25c8d6..791514deb 100644
--- a/libs/scrap/src/common/x11.rs
+++ b/libs/scrap/src/common/x11.rs
@@ -1,4 +1,4 @@
-use crate::x11;
+use crate::{x11, common::TraitCapturer};
use std::{io, ops, time::Duration};
pub struct Capturer(x11::Capturer);
@@ -8,10 +8,6 @@ impl Capturer {
x11::Capturer::new(display.0, yuv).map(Capturer)
}
- pub fn set_use_yuv(&mut self, use_yuv: bool) {
- self.0.set_use_yuv(use_yuv);
- }
-
pub fn width(&self) -> usize {
self.0.display().rect().w as usize
}
@@ -19,8 +15,14 @@ impl Capturer {
pub fn height(&self) -> usize {
self.0.display().rect().h as usize
}
+}
- pub fn frame<'a>(&'a mut self, _timeout: Duration) -> io::Result> {
+impl TraitCapturer for Capturer {
+ fn set_use_yuv(&mut self, use_yuv: bool) {
+ self.0.set_use_yuv(use_yuv);
+ }
+
+ fn frame<'a>(&'a mut self, _timeout: Duration) -> io::Result> {
Ok(Frame(self.0.frame()?))
}
}
diff --git a/src/server/video_service.rs b/src/server/video_service.rs
index e6ea713a1..2fb9f3dcd 100644
--- a/src/server/video_service.rs
+++ b/src/server/video_service.rs
@@ -26,11 +26,11 @@ use hbb_common::tokio::sync::{
use scrap::{
codec::{Encoder, EncoderCfg, HwEncoderConfig},
vpxcodec::{VpxEncoderConfig, VpxVideoCodecId},
- Capturer, Display, Frame,
+ Capturer, Display, TraitCapturer,
};
use std::{
collections::HashSet,
- io::{ErrorKind::WouldBlock, Result},
+ io::ErrorKind::WouldBlock,
ops::{Deref, DerefMut},
time::{self, Duration, Instant},
};
@@ -128,56 +128,6 @@ impl VideoFrameController {
}
}
-pub(super) trait TraitCapturer {
- fn frame<'a>(&'a mut self, timeout: Duration) -> Result>;
-
- fn set_use_yuv(&mut self, use_yuv: bool);
-
- #[cfg(windows)]
- fn is_gdi(&self) -> bool;
- #[cfg(windows)]
- fn set_gdi(&mut self) -> bool;
-}
-
-impl TraitCapturer for Capturer {
- fn frame<'a>(&'a mut self, timeout: Duration) -> Result> {
- self.frame(timeout)
- }
-
- fn set_use_yuv(&mut self, use_yuv: bool) {
- self.set_use_yuv(use_yuv);
- }
-
- #[cfg(windows)]
- fn is_gdi(&self) -> bool {
- self.is_gdi()
- }
-
- #[cfg(windows)]
- fn set_gdi(&mut self) -> bool {
- self.set_gdi()
- }
-}
-
-#[cfg(windows)]
-impl TraitCapturer for scrap::CapturerMag {
- fn frame<'a>(&'a mut self, _timeout_ms: Duration) -> Result> {
- self.frame(_timeout_ms)
- }
-
- fn set_use_yuv(&mut self, use_yuv: bool) {
- self.set_use_yuv(use_yuv);
- }
-
- fn is_gdi(&self) -> bool {
- false
- }
-
- fn set_gdi(&mut self) -> bool {
- false
- }
-}
-
pub fn new() -> GenericService {
let sp = GenericService::new(NAME, true);
sp.run(run);
diff --git a/src/server/wayland.rs b/src/server/wayland.rs
index e84be3f7c..1ac2c18be 100644
--- a/src/server/wayland.rs
+++ b/src/server/wayland.rs
@@ -1,30 +1,39 @@
use super::*;
use hbb_common::allow_err;
-use scrap::{Capturer, Display, Frame};
-use std::{io::Result, time::Duration};
+use scrap::{Capturer, Display, Frame, TraitCapturer};
+use std::io::Result;
lazy_static::lazy_static! {
static ref CAP_DISPLAY_INFO: RwLock = RwLock::new(0);
}
+
+struct CapturerPtr(*mut Capturer);
+
+impl Clone for CapturerPtr {
+ fn clone(&self) -> Self {
+ Self(self.0)
+ }
+}
+
+impl TraitCapturer for CapturerPtr {
+ fn frame<'a>(&'a mut self, timeout: Duration) -> Result> {
+ unsafe { (*self.0).frame(timeout) }
+ }
+
+ fn set_use_yuv(&mut self, use_yuv: bool) {
+ unsafe {
+ (*self.0).set_use_yuv(use_yuv);
+ }
+ }
+}
+
struct CapDisplayInfo {
rects: Vec<((i32, i32), usize, usize)>,
displays: Vec,
num: usize,
primary: usize,
current: usize,
- capturer: *mut Capturer,
-}
-
-impl super::video_service::TraitCapturer for *mut Capturer {
- fn frame<'a>(&'a mut self, timeout: Duration) -> Result> {
- unsafe { (**self).frame(timeout) }
- }
-
- fn set_use_yuv(&mut self, use_yuv: bool) {
- unsafe {
- (**self).set_use_yuv(use_yuv);
- }
- }
+ capturer: CapturerPtr,
}
async fn check_init() -> ResultType<()> {
@@ -68,6 +77,7 @@ async fn check_init() -> ResultType<()> {
let capturer = Box::into_raw(Box::new(
Capturer::new(display, true).with_context(|| "Failed to create capturer")?,
));
+ let capturer = CapturerPtr(capturer);
let cap_display_info = Box::into_raw(Box::new(CapDisplayInfo {
rects,
displays,
@@ -104,7 +114,7 @@ pub fn clear() {
if *lock != 0 {
unsafe {
let cap_display_info = Box::from_raw(*lock as *mut CapDisplayInfo);
- let _ = Box::from_raw(cap_display_info.capturer);
+ let _ = Box::from_raw(cap_display_info.capturer.0);
}
*lock = 0;
}
@@ -170,7 +180,7 @@ pub(super) fn get_capturer() -> ResultType {
current: cap_display_info.current,
privacy_mode_id: 0,
_captuerer_privacy_mode_id: 0,
- capturer: Box::new(cap_display_info.capturer),
+ capturer: Box::new(cap_display_info.capturer.clone()),
})
}
} else {