From efa6b5972da1b4d5105a8f8a10144415655e1963 Mon Sep 17 00:00:00 2001 From: tom Date: Sat, 16 Jul 2022 00:45:23 +0800 Subject: [PATCH 01/17] update bytes(protobuf types) mapping, from Vec to bytes:Byte issues:958 --- Cargo.toml | 1 + libs/hbb_common/build.rs | 5 +++++ libs/scrap/src/common/vpxcodec.rs | 3 ++- src/client.rs | 8 ++++---- src/clipboard_file.rs | 8 ++++---- src/common.rs | 4 ++-- src/platform/windows.rs | 2 +- src/rendezvous_mediator.rs | 14 +++++++------- src/server.rs | 6 ++++-- src/server/audio_service.rs | 2 +- src/server/connection.rs | 2 +- src/server/input_service.rs | 2 +- src/ui/cm.rs | 2 +- 13 files changed, 34 insertions(+), 25 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f270f7b3..898d81da 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -55,6 +55,7 @@ rpassword = "6.0" base64 = "0.13" sysinfo = "0.23" num_cpus = "1.13" +bytes = "1.1" [target.'cfg(not(target_os = "linux"))'.dependencies] reqwest = { version = "0.11", features = ["json", "rustls-tls"], default-features=false } diff --git a/libs/hbb_common/build.rs b/libs/hbb_common/build.rs index 5c1c6af2..3c2a3c7a 100644 --- a/libs/hbb_common/build.rs +++ b/libs/hbb_common/build.rs @@ -5,6 +5,11 @@ fn main() { .out_dir("src/protos") .inputs(&["protos/rendezvous.proto", "protos/message.proto"]) .include("protos") + .customize( + protobuf_codegen::Customize::default() + .tokio_bytes(true) + // .tokio_bytes_for_string(true) + ) .run() .expect("Codegen failed."); } diff --git a/libs/scrap/src/common/vpxcodec.rs b/libs/scrap/src/common/vpxcodec.rs index fc54b153..0fda53fa 100644 --- a/libs/scrap/src/common/vpxcodec.rs +++ b/libs/scrap/src/common/vpxcodec.rs @@ -12,6 +12,7 @@ use crate::STRIDE_ALIGN; use super::vpx::{vp8e_enc_control_id::*, vpx_codec_err_t::*, *}; use std::os::raw::{c_int, c_uint}; use std::{ptr, slice}; +use hbb_common::bytes::Bytes; #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub enum VpxVideoCodecId { @@ -291,7 +292,7 @@ impl VpxEncoder { #[inline] fn create_frame(frame: &EncodeFrame) -> EncodedVideoFrame { EncodedVideoFrame { - data: frame.data.to_vec(), + data: Bytes::from(frame.data.to_vec()), key: frame.key, pts: frame.pts, ..Default::default() diff --git a/src/client.rs b/src/client.rs index 33d966d2..a1c9b2b0 100644 --- a/src/client.rs +++ b/src/client.rs @@ -201,7 +201,7 @@ impl Client { } else { peer_nat_type = ph.nat_type(); is_local = ph.is_local(); - signed_id_pk = ph.pk; + signed_id_pk = ph.pk.as_ref().to_vec(); relay_server = ph.relay_server; peer_addr = AddrMangle::decode(&ph.socket_addr); log::info!("Hole Punched {} = {}", peer, peer_addr); @@ -393,8 +393,8 @@ impl Client { let sealed_key = box_::seal(&key.0, &nonce, &their_pk_b, &out_sk_b); let mut msg_out = Message::new(); msg_out.set_public_key(PublicKey { - asymmetric_value: our_pk_b.0.into(), - symmetric_value: sealed_key, + asymmetric_value: Vec::from(our_pk_b.0).into(), + symmetric_value: sealed_key.into(), ..Default::default() }); timeout(CONNECT_TIMEOUT, conn.send(&msg_out)).await??; @@ -1122,7 +1122,7 @@ impl LoginConfigHandler { let my_id = Config::get_id(); let mut lr = LoginRequest { username: self.id.clone(), - password, + password:password.into(), my_id, my_name: crate::username(), option: self.get_option_message(true).into(), diff --git a/src/clipboard_file.rs b/src/clipboard_file.rs index 2f35065c..d2125010 100644 --- a/src/clipboard_file.rs +++ b/src/clipboard_file.rs @@ -67,7 +67,7 @@ pub fn clip_2_msg(clip: ClipbaordFile) -> Message { CliprdrServerFormatDataResponse { conn_id, msg_flags, - format_data, + format_data: format_data.into(), ..Default::default() }, )), @@ -117,7 +117,7 @@ pub fn clip_2_msg(clip: ClipbaordFile) -> Message { conn_id, msg_flags, stream_id, - requested_data, + requested_data: requested_data.into(), ..Default::default() }, )), @@ -156,7 +156,7 @@ pub fn msg_2_clip(msg: Cliprdr) -> Option { Some(ClipbaordFile::ServerFormatDataResponse { conn_id: data.conn_id, msg_flags: data.msg_flags, - format_data: data.format_data, + format_data: data.format_data.as_ref().to_vec(), }) } Some(cliprdr::Union::FileContentsRequest(data)) => { @@ -177,7 +177,7 @@ pub fn msg_2_clip(msg: Cliprdr) -> Option { conn_id: data.conn_id, msg_flags: data.msg_flags, stream_id: data.stream_id, - requested_data: data.requested_data, + requested_data: data.requested_data.as_ref().to_vec(), }) } _ => None, diff --git a/src/common.rs b/src/common.rs index 9917a47f..2930a161 100644 --- a/src/common.rs +++ b/src/common.rs @@ -49,7 +49,7 @@ pub fn create_clipboard_msg(content: String) -> Message { let mut msg = Message::new(); msg.set_clipboard(Clipboard { compress, - content, + content:content.into(), ..Default::default() }); msg @@ -80,7 +80,7 @@ pub fn update_clipboard(clipboard: Clipboard, old: Option<&Arc>>) let content = if clipboard.compress { decompress(&clipboard.content) } else { - clipboard.content + clipboard.content.as_ref().to_vec() }; if let Ok(content) = String::from_utf8(content) { if content.is_empty() { diff --git a/src/platform/windows.rs b/src/platform/windows.rs index c9f83389..cb0fd778 100644 --- a/src/platform/windows.rs +++ b/src/platform/windows.rs @@ -164,7 +164,7 @@ pub fn get_cursor_data(hcursor: u64) -> ResultType { Ok(CursorData { id: hcursor, - colors: cbits, + colors: cbits.into(), hotx: ii.0.xHotspot as _, hoty: ii.0.yHotspot as _, width: width as _, diff --git a/src/rendezvous_mediator.rs b/src/rendezvous_mediator.rs index 4381fbc7..a07a096a 100644 --- a/src/rendezvous_mediator.rs +++ b/src/rendezvous_mediator.rs @@ -263,7 +263,7 @@ impl RendezvousMediator { async fn handle_request_relay(&self, rr: RequestRelay, server: ServerPtr) -> ResultType<()> { self.create_relay( - rr.socket_addr, + rr.socket_addr.as_ref().to_vec(), rr.relay_server, rr.uuid, server, @@ -300,7 +300,7 @@ impl RendezvousMediator { let mut msg_out = Message::new(); let mut rr = RelayResponse { - socket_addr, + socket_addr: socket_addr.into(), version: crate::VERSION.to_owned(), ..Default::default() }; @@ -331,8 +331,8 @@ impl RendezvousMediator { let relay_server = self.get_relay_server(fla.relay_server); msg_out.set_local_addr(LocalAddr { id: Config::get_id(), - socket_addr: AddrMangle::encode(peer_addr), - local_addr: AddrMangle::encode(local_addr), + socket_addr: AddrMangle::encode(peer_addr).into(), + local_addr: AddrMangle::encode(local_addr).into(), relay_server, version: crate::VERSION.to_owned(), ..Default::default() @@ -350,7 +350,7 @@ impl RendezvousMediator { { let uuid = Uuid::new_v4().to_string(); return self - .create_relay(ph.socket_addr, relay_server, uuid, server, true, true) + .create_relay(ph.socket_addr.as_ref().to_vec(), relay_server, uuid, server, true, true) .await; } let peer_addr = AddrMangle::decode(&ph.socket_addr); @@ -391,8 +391,8 @@ impl RendezvousMediator { self.last_id_pk_registry = id.clone(); msg_out.set_register_pk(RegisterPk { id, - uuid, - pk, + uuid: uuid.into(), + pk: pk.into(), ..Default::default() }); socket.send(&msg_out, self.addr.to_owned()).await?; diff --git a/src/server.rs b/src/server.rs index d437ce6d..0d2e97c6 100644 --- a/src/server.rs +++ b/src/server.rs @@ -20,6 +20,8 @@ use std::{ sync::{Arc, Mutex, RwLock, Weak}, time::Duration, }; +use bytes::Bytes; + pub mod audio_service; cfg_if::cfg_if! { if #[cfg(not(any(target_os = "android", target_os = "ios")))] { @@ -126,13 +128,13 @@ pub async fn create_tcp_connection( id: sign::sign( &IdPk { id: Config::get_id(), - pk: our_pk_b.0.to_vec(), + pk: Bytes::from(our_pk_b.0.to_vec()), ..Default::default() } .write_to_bytes() .unwrap_or_default(), &sk, - ), + ).into(), ..Default::default() }); timeout(CONNECT_TIMEOUT, stream.send(&msg_out)).await??; diff --git a/src/server/audio_service.rs b/src/server/audio_service.rs index e0974a22..02db0bff 100644 --- a/src/server/audio_service.rs +++ b/src/server/audio_service.rs @@ -367,7 +367,7 @@ fn send_f32(data: &[f32], encoder: &mut Encoder, sp: &GenericService) { Ok(data) => { let mut msg_out = Message::new(); msg_out.set_audio_frame(AudioFrame { - data, + data: data.into(), timestamp: crate::common::get_time(), ..Default::default() }); diff --git a/src/server/connection.rs b/src/server/connection.rs index e8344c4a..64ff6cbe 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -1063,7 +1063,7 @@ impl Connection { self.send_fs(ipc::FS::WriteBlock { id: block.id, file_num: block.file_num, - data: block.data, + data: block.data.as_ref().to_vec(), compressed: block.compressed, }); } diff --git a/src/server/input_service.rs b/src/server/input_service.rs index 3ec9c0f7..9bae8d35 100644 --- a/src/server/input_service.rs +++ b/src/server/input_service.rs @@ -145,7 +145,7 @@ fn run_cursor(sp: MouseCursorService, state: &mut StateCursor) -> ResultType<()> msg = cached.clone(); } else { let mut data = crate::get_cursor_data(hcursor)?; - data.colors = hbb_common::compress::compress(&data.colors[..], COMPRESS_LEVEL); + data.colors = hbb_common::compress::compress(&data.colors[..], COMPRESS_LEVEL).into(); let mut tmp = Message::new(); tmp.set_cursor_data(data); msg = Arc::new(tmp); diff --git a/src/ui/cm.rs b/src/ui/cm.rs index c1acb692..1c2b36a9 100644 --- a/src/ui/cm.rs +++ b/src/ui/cm.rs @@ -263,7 +263,7 @@ impl ConnectionManager { FileTransferBlock { id, file_num, - data, + data: data.into(), compressed, ..Default::default() }, From ae839bd5bf0641d1709ab7aaa510e7c64b67d130 Mon Sep 17 00:00:00 2001 From: tom Date: Sun, 17 Jul 2022 00:59:56 +0800 Subject: [PATCH 02/17] update linux.rs & macos.rs with bytes:Byte issues:958 --- libs/hbb_common/build.rs | 1 - src/platform/linux.rs | 12 +++++++----- src/platform/macos.rs | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/libs/hbb_common/build.rs b/libs/hbb_common/build.rs index 3c2a3c7a..225ec34c 100644 --- a/libs/hbb_common/build.rs +++ b/libs/hbb_common/build.rs @@ -8,7 +8,6 @@ fn main() { .customize( protobuf_codegen::Customize::default() .tokio_bytes(true) - // .tokio_bytes_for_string(true) ) .run() .expect("Codegen failed."); diff --git a/src/platform/linux.rs b/src/platform/linux.rs index efd6476b..f331dd6e 100644 --- a/src/platform/linux.rs +++ b/src/platform/linux.rs @@ -109,7 +109,8 @@ pub fn get_cursor_data(hcursor: u64) -> ResultType { cd.id = (*img).cursor_serial as _; let pixels = std::slice::from_raw_parts((*img).pixels, (cd.width * cd.height) as _); - cd.colors.resize(pixels.len() * 4, 0); + // cd.colors.resize(pixels.len() * 4, 0); + let mut cd_colors = vec![0_u8; pixels.len() * 4]; for y in 0..cd.height { for x in 0..cd.width { let pos = (y * cd.width + x) as usize; @@ -122,12 +123,13 @@ pub fn get_cursor_data(hcursor: u64) -> ResultType { continue; } let pos = pos * 4; - cd.colors[pos] = r as _; - cd.colors[pos + 1] = g as _; - cd.colors[pos + 2] = b as _; - cd.colors[pos + 3] = a as _; + cd_colors[pos] = r as _; + cd_colors[pos + 1] = g as _; + cd_colors[pos + 2] = b as _; + cd_colors[pos + 3] = a as _; } } + cd.colors = cd_colors.into(); res = Some(cd); } if !img.is_null() { diff --git a/src/platform/macos.rs b/src/platform/macos.rs index dabe11e4..1a809658 100644 --- a/src/platform/macos.rs +++ b/src/platform/macos.rs @@ -342,7 +342,7 @@ pub fn get_cursor_data(hcursor: u64) -> ResultType { } Ok(CursorData { id: hcursor, - colors, + colors: colors.into(), hotx: hotspot.x as _, hoty: hotspot.y as _, width: size.width as _, From 16b7c7c7163e7b386e29352b29828012e11ec542 Mon Sep 17 00:00:00 2001 From: tom Date: Thu, 21 Jul 2022 00:39:20 +0800 Subject: [PATCH 03/17] upgrade bytes to 1.2 --- Cargo.toml | 2 +- libs/hbb_common/Cargo.toml | 2 +- src/client.rs | 2 +- src/clipboard_file.rs | 4 ++-- src/common.rs | 2 +- src/rendezvous_mediator.rs | 4 ++-- src/server/connection.rs | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3656e822..6237afe4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -55,7 +55,7 @@ rpassword = "7.0" base64 = "0.13" sysinfo = "0.24" num_cpus = "1.13" -bytes = "1.1" +bytes = "1.2" default-net = "0.11.0" wol-rs = "0.9.1" diff --git a/libs/hbb_common/Cargo.toml b/libs/hbb_common/Cargo.toml index 6fec6719..8d34709f 100644 --- a/libs/hbb_common/Cargo.toml +++ b/libs/hbb_common/Cargo.toml @@ -11,7 +11,7 @@ protobuf = { version = "3.1", features = ["with-bytes"] } tokio = { version = "1.20", features = ["full"] } tokio-util = { version = "0.7", features = ["full"] } futures = "0.3" -bytes = "1.1" +bytes = "1.2" log = "0.4" env_logger = "0.9" socket2 = { version = "0.3", features = ["reuseport"] } diff --git a/src/client.rs b/src/client.rs index c8a561c8..9b4bb181 100644 --- a/src/client.rs +++ b/src/client.rs @@ -215,7 +215,7 @@ impl Client { } else { peer_nat_type = ph.nat_type(); is_local = ph.is_local(); - signed_id_pk = ph.pk.as_ref().to_vec(); + signed_id_pk = ph.pk.into(); relay_server = ph.relay_server; peer_addr = AddrMangle::decode(&ph.socket_addr); log::info!("Hole Punched {} = {}", peer, peer_addr); diff --git a/src/clipboard_file.rs b/src/clipboard_file.rs index d2125010..b6c0513e 100644 --- a/src/clipboard_file.rs +++ b/src/clipboard_file.rs @@ -156,7 +156,7 @@ pub fn msg_2_clip(msg: Cliprdr) -> Option { Some(ClipbaordFile::ServerFormatDataResponse { conn_id: data.conn_id, msg_flags: data.msg_flags, - format_data: data.format_data.as_ref().to_vec(), + format_data: data.format_data.into(), }) } Some(cliprdr::Union::FileContentsRequest(data)) => { @@ -177,7 +177,7 @@ pub fn msg_2_clip(msg: Cliprdr) -> Option { conn_id: data.conn_id, msg_flags: data.msg_flags, stream_id: data.stream_id, - requested_data: data.requested_data.as_ref().to_vec(), + requested_data: data.requested_data.into(), }) } _ => None, diff --git a/src/common.rs b/src/common.rs index b2026e5b..e4ec7cb9 100644 --- a/src/common.rs +++ b/src/common.rs @@ -79,7 +79,7 @@ pub fn update_clipboard(clipboard: Clipboard, old: Option<&Arc>>) let content = if clipboard.compress { decompress(&clipboard.content) } else { - clipboard.content.as_ref().to_vec() + clipboard.content.into() }; if let Ok(content) = String::from_utf8(content) { if content.is_empty() { diff --git a/src/rendezvous_mediator.rs b/src/rendezvous_mediator.rs index 24e50f08..7cf05984 100644 --- a/src/rendezvous_mediator.rs +++ b/src/rendezvous_mediator.rs @@ -266,7 +266,7 @@ impl RendezvousMediator { async fn handle_request_relay(&self, rr: RequestRelay, server: ServerPtr) -> ResultType<()> { self.create_relay( - rr.socket_addr.as_ref().to_vec(), + rr.socket_addr.into(), rr.relay_server, rr.uuid, server, @@ -353,7 +353,7 @@ impl RendezvousMediator { { let uuid = Uuid::new_v4().to_string(); return self - .create_relay(ph.socket_addr.as_ref().to_vec(), relay_server, uuid, server, true, true) + .create_relay(ph.socket_addr.into(), relay_server, uuid, server, true, true) .await; } let peer_addr = AddrMangle::decode(&ph.socket_addr); diff --git a/src/server/connection.rs b/src/server/connection.rs index 677d8f23..10a1786f 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -1063,7 +1063,7 @@ impl Connection { self.send_fs(ipc::FS::WriteBlock { id: block.id, file_num: block.file_num, - data: block.data.as_ref().to_vec(), + data: block.data.into(), compressed: block.compressed, }); } From 1fecd7168a3f9b15e0ed8e973d215e66551fd604 Mon Sep 17 00:00:00 2001 From: 21pages Date: Thu, 7 Jul 2022 20:55:19 +0800 Subject: [PATCH 04/17] hwcodec: linux compatible Signed-off-by: 21pages --- Cargo.lock | 2 +- libs/scrap/Cargo.toml | 2 +- libs/scrap/src/common/convert.rs | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c9127211..21224012 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2209,7 +2209,7 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hwcodec" version = "0.1.0" -source = "git+https://github.com/21pages/hwcodec#91d1cd327c88490f917457072aeef0676ddb2be7" +source = "git+https://github.com/21pages/hwcodec#890204e0703a3d361fc7a45f035fe75c0575bb1d" dependencies = [ "bindgen", "cc", diff --git a/libs/scrap/Cargo.toml b/libs/scrap/Cargo.toml index 1b269d96..d40eb0cf 100644 --- a/libs/scrap/Cargo.toml +++ b/libs/scrap/Cargo.toml @@ -50,5 +50,5 @@ gstreamer = { version = "0.16", optional = true } gstreamer-app = { version = "0.16", features = ["v1_10"], optional = true } gstreamer-video = { version = "0.16", optional = true } -[target.'cfg(target_os = "windows")'.dependencies] +[target.'cfg(any(target_os = "windows", target_os = "linux"))'.dependencies] hwcodec = { git = "https://github.com/21pages/hwcodec", optional = true } diff --git a/libs/scrap/src/common/convert.rs b/libs/scrap/src/common/convert.rs index 306a217e..2b0223a0 100644 --- a/libs/scrap/src/common/convert.rs +++ b/libs/scrap/src/common/convert.rs @@ -246,6 +246,7 @@ pub unsafe fn nv12_to_i420( #[cfg(feature = "hwcodec")] pub mod hw { use hbb_common::{anyhow::anyhow, ResultType}; + #[cfg(target_os = "windows")] use hwcodec::{ffmpeg::ffmpeg_linesize_offset_length, AVPixelFormat}; pub fn hw_bgra_to_i420( @@ -381,6 +382,8 @@ pub mod hw { src_stride_y: usize, src_stride_uv: usize, dst: &mut Vec, + _i420: &mut Vec, + _align: usize, ) -> ResultType<()> { dst.resize(width * height * 4, 0); unsafe { From 1b1f28b872a32ba7220affe977d285fae35e57f4 Mon Sep 17 00:00:00 2001 From: 21pages Date: Fri, 8 Jul 2022 18:18:58 +0800 Subject: [PATCH 05/17] hwcodec: check when server or each client starts and refactor hwcodec::best() Signed-off-by: 21pages --- libs/hbb_common/src/config.rs | 4 + libs/scrap/src/common/codec.rs | 4 +- libs/scrap/src/common/hwcodec.rs | 127 +++++++++++++------------------ src/server.rs | 17 ++--- 4 files changed, 69 insertions(+), 83 deletions(-) diff --git a/libs/hbb_common/src/config.rs b/libs/hbb_common/src/config.rs index 787ffe5e..cf657c8d 100644 --- a/libs/hbb_common/src/config.rs +++ b/libs/hbb_common/src/config.rs @@ -978,6 +978,10 @@ impl HwCodecConfig { pub fn store(&self) { Config::store_(self, "_hwcodec"); } + + pub fn remove() { + std::fs::remove_file(Config::file_("_hwcodec")).ok(); + } } #[cfg(test)] diff --git a/libs/scrap/src/common/codec.rs b/libs/scrap/src/common/codec.rs index 1d9deba6..b48053e0 100644 --- a/libs/scrap/src/common/codec.rs +++ b/libs/scrap/src/common/codec.rs @@ -102,7 +102,7 @@ impl Encoder { codec: Box::new(hw), }), Err(e) => { - HwEncoder::best(true, true); + check_config_process(true); Err(e) } }, @@ -132,7 +132,7 @@ impl Encoder { } let current_encoder_name = HwEncoder::current_name(); if states.len() > 0 { - let (best, _) = HwEncoder::best(false, true); + let best = HwEncoder::best(); let enabled_h264 = best.h264.is_some() && states.len() > 0 && states.iter().all(|(_, s)| s.ScoreH264 > 0); diff --git a/libs/scrap/src/common/hwcodec.rs b/libs/scrap/src/common/hwcodec.rs index ff23978d..c2c85395 100644 --- a/libs/scrap/src/common/hwcodec.rs +++ b/libs/scrap/src/common/hwcodec.rs @@ -123,40 +123,11 @@ impl EncoderApi for HwEncoder { } impl HwEncoder { - /// Get best encoders. - /// - /// # Parameter - /// `force_reset`: force to refresh config. - /// `write`: write to config file. - /// - /// # Return - /// `CodecInfos`: infos. - /// `bool`: whether the config is refreshed. - pub fn best(force_reset: bool, write: bool) -> (CodecInfos, bool) { - let config = get_config(CFG_KEY_ENCODER); - if !force_reset && config.is_ok() { - (config.unwrap(), false) - } else { - let ctx = EncodeContext { - name: String::from(""), - width: 1920, - height: 1080, - pixfmt: DEFAULT_PIXFMT, - align: HW_STRIDE_ALIGN as _, - bitrate: 0, - timebase: DEFAULT_TIME_BASE, - gop: DEFAULT_GOP, - quality: DEFAULT_HW_QUALITY, - rc: DEFAULT_RC, - }; - let encoders = CodecInfo::score(Encoder::avaliable_encoders(ctx)); - if write { - set_config(CFG_KEY_ENCODER, &encoders) - .map_err(|e| log::error!("{:?}", e)) - .ok(); - } - (encoders, true) - } + pub fn best() -> CodecInfos { + get_config(CFG_KEY_ENCODER).unwrap_or(CodecInfos { + h264: None, + h265: None, + }) } pub fn current_name() -> Arc>> { @@ -207,24 +178,15 @@ pub struct HwDecoders { } impl HwDecoder { - /// See HwEncoder::best - fn best(force_reset: bool, write: bool) -> (CodecInfos, bool) { - let config = get_config(CFG_KEY_DECODER); - if !force_reset && config.is_ok() { - (config.unwrap(), false) - } else { - let decoders = CodecInfo::score(Decoder::avaliable_decoders()); - if write { - set_config(CFG_KEY_DECODER, &decoders) - .map_err(|e| log::error!("{:?}", e)) - .ok(); - } - (decoders, true) - } + fn best() -> CodecInfos { + get_config(CFG_KEY_DECODER).unwrap_or(CodecInfos { + h264: None, + h265: None, + }) } pub fn new_decoders() -> HwDecoders { - let (best, _) = HwDecoder::best(false, true); + let best = HwDecoder::best(); let mut h264: Option = None; let mut h265: Option = None; let mut fail = false; @@ -242,7 +204,7 @@ impl HwDecoder { } } if fail { - HwDecoder::best(true, true); + check_config_process(true); } HwDecoders { h264, h265 } } @@ -314,31 +276,52 @@ fn get_config(k: &str) -> ResultType { } } -fn set_config(k: &str, v: &CodecInfos) -> ResultType<()> { - match v.serialize() { - Ok(v) => { - let mut config = HwCodecConfig::load(); - config.options.insert(k.to_owned(), v); - config.store(); - Ok(()) - } - Err(_) => Err(anyhow!("Failed to set config:{}", k)), - } -} - pub fn check_config() { - let (encoders, update_encoders) = HwEncoder::best(false, false); - let (decoders, update_decoders) = HwDecoder::best(false, false); - if update_encoders || update_decoders { - if let Ok(encoders) = encoders.serialize() { - if let Ok(decoders) = decoders.serialize() { - let mut config = HwCodecConfig::load(); - config.options.insert(CFG_KEY_ENCODER.to_owned(), encoders); - config.options.insert(CFG_KEY_DECODER.to_owned(), decoders); - config.store(); + let ctx = EncodeContext { + name: String::from(""), + width: 1920, + height: 1080, + pixfmt: DEFAULT_PIXFMT, + align: HW_STRIDE_ALIGN as _, + bitrate: 0, + timebase: DEFAULT_TIME_BASE, + gop: DEFAULT_GOP, + quality: DEFAULT_HW_QUALITY, + rc: DEFAULT_RC, + }; + let encoders = CodecInfo::score(Encoder::avaliable_encoders(ctx)); + let decoders = CodecInfo::score(Decoder::avaliable_decoders()); + + if let Ok(old_encoders) = get_config(CFG_KEY_ENCODER) { + if let Ok(old_decoders) = get_config(CFG_KEY_DECODER) { + if encoders == old_encoders && decoders == old_decoders { return; } } - log::error!("Failed to serialize codec info"); } + + if let Ok(encoders) = encoders.serialize() { + if let Ok(decoders) = decoders.serialize() { + let mut config = HwCodecConfig::load(); + config.options.insert(CFG_KEY_ENCODER.to_owned(), encoders); + config.options.insert(CFG_KEY_DECODER.to_owned(), decoders); + config.store(); + return; + } + } + log::error!("Failed to serialize codec info"); +} + +pub fn check_config_process(force_reset: bool) { + if force_reset { + HwCodecConfig::remove(); + } + if let Ok(exe) = std::env::current_exe() { + std::thread::spawn(move || { + std::process::Command::new(exe) + .arg("--check-hwcodec-config") + .status() + .ok() + }); + }; } diff --git a/src/server.rs b/src/server.rs index a71efaee..f2d643e1 100644 --- a/src/server.rs +++ b/src/server.rs @@ -319,6 +319,14 @@ pub async fn start_server(is_server: bool) { log::info!("DISPLAY={:?}", std::env::var("DISPLAY")); log::info!("XAUTHORITY={:?}", std::env::var("XAUTHORITY")); } + #[cfg(feature = "hwcodec")] + { + use std::sync::Once; + static ONCE: Once = Once::new(); + ONCE.call_once(|| { + scrap::hwcodec::check_config_process(false); + }) + } if is_server { std::thread::spawn(move || { @@ -327,15 +335,6 @@ pub async fn start_server(is_server: bool) { std::process::exit(-1); } }); - #[cfg(feature = "hwcodec")] - if let Ok(exe) = std::env::current_exe() { - std::thread::spawn(move || { - std::process::Command::new(exe) - .arg("--check-hwcodec-config") - .status() - .ok() - }); - } #[cfg(windows)] crate::platform::windows::bootstrap(); input_service::fix_key_down_timeout_loop(); From 7aa431d349593467fbbefb05375fbb80d4aa7dbe Mon Sep 17 00:00:00 2001 From: 21pages Date: Sat, 9 Jul 2022 20:17:10 +0800 Subject: [PATCH 06/17] hwcodec: codec preference Signed-off-by: 21pages --- libs/hbb_common/protos/message.proto | 20 +++- libs/scrap/src/common/codec.rs | 143 +++++++++++++++++++-------- src/client.rs | 21 +++- src/server/connection.rs | 16 +++ src/server/video_service.rs | 4 + src/ui/header.css | 1 + src/ui/header.tis | 20 +++- src/ui/remote.rs | 39 ++++++++ 8 files changed, 217 insertions(+), 47 deletions(-) diff --git a/libs/hbb_common/protos/message.proto b/libs/hbb_common/protos/message.proto index 2044388f..7b4bc378 100644 --- a/libs/hbb_common/protos/message.proto +++ b/libs/hbb_common/protos/message.proto @@ -72,6 +72,11 @@ message Features { bool privacy_mode = 1; } +message SupportedEncoding { + bool h264 = 1; + bool h265 = 2; +} + message PeerInfo { string username = 1; string hostname = 2; @@ -82,6 +87,7 @@ message PeerInfo { string version = 7; int32 conn_id = 8; Features features = 9; + SupportedEncoding encoding = 10; } message LoginResponse { @@ -434,9 +440,17 @@ enum ImageQuality { } message VideoCodecState { - int32 ScoreVpx = 1; - int32 ScoreH264 = 2; - int32 ScoreH265 = 3; + enum PerferCodec { + Auto = 0; + VPX = 1; + H264 = 2; + H265 = 3; + } + + int32 score_vpx = 1; + int32 score_h264 = 2; + int32 score_h265 = 3; + PerferCodec perfer = 4; } message OptionMessage { diff --git a/libs/scrap/src/common/codec.rs b/libs/scrap/src/common/codec.rs index b48053e0..1a18a79c 100644 --- a/libs/scrap/src/common/codec.rs +++ b/libs/scrap/src/common/codec.rs @@ -16,7 +16,11 @@ use hbb_common::{ ResultType, }; #[cfg(feature = "hwcodec")] -use hbb_common::{config::Config2, lazy_static}; +use hbb_common::{ + config::{Config2, PeerConfig}, + lazy_static, + message_proto::video_codec_state::PerferCodec, +}; #[cfg(feature = "hwcodec")] lazy_static::lazy_static! { @@ -113,7 +117,6 @@ impl Encoder { // TODO pub fn update_video_encoder(id: i32, update: EncoderUpdate) { - log::info!("encoder update: {:?}", update); #[cfg(feature = "hwcodec")] { let mut states = PEER_DECODER_STATES.lock().unwrap(); @@ -130,49 +133,75 @@ impl Encoder { } } } - let current_encoder_name = HwEncoder::current_name(); + let name = HwEncoder::current_name(); if states.len() > 0 { let best = HwEncoder::best(); let enabled_h264 = best.h264.is_some() && states.len() > 0 - && states.iter().all(|(_, s)| s.ScoreH264 > 0); + && states.iter().all(|(_, s)| s.score_h264 > 0); let enabled_h265 = best.h265.is_some() && states.len() > 0 - && states.iter().all(|(_, s)| s.ScoreH265 > 0); + && states.iter().all(|(_, s)| s.score_h265 > 0); - // score encoder - let mut score_vpx = SCORE_VPX; - let mut score_h264 = best.h264.as_ref().map_or(0, |c| c.score); - let mut score_h265 = best.h265.as_ref().map_or(0, |c| c.score); - - // score decoder - score_vpx += states.iter().map(|s| s.1.ScoreVpx).sum::(); - if enabled_h264 { - score_h264 += states.iter().map(|s| s.1.ScoreH264).sum::(); - } - if enabled_h265 { - score_h265 += states.iter().map(|s| s.1.ScoreH265).sum::(); + // Preference first + let mut preference = PerferCodec::Auto; + let preferences: Vec<_> = states + .iter() + .filter(|(_, s)| { + s.perfer == PerferCodec::VPX.into() + || s.perfer == PerferCodec::H264.into() && enabled_h264 + || s.perfer == PerferCodec::H265.into() && enabled_h265 + }) + .map(|(_, s)| s.perfer) + .collect(); + if preferences.len() > 0 && preferences.iter().all(|&p| p == preferences[0]) { + preference = preferences[0].enum_value_or(PerferCodec::Auto); } - if enabled_h265 && score_h265 >= score_vpx && score_h265 >= score_h264 { - *current_encoder_name.lock().unwrap() = Some(best.h265.unwrap().name); - } else if enabled_h264 && score_h264 >= score_vpx && score_h264 >= score_h265 { - *current_encoder_name.lock().unwrap() = Some(best.h264.unwrap().name); - } else { - *current_encoder_name.lock().unwrap() = None; + match preference { + PerferCodec::VPX => *name.lock().unwrap() = None, + PerferCodec::H264 => { + *name.lock().unwrap() = best.h264.map_or(None, |c| Some(c.name)) + } + PerferCodec::H265 => { + *name.lock().unwrap() = best.h265.map_or(None, |c| Some(c.name)) + } + PerferCodec::Auto => { + // score encoder + let mut score_vpx = SCORE_VPX; + let mut score_h264 = best.h264.as_ref().map_or(0, |c| c.score); + let mut score_h265 = best.h265.as_ref().map_or(0, |c| c.score); + + // score decoder + score_vpx += states.iter().map(|s| s.1.score_vpx).sum::(); + if enabled_h264 { + score_h264 += states.iter().map(|s| s.1.score_h264).sum::(); + } + if enabled_h265 { + score_h265 += states.iter().map(|s| s.1.score_h265).sum::(); + } + + if enabled_h265 && score_h265 >= score_vpx && score_h265 >= score_h264 { + *name.lock().unwrap() = best.h265.map_or(None, |c| Some(c.name)); + } else if enabled_h264 + && score_h264 >= score_vpx + && score_h264 >= score_h265 + { + *name.lock().unwrap() = best.h264.map_or(None, |c| Some(c.name)); + } else { + *name.lock().unwrap() = None; + } + } } + log::info!( - "connection count:{}, h264:{}, h265:{}, score: vpx({}), h264({}), h265({}), set current encoder name {:?}", + "connection count:{}, used preference:{:?}, encoder:{:?}", states.len(), - enabled_h264, - enabled_h265, - score_vpx, - score_h264, - score_h265, - current_encoder_name.lock().unwrap() - ) + preference, + name.lock().unwrap() + ) } else { - *current_encoder_name.lock().unwrap() = None; + *name.lock().unwrap() = None; } } #[cfg(not(feature = "hwcodec"))] @@ -192,34 +221,51 @@ impl Encoder { #[cfg(not(feature = "hwcodec"))] return None; } + + pub fn supported_encoding() -> (bool, bool) { + #[cfg(feature = "hwcodec")] + if check_hwcodec_config() { + let best = HwEncoder::best(); + ( + best.h264.as_ref().map_or(false, |c| c.score > 0), + best.h265.as_ref().map_or(false, |c| c.score > 0), + ) + } else { + (false, false) + } + #[cfg(not(feature = "hwcodec"))] + (false, false) + } } #[cfg(feature = "hwcodec")] impl Drop for Decoder { fn drop(&mut self) { *MY_DECODER_STATE.lock().unwrap() = VideoCodecState { - ScoreVpx: SCORE_VPX, + score_vpx: SCORE_VPX, ..Default::default() }; } } impl Decoder { - pub fn video_codec_state() -> VideoCodecState { + pub fn video_codec_state(_id: &str) -> VideoCodecState { // video_codec_state is mainted by creation and destruction of Decoder. // It has been ensured to use after Decoder's creation. #[cfg(feature = "hwcodec")] if check_hwcodec_config() { - return MY_DECODER_STATE.lock().unwrap().clone(); + let mut state = MY_DECODER_STATE.lock().unwrap(); + state.perfer = Self::codec_preference(_id).into(); + state.clone() } else { return VideoCodecState { - ScoreVpx: SCORE_VPX, + score_vpx: SCORE_VPX, ..Default::default() }; } #[cfg(not(feature = "hwcodec"))] VideoCodecState { - ScoreVpx: SCORE_VPX, + score_vpx: SCORE_VPX, ..Default::default() } } @@ -237,9 +283,9 @@ impl Decoder { #[cfg(feature = "hwcodec")] { let mut state = MY_DECODER_STATE.lock().unwrap(); - state.ScoreVpx = SCORE_VPX; - state.ScoreH264 = decoder.hw.h264.as_ref().map_or(0, |d| d.info.score); - state.ScoreH265 = decoder.hw.h265.as_ref().map_or(0, |d| d.info.score); + state.score_vpx = SCORE_VPX; + state.score_h264 = decoder.hw.h264.as_ref().map_or(0, |d| d.info.score); + state.score_h265 = decoder.hw.h265.as_ref().map_or(0, |d| d.info.score); } decoder @@ -316,6 +362,23 @@ impl Decoder { } return Ok(ret); } + + #[cfg(feature = "hwcodec")] + fn codec_preference(id: &str) -> PerferCodec { + let codec = PeerConfig::load(id) + .options + .get("codec-preference") + .map_or("".to_owned(), |c| c.to_owned()); + if codec == "vp9" { + PerferCodec::VPX + } else if codec == "h264" { + PerferCodec::H264 + } else if codec == "h265" { + PerferCodec::H265 + } else { + PerferCodec::Auto + } + } } #[cfg(feature = "hwcodec")] diff --git a/src/client.rs b/src/client.rs index 28101896..dbea079e 100644 --- a/src/client.rs +++ b/src/client.rs @@ -784,6 +784,7 @@ pub struct LoginConfigHandler { pub conn_id: i32, features: Option, session_id: u64, + pub supported_encoding: Option<(bool, bool)>, } impl Deref for LoginConfigHandler { @@ -808,6 +809,7 @@ impl LoginConfigHandler { self.remember = !config.password.is_empty(); self.config = config; self.session_id = rand::random(); + self.supported_encoding = None; } pub fn should_auto_login(&self) -> String { @@ -958,8 +960,7 @@ impl LoginConfigHandler { msg.disable_clipboard = BoolOption::Yes.into(); n += 1; } - // TODO: add option - let state = Decoder::video_codec_state(); + let state = Decoder::video_codec_state(&self.id); msg.video_codec_state = hbb_common::protobuf::MessageField::some(state); n += 1; @@ -1111,6 +1112,10 @@ impl LoginConfigHandler { self.conn_id = pi.conn_id; // no matter if change, for update file time self.save_config(config); + #[cfg(feature = "hwcodec")] + { + self.supported_encoding = Some((pi.encoding.h264, pi.encoding.h265)); + } } pub fn get_remote_dir(&self) -> String { @@ -1163,6 +1168,18 @@ impl LoginConfigHandler { msg_out.set_login_request(lr); msg_out } + + pub fn change_prefer_codec(&self) -> Message { + let state = scrap::codec::Decoder::video_codec_state(&self.id); + let mut misc = Misc::new(); + misc.set_option(OptionMessage { + video_codec_state: hbb_common::protobuf::MessageField::some(state), + ..Default::default() + }); + let mut msg_out = Message::new(); + msg_out.set_misc(misc); + msg_out + } } pub enum MediaData { diff --git a/src/server/connection.rs b/src/server/connection.rs index 869df419..8b0b3f19 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -635,6 +635,16 @@ impl Connection { pi.hostname = MOBILE_INFO2.lock().unwrap().clone(); pi.platform = "Android".into(); } + #[cfg(feature = "hwcodec")] + { + let (h264, h265) = scrap::codec::Encoder::supported_encoding(); + pi.encoding = Some(SupportedEncoding { + h264, + h265, + ..Default::default() + }) + .into(); + } if self.port_forward_socket.is_some() { let mut msg_out = Message::new(); @@ -1351,6 +1361,12 @@ impl Connection { } } } + if let Some(q) = o.video_codec_state.clone().take() { + scrap::codec::Encoder::update_video_encoder( + self.inner.id(), + scrap::codec::EncoderUpdate::State(q), + ); + } } async fn on_close(&mut self, reason: &str, lock: bool) { diff --git a/src/server/video_service.rs b/src/server/video_service.rs index e6ea713a..e639fbe2 100644 --- a/src/server/video_service.rs +++ b/src/server/video_service.rs @@ -483,6 +483,7 @@ fn run(sp: GenericService) -> ResultType<()> { let mut try_gdi = 1; #[cfg(windows)] log::info!("gdi: {}", c.is_gdi()); + let codec_name = Encoder::current_hw_encoder_name(); while sp.ok() { #[cfg(windows)] @@ -508,6 +509,9 @@ fn run(sp: GenericService) -> ResultType<()> { *SWITCH.lock().unwrap() = true; bail!("SWITCH"); } + if codec_name != Encoder::current_hw_encoder_name() { + bail!("SWITCH"); + } check_privacy_mode_changed(&sp, c.privacy_mode_id)?; #[cfg(windows)] { diff --git a/src/ui/header.css b/src/ui/header.css index fb7b57fd..e248b46d 100644 --- a/src/ui/header.css +++ b/src/ui/header.css @@ -94,3 +94,4 @@ span#fullscreen.active { button:disabled { opacity: 0.3; } + diff --git a/src/ui/header.tis b/src/ui/header.tis index 35a132c9..6ee3cad0 100644 --- a/src/ui/header.tis +++ b/src/ui/header.tis @@ -145,6 +145,9 @@ class Header: Reactor.Component { } function renderDisplayPop() { + var codecs = handler.supported_hwcodec(); + var show_codec = handler.has_hwcodec() && (codecs[0] || codecs[1]); + return
  • {translate('Adjust Window')}
  • @@ -157,6 +160,13 @@ class Header: Reactor.Component {
  • {svg_checkmark}{translate('Balanced')}
  • {svg_checkmark}{translate('Optimize reaction time')}
  • {svg_checkmark}{translate('Custom')}
  • + {show_codec ?
    +
    +
  • {svg_checkmark}Auto
  • +
  • {svg_checkmark}VP9
  • + {codecs[0] ?
  • {svg_checkmark}H264
  • : ""} + {codecs[1] ?
  • {svg_checkmark}H265
  • : ""} +
    : ""}
  • {svg_checkmark}{translate('Show remote cursor')}
  • {svg_checkmark}{translate('Show quality monitor')}
  • @@ -311,7 +321,7 @@ class Header: Reactor.Component { } } - event click $(menu#display-options>li) (_, me) { + event click $(menu#display-options li) (_, me) { if (me.id == "custom") { handle_custom_image_quality(); } else if (me.id == "privacy-mode") { @@ -328,6 +338,9 @@ class Header: Reactor.Component { } else if (type == "view-style") { handler.save_view_style(me.id); adaptDisplay(); + } else if (type == "codec-preference") { + handler.set_option("codec-preference", me.id); + handler.change_prefer_codec(); } toggleMenuState(); } @@ -355,7 +368,10 @@ function toggleMenuState() { var s = handler.get_view_style(); if (!s) s = "original"; values.push(s); - for (var el in $$(menu#display-options>li)) { + var c = handler.get_option("codec-preference"); + if (!c) c = "auto"; + values.push(c); + for (var el in $$(menu#display-options li)) { el.attributes.toggleClass("selected", values.indexOf(el.id) >= 0); } for (var id in ["show-remote-cursor", "show-quality-monitor", "disable-audio", "enable-file-transfer", "disable-clipboard", "lock-after-session-end"]) { diff --git a/src/ui/remote.rs b/src/ui/remote.rs index 4d941e1f..a738d7f8 100644 --- a/src/ui/remote.rs +++ b/src/ui/remote.rs @@ -231,6 +231,9 @@ impl sciter::EventHandler for Handler { fn get_remember(); fn peer_platform(); fn set_write_override(i32, i32, bool, bool, bool); + fn has_hwcodec(); + fn supported_hwcodec(); + fn change_prefer_codec(); } } @@ -595,6 +598,42 @@ impl Handler { true } + fn has_hwcodec(&self) -> bool { + #[cfg(not(feature = "hwcodec"))] + return false; + #[cfg(feature = "hwcodec")] + return true; + } + + fn supported_hwcodec(&self) -> Value { + #[cfg(feature = "hwcodec")] + { + let mut v = Value::array(0); + let decoder = scrap::codec::Decoder::video_codec_state(&self.id); + let mut h264 = decoder.score_h264 > 0; + let mut h265 = decoder.score_h265 > 0; + if let Some((encoding_264, encoding_265)) = self.lc.read().unwrap().supported_encoding { + h264 = h264 && encoding_264; + h265 = h265 && encoding_265; + } + v.push(h264); + v.push(h265); + v + } + #[cfg(not(feature = "hwcodec"))] + { + let mut v = Value::array(0); + v.push(false); + v.push(false); + v + } + } + + fn change_prefer_codec(&self) { + let msg = self.lc.write().unwrap().change_prefer_codec(); + self.send(Data::Message(msg)); + } + fn t(&self, name: String) -> String { crate::client::translate(name) } From 23deae0e523557e9bfbb8fe0e48322a9f7505bd7 Mon Sep 17 00:00:00 2001 From: 21pages Date: Tue, 19 Jul 2022 18:14:34 +0800 Subject: [PATCH 07/17] hwcodec: remove bad MY_DECODER_STATE When reset, the new of the decoder will be after it's drop Signed-off-by: 21pages --- libs/scrap/src/common/codec.rs | 36 ++++++++------------------------ libs/scrap/src/common/hwcodec.rs | 2 +- 2 files changed, 10 insertions(+), 28 deletions(-) diff --git a/libs/scrap/src/common/codec.rs b/libs/scrap/src/common/codec.rs index 1a18a79c..f0bd1c5f 100644 --- a/libs/scrap/src/common/codec.rs +++ b/libs/scrap/src/common/codec.rs @@ -25,7 +25,6 @@ use hbb_common::{ #[cfg(feature = "hwcodec")] lazy_static::lazy_static! { static ref PEER_DECODER_STATES: Arc>> = Default::default(); - static ref MY_DECODER_STATE: Arc> = Default::default(); } const SCORE_VPX: i32 = 90; @@ -238,25 +237,18 @@ impl Encoder { } } -#[cfg(feature = "hwcodec")] -impl Drop for Decoder { - fn drop(&mut self) { - *MY_DECODER_STATE.lock().unwrap() = VideoCodecState { - score_vpx: SCORE_VPX, - ..Default::default() - }; - } -} - impl Decoder { pub fn video_codec_state(_id: &str) -> VideoCodecState { - // video_codec_state is mainted by creation and destruction of Decoder. - // It has been ensured to use after Decoder's creation. #[cfg(feature = "hwcodec")] if check_hwcodec_config() { - let mut state = MY_DECODER_STATE.lock().unwrap(); - state.perfer = Self::codec_preference(_id).into(); - state.clone() + let best = HwDecoder::best(); + VideoCodecState { + score_vpx: SCORE_VPX, + score_h264: best.h264.map_or(0, |c| c.score), + score_h265: best.h265.map_or(0, |c| c.score), + perfer: Self::codec_preference(_id).into(), + ..Default::default() + } } else { return VideoCodecState { score_vpx: SCORE_VPX, @@ -272,23 +264,13 @@ impl Decoder { pub fn new(config: DecoderCfg) -> Decoder { let vpx = VpxDecoder::new(config.vpx).unwrap(); - let decoder = Decoder { + Decoder { vpx, #[cfg(feature = "hwcodec")] hw: HwDecoder::new_decoders(), #[cfg(feature = "hwcodec")] i420: vec![], - }; - - #[cfg(feature = "hwcodec")] - { - let mut state = MY_DECODER_STATE.lock().unwrap(); - state.score_vpx = SCORE_VPX; - state.score_h264 = decoder.hw.h264.as_ref().map_or(0, |d| d.info.score); - state.score_h265 = decoder.hw.h265.as_ref().map_or(0, |d| d.info.score); } - - decoder } pub fn handle_video_frame( diff --git a/libs/scrap/src/common/hwcodec.rs b/libs/scrap/src/common/hwcodec.rs index c2c85395..c065d811 100644 --- a/libs/scrap/src/common/hwcodec.rs +++ b/libs/scrap/src/common/hwcodec.rs @@ -178,7 +178,7 @@ pub struct HwDecoders { } impl HwDecoder { - fn best() -> CodecInfos { + pub fn best() -> CodecInfos { get_config(CFG_KEY_DECODER).unwrap_or(CodecInfos { h264: None, h265: None, From 9ab955bb8eaac10f01ad023113f43c9fa8a1570e Mon Sep 17 00:00:00 2001 From: tom Date: Thu, 21 Jul 2022 16:07:19 +0800 Subject: [PATCH 08/17] enable serde feature of bytes, modify struct WriteBlock using Bytes --- Cargo.toml | 2 +- libs/hbb_common/Cargo.toml | 2 +- src/ipc.rs | 3 ++- src/server/connection.rs | 6 +++--- src/ui/cm.rs | 2 +- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6237afe4..e8487546 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -55,7 +55,7 @@ rpassword = "7.0" base64 = "0.13" sysinfo = "0.24" num_cpus = "1.13" -bytes = "1.2" +bytes = { version = "1.2", features = ["serde"] } default-net = "0.11.0" wol-rs = "0.9.1" diff --git a/libs/hbb_common/Cargo.toml b/libs/hbb_common/Cargo.toml index 8d34709f..027aefe7 100644 --- a/libs/hbb_common/Cargo.toml +++ b/libs/hbb_common/Cargo.toml @@ -11,7 +11,7 @@ protobuf = { version = "3.1", features = ["with-bytes"] } tokio = { version = "1.20", features = ["full"] } tokio-util = { version = "0.7", features = ["full"] } futures = "0.3" -bytes = "1.2" +bytes = { version = "1.2", features = ["serde"] } log = "0.4" env_logger = "0.9" socket2 = { version = "0.3", features = ["reuseport"] } diff --git a/src/ipc.rs b/src/ipc.rs index 7df06cd2..532722e3 100644 --- a/src/ipc.rs +++ b/src/ipc.rs @@ -17,6 +17,7 @@ use parity_tokio_ipc::{ }; use serde_derive::{Deserialize, Serialize}; use std::{collections::HashMap, sync::atomic::Ordering}; +use bytes::Bytes; #[cfg(not(windows))] use std::{fs::File, io::prelude::*}; @@ -63,7 +64,7 @@ pub enum FS { WriteBlock { id: i32, file_num: i32, - data: Vec, + data: Bytes, compressed: bool, }, WriteDone { diff --git a/src/server/connection.rs b/src/server/connection.rs index 10a1786f..f4ed9da2 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -1063,7 +1063,7 @@ impl Connection { self.send_fs(ipc::FS::WriteBlock { id: block.id, file_num: block.file_num, - data: block.data.into(), + data: block.data, compressed: block.compressed, }); } @@ -1363,8 +1363,8 @@ async fn start_ipc( file_num, data, compressed}) = data { - stream.send(&Data::FS(ipc::FS::WriteBlock{id, file_num, data: Vec::new(), compressed})).await?; - stream.send_raw(data).await?; + stream.send(&Data::FS(ipc::FS::WriteBlock{id, file_num, data: Bytes::new(), compressed})).await?; + stream.send_raw(data.into()).await?; } else { stream.send(&data).await?; } diff --git a/src/ui/cm.rs b/src/ui/cm.rs index 1c2b36a9..c1acb692 100644 --- a/src/ui/cm.rs +++ b/src/ui/cm.rs @@ -263,7 +263,7 @@ impl ConnectionManager { FileTransferBlock { id, file_num, - data: data.into(), + data, compressed, ..Default::default() }, From e811d5f18b7df0963b272f2831561e261634362a Mon Sep 17 00:00:00 2001 From: tom Date: Thu, 21 Jul 2022 17:54:07 +0800 Subject: [PATCH 09/17] modify argument of ConnectionTmpl::send_raw() --- src/ipc.rs | 4 ++-- src/server/connection.rs | 2 +- src/ui/cm.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ipc.rs b/src/ipc.rs index 532722e3..f2765ebd 100644 --- a/src/ipc.rs +++ b/src/ipc.rs @@ -456,8 +456,8 @@ where } } - pub async fn send_raw(&mut self, data: Vec) -> ResultType<()> { - self.inner.send(bytes::Bytes::from(data)).await?; + pub async fn send_raw(&mut self, data: Bytes) -> ResultType<()> { + self.inner.send(data).await?; Ok(()) } diff --git a/src/server/connection.rs b/src/server/connection.rs index f4ed9da2..9c326575 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -1364,7 +1364,7 @@ async fn start_ipc( data, compressed}) = data { stream.send(&Data::FS(ipc::FS::WriteBlock{id, file_num, data: Bytes::new(), compressed})).await?; - stream.send_raw(data.into()).await?; + stream.send_raw(data).await?; } else { stream.send(&data).await?; } diff --git a/src/ui/cm.rs b/src/ui/cm.rs index c1acb692..fe5738c3 100644 --- a/src/ui/cm.rs +++ b/src/ui/cm.rs @@ -590,7 +590,7 @@ async fn start_pa() { } else { buf.clone() }; - if let Err(err) = stream.send_raw(out).await { + if let Err(err) = stream.send_raw(out.into()).await { log::error!("Failed to send audio data:{}", err); break; } From d19a8fdc4307f44f95364eb3852af855cc6cd003 Mon Sep 17 00:00:00 2001 From: fufesou Date: Thu, 21 Jul 2022 20:04:39 +0800 Subject: [PATCH 10/17] fix_capturer_trait_name_shadowing: build win Signed-off-by: fufesou --- libs/scrap/examples/capture_mag.rs | 2 +- libs/scrap/examples/ffplay.rs | 2 +- libs/scrap/examples/record-screen.rs | 2 +- libs/scrap/examples/screenshot.rs | 2 +- libs/scrap/src/common/android.rs | 6 ++- libs/scrap/src/common/dxgi.rs | 62 ++++++++++++++++++---------- libs/scrap/src/common/linux.rs | 19 +++++---- libs/scrap/src/common/mod.rs | 10 +++++ libs/scrap/src/common/quartz.rs | 8 +++- libs/scrap/src/common/wayland.rs | 14 ++++--- libs/scrap/src/common/x11.rs | 14 ++++--- src/server/video_service.rs | 54 +----------------------- src/server/wayland.rs | 44 ++++++++++++-------- 13 files changed, 122 insertions(+), 117 deletions(-) diff --git a/libs/scrap/examples/capture_mag.rs b/libs/scrap/examples/capture_mag.rs index c0505141..81b2d857 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 2c685b93..b8fe16e3 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 e099a8d1..5df97838 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 b6bf8a1d..636768eb 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 8322da3c..e15752d8 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 855ac7ac..963f39de 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 8498ab7f..866fb851 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 9115bfd3..4a9ade58 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 46ac1b56..b4ecf898 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 05bb0874..e33cbe74 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 c1a25c8d..791514de 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 e6ea713a..2fb9f3dc 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 e84be3f7..1ac2c18b 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 { From 04c8340b3b87c64edcb14637e9fc97b35ed1ef78 Mon Sep 17 00:00:00 2001 From: fufesou Date: Thu, 21 Jul 2022 20:53:31 +0800 Subject: [PATCH 11/17] fix_capturer_trait_name_shadowing: update Cargo.lock Signed-off-by: fufesou --- Cargo.lock | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c9127211..be6c1391 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", From e06c37338914f9752a3c2e025cd0a3cb2f2697eb Mon Sep 17 00:00:00 2001 From: fufesou Date: Thu, 21 Jul 2022 21:58:42 +0800 Subject: [PATCH 12/17] fix_cmd_window: do not show cmd prompt window Signed-off-by: fufesou --- Cargo.lock | 8 ++++++-- src/server/video_service.rs | 6 ++++-- src/ui/win_privacy.rs | 6 +++++- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c9127211..be6c1391 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/src/server/video_service.rs b/src/server/video_service.rs index e6ea713a..362fe15c 100644 --- a/src/server/video_service.rs +++ b/src/server/video_service.rs @@ -393,8 +393,10 @@ fn get_capturer(use_yuv: bool) -> ResultType { #[cfg(windows)] let mut captuerer_privacy_mode_id = privacy_mode_id; #[cfg(windows)] - if crate::ui::win_privacy::is_process_consent_running()? { - captuerer_privacy_mode_id = 0; + if captuerer_privacy_mode_id != 0 { + if crate::ui::win_privacy::is_process_consent_running()? { + captuerer_privacy_mode_id = 0; + } } log::debug!( "Try create capturer with captuerer privacy mode id {}", diff --git a/src/ui/win_privacy.rs b/src/ui/win_privacy.rs index 0bbb040e..9944bf26 100644 --- a/src/ui/win_privacy.rs +++ b/src/ui/win_privacy.rs @@ -5,6 +5,7 @@ use crate::{ use hbb_common::{allow_err, bail, lazy_static, log, tokio, ResultType}; use std::{ ffi::CString, + os::windows::process::CommandExt, sync::Mutex, time::{Duration, Instant}, }; @@ -24,7 +25,9 @@ use winapi::{ CreateProcessAsUserW, GetCurrentThreadId, QueueUserAPC, ResumeThread, PROCESS_INFORMATION, STARTUPINFOW, }, - winbase::{WTSGetActiveConsoleSessionId, CREATE_SUSPENDED, DETACHED_PROCESS}, + winbase::{ + WTSGetActiveConsoleSessionId, CREATE_NO_WINDOW, CREATE_SUSPENDED, DETACHED_PROCESS, + }, winnt::{MEM_COMMIT, PAGE_READWRITE}, winuser::*, }, @@ -317,6 +320,7 @@ fn wait_find_privacy_hwnd(msecs: u128) -> ResultType { pub fn is_process_consent_running() -> ResultType { let output = std::process::Command::new("cmd") .args(&["/C", "tasklist | findstr consent.exe"]) + .creation_flags(CREATE_NO_WINDOW) .output()?; Ok(output.status.success() && !output.stdout.is_empty()) } From 9ee2d750f82f3e672a9b6374ddfe8f548775c7a6 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Thu, 21 Jul 2022 22:29:26 +0800 Subject: [PATCH 13/17] fix compile error --- libs/scrap/src/common/android.rs | 2 +- libs/scrap/src/common/quartz.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/scrap/src/common/android.rs b/libs/scrap/src/common/android.rs index e15752d8..94918871 100644 --- a/libs/scrap/src/common/android.rs +++ b/libs/scrap/src/common/android.rs @@ -34,7 +34,7 @@ impl Capturer { } } -impl TraitCapturer for Capturer { +impl crate::TraitCapturer for Capturer { fn set_use_yuv(&mut self, _use_yuv: bool) {} fn frame<'a>(&'a mut self, _timeout: Duration) -> io::Result> { diff --git a/libs/scrap/src/common/quartz.rs b/libs/scrap/src/common/quartz.rs index b4ecf898..6e29c244 100644 --- a/libs/scrap/src/common/quartz.rs +++ b/libs/scrap/src/common/quartz.rs @@ -52,7 +52,7 @@ impl Capturer { } } -impl TraitCapturer for Capturer { +impl crate::TraitCapturer for Capturer { fn set_use_yuv(&mut self, use_yuv: bool) { self.use_yuv = use_yuv; } From bb1289dbc3c00267a613ac4a94be541e90e47785 Mon Sep 17 00:00:00 2001 From: Fabian Schillig Date: Thu, 21 Jul 2022 18:31:59 +0200 Subject: [PATCH 14/17] Update de.rs --- src/lang/de.rs | 284 ++++++++++++++++++++++++------------------------- 1 file changed, 142 insertions(+), 142 deletions(-) diff --git a/src/lang/de.rs b/src/lang/de.rs index c9cd243f..671bcae9 100644 --- a/src/lang/de.rs +++ b/src/lang/de.rs @@ -6,14 +6,14 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("desk_tip", "Mit dieser ID und diesem Passwort können Sie auf Ihren Desktop zugreifen."), ("Password", "Passwort"), ("Ready", "Bereit"), - ("Established", "Etabliert"), + ("Established", "Verbunden"), ("connecting_status", "Verbinden mit dem RustDesk-Netzwerk..."), - ("Enable Service", "Verbindungsserver einschalten"), - ("Start Service", "Starte Verbindungsserver"), - ("Service is running", "Dienst läuft"), - ("Service is not running", "Der Verbindungsserver läuft nicht"), + ("Enable Service", "Verbindungsserver aktivieren"), + ("Start Service", "Starte Vermittlungsdienst"), + ("Service is running", "Vermittlungsdienst aktiv"), + ("Service is not running", "Vermittlungsdienst deaktiviert"), ("not_ready_status", "Nicht bereit. Bitte überprüfen Sie Ihre Verbindung"), - ("Control Remote Desktop", "Entfernten Desktop steuern"), + ("Control Remote Desktop", "Entfernten PC steuern"), ("Transfer File", "Datei übertragen"), ("Connect", "Verbinden"), ("Recent Sessions", "Letzte Sitzungen"), @@ -21,49 +21,49 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Confirmation", "Bestätigung"), ("TCP Tunneling", "TCP Tunneln"), ("Remove", "Entfernen"), - ("Refresh random password", "Zufälliges Passwort aktualisieren"), - ("Set your own password", "Legen Sie Ihr eigenes Passwort fest"), - ("Enable Keyboard/Mouse", "Tastatur/Maus einschalten"), - ("Enable Clipboard", "Zwischenablage einschalten"), + ("Refresh random password", "Neues zufälliges Passwort"), + ("Set your own password", "Eigenes Passwort setzen"), + ("Enable Keyboard/Mouse", "Tastatur/Maus aktivieren"), + ("Enable Clipboard", "Zwischenablage aktivieren"), ("Enable File Transfer", "Dateiübertragung aktivieren"), - ("Enable TCP Tunneling", "TCP-Tunneling einschalten"), - ("IP Whitelisting", "IP Freigabeliste"), - ("ID/Relay Server", "ID/Verbindungsserver"), - ("Stop service", "Verbindungsserver ausschalten"), - ("Change ID", "ID wechseln"), + ("Enable TCP Tunneling", "TCP-Tunneln aktivieren"), + ("IP Whitelisting", "IP-Whitelist"), + ("ID/Relay Server", "ID/Vermittlungsserver"), + ("Stop service", "Vermittlungsdienst deaktivieren"), + ("Change ID", "ID ändern"), ("Website", "Webseite"), ("About", "Über"), ("Mute", "Stummschalten"), ("Audio Input", "Audio-Eingang"), - ("Enhancements", ""), - ("Hardware Codec", ""), - ("Adaptive Bitrate", ""), + ("Enhancements", "Verbesserungen"), + ("Hardware Codec", "Hardware-Codec"), + ("Adaptive Bitrate", "Adaptive Bitrate"), ("ID Server", "ID Server"), - ("Relay Server", "Verbindungsserver Server"), - ("API Server", "API Server"), + ("Relay Server", "Vermittlungsserver"), + ("API Server", "API-Server"), ("invalid_http", "Muss mit http:// oder https:// beginnen"), ("Invalid IP", "Ungültige IP-Adresse"), - ("id_change_tip", "Nur die Zeichen a-z, A-Z, 0-9 und _ (Unterstrich) sind erlaubt. Der erste Buchstabe muss a-z, A-Z sein. Länge zwischen 6 und 16."), + ("id_change_tip", "Nur die Zeichen a-z, A-Z, 0-9 und _ (Unterstrich) sind erlaubt. Der erste Buchstabe muss a-z, A-Z sein, Länge zwischen 6 und 16."), ("Invalid format", "Ungültiges Format"), - ("server_not_support", "Noch nicht vom Server unterstützt"), + ("server_not_support", "Diese Funktion wird noch nicht vom Server unterstützt"), ("Not available", "Nicht verfügbar"), ("Too frequent", "Zu häufig"), ("Cancel", "Abbrechen"), ("Skip", "Überspringen"), ("Close", "Schließen"), - ("Retry", "Nochmal versuchen"), + ("Retry", "Erneut versuchen"), ("OK", "OK"), ("Password Required", "Passwort erforderlich"), - ("Please enter your password", "Bitte geben Sie Ihr Passwort ein"), + ("Please enter your password", "Bitte geben Sie das Passwort des entfernten PCs ein."), ("Remember password", "Passwort merken"), ("Wrong Password", "Falsches Passwort"), - ("Do you want to enter again?", "Möchten Sie erneut teilnehmen?"), + ("Do you want to enter again?", "Erneut verbinden?"), ("Connection Error", "Verbindungsfehler"), ("Error", "Fehler"), - ("Reset by the peer", "Zurücksetzen durch die Gegenstelle"), + ("Reset by the peer", "Verbindung wurde von der Gegenstelle zurückgesetzt"), ("Connecting...", "Verbinden..."), ("Connection in progress. Please wait.", "Die Verbindung wird hergestellt. Bitte warten Sie."), - ("Please try 1 minute later", "Bitte versuchen Sie es 1 Minute später"), + ("Please try 1 minute later", "Bitte versuchen Sie es später erneut"), ("Login Error", "Anmeldefehler"), ("Successful", "Erfolgreich"), ("Connected, waiting for image...", "Verbunden, warten auf Bild..."), @@ -75,92 +75,92 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Receive", "Empfangen"), ("Send", "Senden"), ("Refresh File", "Datei aktualisieren"), - ("Local", "Lokaler"), - ("Remote", "Entfernter"), + ("Local", "Lokal"), + ("Remote", "Entfernt"), ("Remote Computer", "Entfernter Computer"), - ("Local Computer", "Lokaler Computer"), + ("Local Computer", "Dieser Computer"), ("Confirm Delete", "Löschen bestätigen"), ("Delete", "Löschen"), ("Properties", "Eigenschaften"), ("Multi Select", "Mehrfachauswahl"), - ("Empty Directory", "Leeres Verzeichnis"), - ("Not an empty directory", "Kein leeres Verzeichnis"), + ("Empty Directory", "Leerer Ordner"), + ("Not an empty directory", "Ordner nicht leer"), ("Are you sure you want to delete this file?", "Sind Sie sicher, dass Sie diese Datei löschen wollen?"), - ("Are you sure you want to delete this empty directory?", "Sind Sie sicher, dass Sie dieses leere Verzeichnis löschen möchten?"), - ("Are you sure you want to delete the file of this directory?", "Sind Sie sicher, dass Sie die Datei dieses Verzeichnisses löschen möchten?"), - ("Do this for all conflicts", "Dies gilt für alle Konflikte"), + ("Are you sure you want to delete this empty directory?", "Sind Sie sicher, dass Sie diesen leeren Ordner löschen möchten?"), + ("Are you sure you want to delete the file of this directory?", "Sind Sie sicher, dass Sie die Datei dieses Ordners löschen möchten?"), + ("Do this for all conflicts", "Für alle Konflikte merken"), ("This is irreversible!", "Dies ist irreversibel!"), ("Deleting", "Löschen"), ("files", "Dateien"), ("Waiting", "Warten"), ("Finished", "Fertiggestellt"), ("Speed", "Geschwindigkeit"), - ("Custom Image Quality", "Individuelle Bildqualität"), + ("Custom Image Quality", "Benutzerdefinierte Bildqualität"), ("Privacy mode", "Datenschutz-Modus"), ("Block user input", "Benutzereingaben blockieren"), ("Unblock user input", "Benutzereingaben freigeben"), ("Adjust Window", "Fenster anpassen"), ("Original", "Original"), - ("Shrink", "Geschrumpft"), - ("Stretch", "Gestreckt"), - ("Good image quality", "Gute Bildqualität"), + ("Shrink", "Verkleinern"), + ("Stretch", "Strecken"), + ("Good image quality", "Schöner"), ("Balanced", "Ausgeglichen"), - ("Optimize reaction time", "Optimierte Reaktionszeit"), + ("Optimize reaction time", "Schneller"), ("Custom", "Benutzerdefiniert"), - ("Show remote cursor", "Ferngesteuerten Cursor anzeigen"), - ("Show quality monitor", ""), + ("Show remote cursor", "Entfernten Cursor anzeigen"), + ("Show quality monitor", "Qualitätsüberwachung anzeigen"), ("Disable clipboard", "Zwischenablage deaktivieren"), ("Lock after session end", "Sperren nach Sitzungsende"), ("Insert", "Einfügen"), - ("Insert Lock", "Sperre einfügen"), + ("Insert Lock", "Win+L (Sperren) senden"), ("Refresh", "Aktualisieren"), - ("ID does not exist", "Die ID existiert nicht"), - ("Failed to connect to rendezvous server", "Verbindung zum Verbindungsserver fehlgeschlagen"), - ("Please try later", "Bitte versuchen Sie es später"), - ("Remote desktop is offline", "Entfernter Desktop ist offline"), - ("Key mismatch", "Schlüssel nicht übereinstimmend"), + ("ID does not exist", "Diese ID existiert nicht"), + ("Failed to connect to rendezvous server", "Verbindung zum Vermittlungsserver fehlgeschlagen"), + ("Please try later", "Bitte versuchen Sie es später erneut"), + ("Remote desktop is offline", "Entfernter PC ist offline"), + ("Key mismatch", "Schlüssel stimmt nicht mit Serverschlüssel überein"), ("Timeout", "Zeitüberschreitung"), - ("Failed to connect to relay server", "Verbindung zum Verbindungsserver fehlgeschlagen"), - ("Failed to connect via rendezvous server", "Verbindung über rendezvous server fehlgeschlagen"), - ("Failed to connect via relay server", "Verbindung über den Verbindungsserver ist fehlgeschlagen"), - ("Failed to make direct connection to remote desktop", "Direkte Verbindung zum Entfernten-Desktop konnte nicht hergestellt werden"), + ("Failed to connect to relay server", "Verbindung zum Vermittlungsserver fehlgeschlagen"), + ("Failed to connect via rendezvous server", "Verbindung über Vermittlungsserver ist fehlgeschlagen"), + ("Failed to connect via relay server", "Verbindung über Relay-Server ist fehlgeschlagen"), + ("Failed to make direct connection to remote desktop", "Direkte Verbindung zum entfernten PC fehlgeschlagen"), ("Set Password", "Passwort festlegen"), ("OS Password", "Betriebssystem-Passwort"), ("install_tip", "Aufgrund der UAC kann RustDesk in manchen Fällen nicht ordnungsgemäß auf der Gegenseite funktionieren. Um UAC zu vermeiden, klicken Sie bitte auf die Schaltfläche unten, um RustDesk auf dem System zu installieren"), - ("Click to upgrade", "Zum Upgrade anklicken"), + ("Click to upgrade", "Zum Aktualisieren anklicken"), ("Click to download", "Zum Herunterladen klicken"), ("Click to update", "Zum Aktualisieren klicken"), ("Configure", "Konfigurieren"), - ("config_acc", "Um Ihren Desktop aus der Ferne zu steuern, müssen Sie RustDesk \"Zugangs\" Rechte erteilen."), - ("config_screen", "Um aus der Ferne auf Ihren Desktop zugreifen zu können, müssen Sie RustDesk \"Bildschirm-Aufnahme\" Berechtigungen erteilen."), + ("config_acc", "Um Ihren PC aus der Ferne zu steuern, müssen Sie RustDesk Zugriffsrechte erteilen."), + ("config_screen", "Um aus der Ferne auf Ihren PC zugreifen zu können, müssen Sie RustDesk \"Bildschirm-Aufnahme\"-Berechtigung erteilen."), ("Installing ...", "Installiere ..."), ("Install", "Installieren"), - ("Installation", "Einrichtung"), - ("Installation Path", "Einrichtungs Pfad"), - ("Create start menu shortcuts", "Startmenü Verknüpfungen erstellen"), - ("Create desktop icon", "Desktop Symbol erstellen"), - ("agreement_tip", "Wenn Sie die Einrichtung starten, akzeptieren Sie die Lizenzvereinbarung"), - ("Accept and Install", "Akzeptieren und installieren"), + ("Installation", "Installation"), + ("Installation Path", "Installationspfad"), + ("Create start menu shortcuts", "Verknüpfung im Startmenü erstellen"), + ("Create desktop icon", "Desktop-Verknüpfung erstellen"), + ("agreement_tip", "Durch die Installation akzeptieren Sie die Lizenzvereinbarung"), + ("Accept and Install", "Akzeptieren und Installieren"), ("End-user license agreement", "Lizenzvereinbarung für Endbenutzer"), - ("Generating ...", "Generierung ..."), - ("Your installation is lower version.", "Ihre Installation ist eine niedrigere Version."), - ("not_close_tcp_tip", "Schließen Sie dieses Fenster nicht, während Sie den Tunnel benutzen."), - ("Listening ...", "Hören ..."), - ("Remote Host", "Entfernter Rechner"), + ("Generating ...", "Generiere..."), + ("Your installation is lower version.", "Ihre Installation ist älter."), + ("not_close_tcp_tip", "Schließen Sie dieses Fenster nicht, solange Sie den Tunnel benutzen."), + ("Listening ...", "Höre..."), + ("Remote Host", "Entfernter PC"), ("Remote Port", "Entfernter Port"), ("Action", "Aktion"), ("Add", "Hinzufügen"), ("Local Port", "Lokaler Port"), - ("setup_server_tip", "Für eine schnellere Verbindung, richten Sie bitte Ihren eigenen Verbindungsserver ein"), + ("setup_server_tip", "Für eine schnellere Verbindung richten Sie bitte Ihren eigenen Verbindungsserver ein"), ("Too short, at least 6 characters.", "Zu kurz, mindestens 6 Zeichen."), - ("The confirmation is not identical.", "Die Bestätigung ist nicht identisch."), + ("The confirmation is not identical.", "Die Passwörter sind nicht identisch."), ("Permissions", "Berechtigungen"), ("Accept", "Akzeptieren"), ("Dismiss", "Ablehnen"), ("Disconnect", "Verbindung trennen"), - ("Allow using keyboard and mouse", "Erlaubt die Verwendung von Tastatur und Maus"), + ("Allow using keyboard and mouse", "Verwendung von Maus und Tastatur zulassen"), ("Allow using clipboard", "Verwendung der Zwischenablage zulassen"), - ("Allow hearing sound", "Erlaubt das Hören von Sound"), + ("Allow hearing sound", "System-Audio übertragen"), ("Allow file copy and paste", "Kopieren und Einfügen von Dateien zulassen"), ("Connected", "Verbunden"), ("Direct and encrypted connection", "Direkte und verschlüsselte Verbindung"), @@ -171,17 +171,17 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Enter your password", "Geben Sie Ihr Passwort ein"), ("Logging in...", "Anmeldung..."), ("Enable RDP session sharing", "RDP-Sitzungsfreigabe aktivieren"), - ("Auto Login", "Automatisches Login (nur gültig, wenn Sie \"Sperren nach Sitzungsende\" eingestellt haben)"), + ("Auto Login", "Automatisch anmelden (nur gültig, wenn Sie \"Sperren nach Sitzungsende\" aktiviert haben)"), ("Enable Direct IP Access", "Direkten IP-Zugang aktivieren"), ("Rename", "Umbenennen"), - ("Space", "Platz"), + ("Space", "Speicherplatz"), ("Create Desktop Shortcut", "Desktop-Verknüpfung erstellen"), ("Change Path", "Pfad ändern"), ("Create Folder", "Ordner erstellen"), ("Please enter the folder name", "Bitte geben Sie den Ordnernamen ein"), ("Fix it", "Reparieren"), ("Warning", "Warnung"), - ("Login screen using Wayland is not supported", "Anmeldebildschirm mit Wayland wird nicht unterstützt"), + ("Login screen using Wayland is not supported", "Anmeldebildschirm wird mit Wayland nicht unterstützt"), ("Reboot required", "Neustart erforderlich"), ("Unsupported display server ", "Nicht unterstützter Display-Server"), ("x11 expected", "X11 erwartet"), @@ -189,14 +189,14 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Settings", "Einstellungen"), ("Username", " Benutzername"), ("Invalid port", "Ungültiger Port"), - ("Closed manually by the peer", "Vom Peer manuell geschlossen"), - ("Enable remote configuration modification", "Änderung der Fernkonfiguration zulassen"), + ("Closed manually by the peer", "Von der Gegenstelle manuell geschlossen"), + ("Enable remote configuration modification", "Änderung der Konfiguration aus der Ferne zulassen"), ("Run without install", "Ohne Installation ausführen"), - ("Always connected via relay", "Immer über Verbindungsserver verbunden"), - ("Always connect via relay", "Verbindung immer über Verbindungsserver"), - ("whitelist_tip", "Nur IPs auf der Freigabeliste können auf mich zugreifen"), - ("Login", "Anmeldung"), - ("Logout", "Abmeldung"), + ("Always connected via relay", "Immer über Relay-Server verbunden"), + ("Always connect via relay", "Immer über Relay-Server verbinden"), + ("whitelist_tip", "Nur IPs auf der Whitelist können zugreifen"), + ("Login", "Anmelden"), + ("Logout", "Abmelden"), ("Tags", "Stichworte"), ("Search ID", "Suche ID"), ("Current Wayland display server is not supported", "Der aktuelle Wayland-Anzeigeserver wird nicht unterstützt"), @@ -205,100 +205,100 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Add Tag", "Stichwort hinzufügen"), ("Unselect all tags", "Alle Stichworte abwählen"), ("Network error", "Netzwerkfehler"), - ("Username missed", "Benutzername fehlt"), + ("Username missed", "Benutzername vergessen"), ("Password missed", "Passwort vergessen"), ("Wrong credentials", "Falsche Anmeldedaten"), ("Edit Tag", "Stichwort bearbeiten"), - ("Unremember Password", "Passwort nicht merken"), + ("Unremember Password", "Passwort vergessen"), ("Favorites", "Favoriten"), ("Add to Favorites", "Zu Favoriten hinzufügen"), - ("Remove from Favorites", "Entferne von Favoriten"), + ("Remove from Favorites", "Aus Favoriten entfernen"), ("Empty", "Leer"), ("Invalid folder name", "Ungültiger Ordnername"), ("Socks5 Proxy", "Socks5 Proxy"), ("Hostname", "Rechnername"), ("Discovered", "Gefunden"), - ("install_daemon_tip", "Um beim Booten zu starten, müssen Sie den Systemdienst installieren"), + ("install_daemon_tip", "Um mit System zu starten, muss der Systemdienst installiert sein"), ("Remote ID", "Entfernte ID"), ("Paste", "Einfügen"), ("Paste here?", "Hier einfügen?"), - ("Are you sure to close the connection?", "Sind Sie sicher, dass Sie die Verbindung schließen wollen?"), + ("Are you sure to close the connection?", "Möchten Sie diese Verbindung wirklich trennen?"), ("Download new version", "Neue Version herunterladen"), ("Touch mode", "Touch-Modus"), - ("Mouse mode", "Mouse-Modus"), - ("One-Finger Tap", "Ein Fingertipp"), - ("Left Mouse", "Linke Maus"), - ("One-Long Tap", "Tippen Sie mit einem Finger lang"), - ("Two-Finger Tap", "Zwei Finger tippen"), - ("Right Mouse", "Rechte Maus"), - ("One-Finger Move", "Eine Fingerbewegung"), - ("Double Tap & Move", "Doppeltippen und verschieben"), - ("Mouse Drag", "Maus ziehen"), - ("Three-Finger vertically", "Drei Finger vertikal"), + ("Mouse mode", "Maus-Modus"), + ("One-Finger Tap", "1-Finger-Tipp"), + ("Left Mouse", "Linksklick"), + ("One-Long Tap", "1-Finger-Halten"), + ("Two-Finger Tap", "2-Finger-Tipp"), + ("Right Mouse", "Rechtsklick"), + ("One-Finger Move", "Einen Finger bewegen"), + ("Double Tap & Move", "Doppeltippen und bewegen"), + ("Mouse Drag", "Maus bewegen"), + ("Three-Finger vertically", "Drei Finger vertikal bewegen"), ("Mouse Wheel", "Mausrad"), - ("Two-Finger Move", "Zwei Finger Bewegung"), - ("Canvas Move", "Leinwand bewegen"), - ("Pinch to Zoom", "Zum Zoomen kneifen"), - ("Canvas Zoom", "Leinwand Zoom"), - ("Reset canvas", "Anzeige zurücksetzen"), - ("No permission of file transfer", "Keine Erlaubnis zur Dateiübertragung"), - ("Note", "Notiz"), + ("Two-Finger Move", "Zwei Finger bewegen"), + ("Canvas Move", "Sichtfeld bewegen"), + ("Pinch to Zoom", "2-Finger-Zoom"), + ("Canvas Zoom", "Sichtfeld-Zoom"), + ("Reset canvas", "Sichtfeld zurücksetzen"), + ("No permission of file transfer", "Keine Dateizugriff-Berechtigung"), + ("Note", "Anmerkung"), ("Connection", "Verbindung"), ("Share Screen", "Bildschirm freigeben"), - ("CLOSE", "NAH DRAN"), - ("OPEN", "OFFEN"), - ("Chat", "Plaudern"), + ("CLOSE", "DEAKTIV."), + ("OPEN", "AKTIVIER."), + ("Chat", "Chat"), ("Total", "Gesamt"), - ("items", "Artikel"), + ("items", "Einträge"), ("Selected", "Ausgewählt"), - ("Screen Capture", "Bildschirmaufnahme"), - ("Input Control", "Eingabesteuerung"), - ("Audio Capture", "Audioaufnahme"), - ("File Connection", "Dateiverbindung"), + ("Screen Capture", "Bildschirmzugr."), + ("Input Control", "Eingabezugriff"), + ("Audio Capture", "Audiozugriff"), + ("File Connection", "Dateizugriff"), ("Screen Connection", "Bildschirmanschluss"), - ("Do you accept?", "Akzeptieren Sie?"), + ("Do you accept?", "Verbindung zulassen?"), ("Open System Setting", "Systemeinstellung öffnen"), ("How to get Android input permission?", "Wie erhalte ich eine Android-Eingabeberechtigung?"), - ("android_input_permission_tip1", "Damit ein Remote-Gerät Ihr Android-Gerät per Maus oder Berührung steuern kann, müssen Sie RustDesk erlauben, den Dienst \"Barrierefreiheit\" zu verwenden."), + ("android_input_permission_tip1", "Damit ein Remote-Gerät Ihr Android-Gerät steuern kann, müssen Sie RustDesk erlauben, den Dienst \"Barrierefreiheit\" zu verwenden."), ("android_input_permission_tip2", "Bitte gehen Sie zur nächsten Systemeinstellungsseite, suchen und geben Sie [Installierte Dienste] ein, schalten Sie den Dienst [RustDesk Input] ein."), - ("android_new_connection_tip", "Es wurde eine neue Steuerungsanforderung empfangen, die Ihr aktuelles Gerät steuern möchte."), - ("android_service_will_start_tip", "Durch das Einschalten der Bildschirmaufnahme wird der Dienst automatisch gestartet, sodass andere Geräte eine Verbindung von diesem Gerät anfordern können."), - ("android_stop_service_tip", "Durch das Schließen des Dienstes werden automatisch alle hergestellten Verbindungen geschlossen."), - ("android_version_audio_tip", "Die aktuelle Android-Version unterstützt keine Audioaufnahme, bitte aktualisieren Sie auf Android 10 oder höher."), - ("android_start_service_tip", "Tippen Sie auf [Dienst starten] oder ÖFFNEN Sie die Berechtigung [Bildschirmaufnahme], um den Bildschirmfreigabedienst zu starten."), + ("android_new_connection_tip", "möchte ihr Gerät steuern."), + ("android_service_will_start_tip", "Durch das Aktivieren der Bildschirmfreigabe wird der Dienst automatisch gestartet, sodass andere Geräte dieses Android-Gerät steuern können."), + ("android_stop_service_tip", "Durch das Deaktivieren des Dienstes werden automatisch alle hergestellten Verbindungen getrennt."), + ("android_version_audio_tip", "Ihre Android-Version unterstützt keine Audioaufnahme, bitte aktualisieren Sie auf Android 10 oder höher, falls möglich."), + ("android_start_service_tip", "Tippen Sie auf [Dienst aktivieren] oder aktivieren Sie die Berechtigung [Bildschirmzugr.], um den Bildschirmfreigabedienst zu starten."), ("Account", "Konto"), ("Overwrite", "Überschreiben"), - ("This file exists, skip or overwrite this file?", "Diese Datei existiert, diese Datei überspringen oder überschreiben?"), - ("Quit", "Aufhören"), - ("doc_mac_permission", "https://rustdesk.com/docs/en/manual/mac/#enable-permissions"), + ("This file exists, skip or overwrite this file?", "Diese Datei existiert; überspringen oder überschreiben?"), + ("Quit", "Beenden"), + ("doc_mac_permission", "https://rustdesk.com/docs/de/manual/mac/#berechtigungen-aktivieren"), ("Help", "Hilfe"), - ("Failed", "Gescheitert"), + ("Failed", "Fehlgeschlagen"), ("Succeeded", "Erfolgreich"), - ("Someone turns on privacy mode, exit", "Jemand aktiviert den Datenschutzmodus, beenden"), + ("Someone turns on privacy mode, exit", "Jemand hat den Datenschutzmodus aktiviert, beende..."), ("Unsupported", "Nicht unterstützt"), - ("Peer denied", "Peer verweigert"), + ("Peer denied", "Die Gegenstelle hat die Verbindung abgelehnt"), ("Please install plugins", "Bitte installieren Sie Plugins"), - ("Peer exit", "Peer-Ausgang"), + ("Peer exit", "Die Gegenstelle hat die Verbindung getrennt"), ("Failed to turn off", "Ausschalten fehlgeschlagen"), ("Turned off", "Ausgeschaltet"), - ("In privacy mode", "im Datenschutzmodus"), - ("Out privacy mode", "Datenschutzmodus aus"), + ("In privacy mode", "Datenschutzmodus aktivieren"), + ("Out privacy mode", "Datenschutzmodus deaktivieren"), ("Language", "Sprache"), - ("Keep RustDesk background service", ""), - ("Ignore Battery Optimizations", ""), - ("android_open_battery_optimizations_tip", ""), - ("Random Password After Session", ""), - ("Keep", ""), - ("Update", ""), - ("Disable", ""), - ("Onetime Password", ""), - ("Verification Method", ""), - ("Enable security password", ""), - ("Enable random password", ""), - ("Enable onetime password", ""), - ("Disable onetime password", ""), - ("Activate onetime password", ""), - ("Set security password", ""), - ("Connection not allowed", ""), + ("Keep RustDesk background service", "RustDesk im Hintergrund ausführen"), + ("Ignore Battery Optimizations", "Batterieoptimierung ignorieren"), + ("android_open_battery_optimizations_tip", "Möchten Sie die Batterieopimierungs-Einstellungen öffnen?"), + ("Random Password After Session", "Neues zufälliges Passwort nach jeder Sitzung"), + ("Keep", "Behalten"), + ("Update", "Aktualisieren"), + ("Disable", "Deaktivieren"), + ("Onetime Password", "Einmal-Passwort"), + ("Verification Method", "Überprüfungsmethode"), + ("Enable security password", "Sicheres Passwort aktivieren"), + ("Enable random password", "Zufälliges Passwort aktivieren"), + ("Enable onetime password", "Einmal-Passwort aktivieren"), + ("Disable onetime password", "Einmal-Passwort deaktivieren"), + ("Activate onetime password", "Einmal-Passwort aktivieren"), + ("Set security password", "Sicheres Passwort setzen"), + ("Connection not allowed", "Verbindung abgelehnt"), ].iter().cloned().collect(); } From b55fc35d83e1f2bad227711dd8f1a5d4224ffc53 Mon Sep 17 00:00:00 2001 From: 21pages Date: Fri, 22 Jul 2022 09:13:40 +0800 Subject: [PATCH 15/17] hwcodec: fix compile error Signed-off-by: 21pages --- libs/scrap/src/common/hwcodec.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/scrap/src/common/hwcodec.rs b/libs/scrap/src/common/hwcodec.rs index c065d811..7431bc95 100644 --- a/libs/scrap/src/common/hwcodec.rs +++ b/libs/scrap/src/common/hwcodec.rs @@ -7,7 +7,7 @@ use hbb_common::{ config::HwCodecConfig, lazy_static, log, message_proto::{EncodedVideoFrame, EncodedVideoFrames, Message, VideoFrame}, - ResultType, + ResultType, bytes::Bytes, }; use hwcodec::{ decode::{DecodeContext, DecodeFrame, Decoder}, @@ -91,7 +91,7 @@ impl EncoderApi for HwEncoder { let mut frames = Vec::new(); for frame in self.encode(frame).with_context(|| "Failed to encode")? { frames.push(EncodedVideoFrame { - data: frame.data, + data: Bytes::from(frame.data), pts: frame.pts as _, ..Default::default() }); From af60042e33bc1a6888b3234db0aa79a03a58937d Mon Sep 17 00:00:00 2001 From: 21pages Date: Fri, 22 Jul 2022 09:14:18 +0800 Subject: [PATCH 16/17] hwcodec: update build.py Signed-off-by: 21pages --- build.py | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) mode change 100644 => 100755 build.py diff --git a/build.py b/build.py old mode 100644 new mode 100755 index efa6f783..f612caa2 --- a/build.py +++ b/build.py @@ -22,7 +22,7 @@ def get_version(): return '' -def get_features(feature): +def prase_rc_features(feature): available_features = { 'IddDriver': { 'zip_url': 'https://github.com/fufesou/RustDeskIddDriver/releases/download/v0.1/RustDeskIddDriver_x64.zip', @@ -94,8 +94,8 @@ def download_extract_features(features, res_dir): print(f'{feat} extract end') -def build_windows(args): - features = get_features(args.feature) +def get_rc_features(args): + features = prase_rc_features(args.feature) if features: print(f'Build with features {list(features.keys())}') res_dir = 'resources' @@ -105,12 +105,17 @@ def build_windows(args): raise Exception(f'Find file {res_dir}, not a directory') os.makedirs(res_dir, exist_ok=True) download_extract_features(features, res_dir) + return ['with_rc'] if features else [] + - with_rc = ',with_rc' if features else '' - hwcodec = ',hwcodec' if args.hwcodec else '' - cmd = 'cargo build --release --features inline' + with_rc + hwcodec - print(cmd) - os.system(cmd) +def get_features(args): + features = ['inline'] + if windows: + features.extend(get_rc_features(args)) + if args.hwcodec: + features.append('hwcodec') + print("features:", features) + return features def main(): parser = make_parser() @@ -129,8 +134,9 @@ def main(): if os.path.isfile('/usr/bin/pacman'): os.system('git checkout src/ui/common.tis') version = get_version() + features = ",".join(get_features(args)) if windows: - build_windows(args) + os.system('cargo build --release --features ' + features) # os.system('upx.exe target/release/rustdesk.exe') os.system('mv target/release/rustdesk.exe target/release/RustDesk.exe') pa = os.environ.get('P') @@ -141,7 +147,7 @@ def main(): print('Not signed') os.system(f'cp -rf target/release/RustDesk.exe rustdesk-{version}-setdown.exe') elif os.path.isfile('/usr/bin/pacman'): - os.system('cargo build --release --features inline') + os.system('cargo build --release --features ' + features) os.system('git checkout src/ui/common.tis') os.system('strip target/release/rustdesk') os.system("sed -i 's/pkgver=.*/pkgver=%s/g' PKGBUILD" % version) @@ -150,7 +156,7 @@ def main(): os.system('mv rustdesk-%s-0-x86_64.pkg.tar.zst rustdesk-%s-manjaro-arch.pkg.tar.zst' % (version, version)) # pacman -U ./rustdesk.pkg.tar.zst elif os.path.isfile('/usr/bin/yum'): - os.system('cargo build --release --features inline') + os.system('cargo build --release --features ' + features) os.system('strip target/release/rustdesk') os.system("sed -i 's/Version: .*/Version: %s/g' rpm.spec" % version) os.system('HBB=`pwd` rpmbuild -ba rpm.spec') @@ -158,14 +164,14 @@ def main(): version, version)) # yum localinstall rustdesk.rpm elif os.path.isfile('/usr/bin/zypper'): - os.system('cargo build --release --features inline') + os.system('cargo build --release --features ' + features) os.system('strip target/release/rustdesk') os.system("sed -i 's/Version: .*/Version: %s/g' rpm-suse.spec" % version) os.system('HBB=`pwd` rpmbuild -ba rpm-suse.spec') os.system('mv $HOME/rpmbuild/RPMS/x86_64/rustdesk-%s-0.x86_64.rpm ./rustdesk-%s-suse.rpm' % (version, version)) # yum localinstall rustdesk.rpm else: - os.system('cargo bundle --release --features inline') + os.system('cargo bundle --release --features ' + features) if osx: os.system( 'strip target/release/bundle/osx/RustDesk.app/Contents/MacOS/rustdesk') From 3fe3ba00a0ed334d9a747972fbdb675d0f68f541 Mon Sep 17 00:00:00 2001 From: 21pages Date: Fri, 22 Jul 2022 12:41:49 +0800 Subject: [PATCH 17/17] fix spell mistake Signed-off-by: 21pages --- build.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.py b/build.py index f612caa2..341f4f4e 100755 --- a/build.py +++ b/build.py @@ -22,7 +22,7 @@ def get_version(): return '' -def prase_rc_features(feature): +def parse_rc_features(feature): available_features = { 'IddDriver': { 'zip_url': 'https://github.com/fufesou/RustDeskIddDriver/releases/download/v0.1/RustDeskIddDriver_x64.zip', @@ -95,7 +95,7 @@ def download_extract_features(features, res_dir): def get_rc_features(args): - features = prase_rc_features(args.feature) + features = parse_rc_features(args.feature) if features: print(f'Build with features {list(features.keys())}') res_dir = 'resources'