From 534bfad50f085499e4cf260ad2cad296e4bdd58f Mon Sep 17 00:00:00 2001 From: 21pages Date: Thu, 2 Nov 2023 16:57:24 +0800 Subject: [PATCH] opt codec 1. use src width/height to convert yuv 2. align dst yuv to avoid illegal memory access 3. init yuvfmt when new codec 4. move remote reset calls from empty conns judge to emtpy remote conns judge Signed-off-by: 21pages --- Cargo.lock | 4 +- libs/scrap/src/common/android.rs | 31 ++++++++++++---- libs/scrap/src/common/aom.rs | 62 ++++++++++++++++--------------- libs/scrap/src/common/convert.rs | 60 ++++++++++++++++++++---------- libs/scrap/src/common/dxgi.rs | 33 ++++++++++++---- libs/scrap/src/common/mod.rs | 5 +++ libs/scrap/src/common/quartz.rs | 26 +++++++++++-- libs/scrap/src/common/vpxcodec.rs | 62 ++++++++++++++++--------------- libs/scrap/src/common/wayland.rs | 4 +- libs/scrap/src/common/x11.rs | 38 +++++++++++++------ libs/scrap/src/x11/capturer.rs | 2 +- src/server/connection.rs | 38 ++++++++----------- src/server/portable_service.rs | 2 +- 13 files changed, 229 insertions(+), 138 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 01f6570dc..2d3de8743 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2973,8 +2973,8 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hwcodec" -version = "0.1.1" -source = "git+https://github.com/21pages/hwcodec?branch=stable#82cdc15457e42feaf14e1b38622506b2d54baf76" +version = "0.1.3" +source = "git+https://github.com/21pages/hwcodec?branch=stable#83300549075158e5a3fa6c59ea527af3330e48ff" dependencies = [ "bindgen 0.59.2", "cc", diff --git a/libs/scrap/src/common/android.rs b/libs/scrap/src/common/android.rs index ffbf4353a..538b52b69 100644 --- a/libs/scrap/src/common/android.rs +++ b/libs/scrap/src/common/android.rs @@ -43,7 +43,7 @@ impl crate::TraitCapturer for Capturer { unsafe { std::ptr::copy_nonoverlapping(buf.as_ptr(), self.rgba.as_mut_ptr(), buf.len()) }; - Ok(Frame::new(&self.rgba, self.height())) + Ok(Frame::new(&self.rgba, self.width(), self.height())) } else { return Err(io::ErrorKind::WouldBlock.into()); } @@ -51,16 +51,23 @@ impl crate::TraitCapturer for Capturer { } pub struct Frame<'a> { - pub data: &'a [u8], - pub stride: Vec, + data: &'a [u8], + width: usize, + height: usize, + stride: Vec, } impl<'a> Frame<'a> { - pub fn new(data: &'a [u8], h: usize) -> Self { - let stride = data.len() / h; - let mut v = Vec::new(); - v.push(stride); - Frame { data, stride: v } + pub fn new(data: &'a [u8], width: usize, height: usize) -> Self { + let stride0 = data.len() / height; + let mut stride = Vec::new(); + stride.push(stride0); + Frame { + data, + width, + height, + stride, + } } } @@ -69,6 +76,14 @@ impl<'a> crate::TraitFrame for Frame<'a> { self.data } + fn width(&self) -> usize { + self.width + } + + fn height(&self) -> usize { + self.height + } + fn stride(&self) -> Vec { self.stride.clone() } diff --git a/libs/scrap/src/common/aom.rs b/libs/scrap/src/common/aom.rs index c75106a6e..975a82d64 100644 --- a/libs/scrap/src/common/aom.rs +++ b/libs/scrap/src/common/aom.rs @@ -7,9 +7,9 @@ include!(concat!(env!("OUT_DIR"), "/aom_ffi.rs")); use crate::codec::{base_bitrate, codec_thread_num, Quality}; -use crate::Pixfmt; use crate::{codec::EncoderApi, EncodeFrame, STRIDE_ALIGN}; use crate::{common::GoogleImage, generate_call_macro, generate_call_ptr_macro, Error, Result}; +use crate::{EncodeYuvFormat, Pixfmt}; use hbb_common::{ anyhow::{anyhow, Context}, bytes::Bytes, @@ -54,6 +54,7 @@ pub struct AomEncoder { width: usize, height: usize, i444: bool, + yuvfmt: EncodeYuvFormat, } // https://webrtc.googlesource.com/src/+/refs/heads/main/modules/video_coding/codecs/av1/libaom_av1_encoder.cc @@ -241,6 +242,7 @@ impl EncoderApi for AomEncoder { width: config.width as _, height: config.height as _, i444, + yuvfmt: Self::get_yuvfmt(config.width, config.height, i444), }) } _ => Err(anyhow!("encoder type mismatch")), @@ -263,35 +265,7 @@ impl EncoderApi for AomEncoder { } fn yuvfmt(&self) -> crate::EncodeYuvFormat { - let mut img = Default::default(); - let fmt = if self.i444 { - aom_img_fmt::AOM_IMG_FMT_I444 - } else { - aom_img_fmt::AOM_IMG_FMT_I420 - }; - unsafe { - aom_img_wrap( - &mut img, - fmt, - self.width as _, - self.height as _, - crate::STRIDE_ALIGN as _, - 0x1 as _, - ); - } - let pixfmt = if self.i444 { - Pixfmt::I444 - } else { - Pixfmt::I420 - }; - crate::EncodeYuvFormat { - pixfmt, - w: img.w as _, - h: img.h as _, - stride: img.stride.map(|s| s as usize).to_vec(), - u: img.planes[1] as usize - img.planes[0] as usize, - v: img.planes[2] as usize - img.planes[0] as usize, - } + self.yuvfmt.clone() } fn set_quality(&mut self, quality: Quality) -> ResultType<()> { @@ -400,6 +374,34 @@ impl AomEncoder { (q_min, q_max) } + + fn get_yuvfmt(width: u32, height: u32, i444: bool) -> EncodeYuvFormat { + let mut img = Default::default(); + let fmt = if i444 { + aom_img_fmt::AOM_IMG_FMT_I444 + } else { + aom_img_fmt::AOM_IMG_FMT_I420 + }; + unsafe { + aom_img_wrap( + &mut img, + fmt, + width as _, + height as _, + crate::STRIDE_ALIGN as _, + 0x1 as _, + ); + } + let pixfmt = if i444 { Pixfmt::I444 } else { Pixfmt::I420 }; + EncodeYuvFormat { + pixfmt, + w: img.w as _, + h: img.h as _, + stride: img.stride.map(|s| s as usize).to_vec(), + u: img.planes[1] as usize - img.planes[0] as usize, + v: img.planes[2] as usize - img.planes[0] as usize, + } + } } impl Drop for AomEncoder { diff --git a/libs/scrap/src/common/convert.rs b/libs/scrap/src/common/convert.rs index 0ef3bc362..3bf0e7a03 100644 --- a/libs/scrap/src/common/convert.rs +++ b/libs/scrap/src/common/convert.rs @@ -202,17 +202,31 @@ pub fn convert_to_yuv( ) -> ResultType<()> { let src = captured.data(); let src_stride = captured.stride(); - let captured_pixfmt = captured.pixfmt(); - if captured_pixfmt == crate::Pixfmt::BGRA || captured_pixfmt == crate::Pixfmt::RGBA { - if src.len() < src_stride[0] * dst_fmt.h { + let src_pixfmt = captured.pixfmt(); + let src_width = captured.width(); + let src_height = captured.height(); + if src_width > dst_fmt.w || src_height > dst_fmt.h { + bail!( + "src rect > dst rect: ({src_width}, {src_height}) > ({},{})", + dst_fmt.w, + dst_fmt.h + ); + } + if src_pixfmt == crate::Pixfmt::BGRA || src_pixfmt == crate::Pixfmt::RGBA { + if src.len() < src_stride[0] * src_height { bail!( - "length not enough: {} < {}", + "wrong src len, {} < {} * {}", src.len(), - src_stride[0] * dst_fmt.h + src_stride[0], + src_height ); } } - match (captured_pixfmt, dst_fmt.pixfmt) { + let align = |x:usize| { + (x + 63) / 64 * 64 + }; + + match (src_pixfmt, dst_fmt.pixfmt) { (crate::Pixfmt::BGRA, crate::Pixfmt::I420) | (crate::Pixfmt::RGBA, crate::Pixfmt::I420) => { let dst_stride_y = dst_fmt.stride[0]; let dst_stride_uv = dst_fmt.stride[1]; @@ -220,7 +234,7 @@ pub fn convert_to_yuv( let dst_y = dst.as_mut_ptr(); let dst_u = dst[dst_fmt.u..].as_mut_ptr(); let dst_v = dst[dst_fmt.v..].as_mut_ptr(); - let f = if captured_pixfmt == crate::Pixfmt::BGRA { + let f = if src_pixfmt == crate::Pixfmt::BGRA { ARGBToI420 } else { ABGRToI420 @@ -234,17 +248,20 @@ pub fn convert_to_yuv( dst_stride_uv as _, dst_v, dst_stride_uv as _, - dst_fmt.w as _, - dst_fmt.h as _, + src_width as _, + src_height as _, )); } (crate::Pixfmt::BGRA, crate::Pixfmt::NV12) | (crate::Pixfmt::RGBA, crate::Pixfmt::NV12) => { let dst_stride_y = dst_fmt.stride[0]; let dst_stride_uv = dst_fmt.stride[1]; - dst.resize(dst_fmt.h * (dst_stride_y + dst_stride_uv / 2), 0); + dst.resize( + align(dst_fmt.h) * (align(dst_stride_y) + align(dst_stride_uv / 2)), + 0, + ); let dst_y = dst.as_mut_ptr(); let dst_uv = dst[dst_fmt.u..].as_mut_ptr(); - let f = if captured_pixfmt == crate::Pixfmt::BGRA { + let f = if src_pixfmt == crate::Pixfmt::BGRA { ARGBToNV12 } else { ABGRToNV12 @@ -256,19 +273,22 @@ pub fn convert_to_yuv( dst_stride_y as _, dst_uv, dst_stride_uv as _, - dst_fmt.w as _, - dst_fmt.h as _, + src_width as _, + src_height as _, )); } (crate::Pixfmt::BGRA, crate::Pixfmt::I444) | (crate::Pixfmt::RGBA, crate::Pixfmt::I444) => { let dst_stride_y = dst_fmt.stride[0]; let dst_stride_u = dst_fmt.stride[1]; let dst_stride_v = dst_fmt.stride[2]; - dst.resize(dst_fmt.h * (dst_stride_y + dst_stride_u + dst_stride_v), 0); + dst.resize( + align(dst_fmt.h) * (align(dst_stride_y) + align(dst_stride_u) + align(dst_stride_v)), + 0, + ); let dst_y = dst.as_mut_ptr(); let dst_u = dst[dst_fmt.u..].as_mut_ptr(); let dst_v = dst[dst_fmt.v..].as_mut_ptr(); - let src = if captured_pixfmt == crate::Pixfmt::BGRA { + let src = if src_pixfmt == crate::Pixfmt::BGRA { src } else { mid_data.resize(src.len(), 0); @@ -277,8 +297,8 @@ pub fn convert_to_yuv( src_stride[0] as _, mid_data.as_mut_ptr(), src_stride[0] as _, - dst_fmt.w as _, - dst_fmt.h as _, + src_width as _, + src_height as _, )); mid_data }; @@ -291,13 +311,13 @@ pub fn convert_to_yuv( dst_stride_u as _, dst_v, dst_stride_v as _, - dst_fmt.w as _, - dst_fmt.h as _, + src_width as _, + src_height as _, )); } _ => { bail!( - "convert not support, {captured_pixfmt:?} -> {:?}", + "convert not support, {src_pixfmt:?} -> {:?}", dst_fmt.pixfmt ); } diff --git a/libs/scrap/src/common/dxgi.rs b/libs/scrap/src/common/dxgi.rs index cfec42195..3bf1783a8 100644 --- a/libs/scrap/src/common/dxgi.rs +++ b/libs/scrap/src/common/dxgi.rs @@ -41,7 +41,7 @@ impl Capturer { impl TraitCapturer for Capturer { fn frame<'a>(&'a mut self, timeout: Duration) -> io::Result> { match self.inner.frame(timeout.as_millis() as _) { - Ok(frame) => Ok(Frame::new(frame, self.height)), + Ok(frame) => Ok(Frame::new(frame, self.width, self.height)), Err(ref error) if error.kind() == TimedOut => Err(WouldBlock.into()), Err(error) => Err(error), } @@ -58,15 +58,22 @@ impl TraitCapturer for Capturer { pub struct Frame<'a> { data: &'a [u8], + width: usize, + height: usize, stride: Vec, } impl<'a> Frame<'a> { - pub fn new(data: &'a [u8], h: usize) -> Self { - let stride = data.len() / h; - let mut v = Vec::new(); - v.push(stride); - Frame { data, stride: v } + pub fn new(data: &'a [u8], width: usize, height: usize) -> Self { + let stride0 = data.len() / height; + let mut stride = Vec::new(); + stride.push(stride0); + Frame { + data, + width, + height, + stride, + } } } @@ -75,6 +82,14 @@ impl<'a> crate::TraitFrame for Frame<'a> { self.data } + fn width(&self) -> usize { + self.width + } + + fn height(&self) -> usize { + self.height + } + fn stride(&self) -> Vec { self.stride.clone() } @@ -167,7 +182,11 @@ impl CapturerMag { impl TraitCapturer for CapturerMag { fn frame<'a>(&'a mut self, _timeout_ms: Duration) -> io::Result> { self.inner.frame(&mut self.data)?; - Ok(Frame::new(&self.data, self.inner.get_rect().2)) + Ok(Frame::new( + &self.data, + self.inner.get_rect().1, + self.inner.get_rect().2, + )) } fn is_gdi(&self) -> bool { diff --git a/libs/scrap/src/common/mod.rs b/libs/scrap/src/common/mod.rs index f1cc9ab0e..4433e512f 100644 --- a/libs/scrap/src/common/mod.rs +++ b/libs/scrap/src/common/mod.rs @@ -112,6 +112,10 @@ pub trait TraitCapturer { pub trait TraitFrame { fn data(&self) -> &[u8]; + fn width(&self) -> usize; + + fn height(&self) -> usize; + fn stride(&self) -> Vec; fn pixfmt(&self) -> Pixfmt; @@ -125,6 +129,7 @@ pub enum Pixfmt { I444, } +#[derive(Debug, Clone)] pub struct EncodeYuvFormat { pub pixfmt: Pixfmt, pub w: usize, diff --git a/libs/scrap/src/common/quartz.rs b/libs/scrap/src/common/quartz.rs index 9aad7ee09..d84913999 100644 --- a/libs/scrap/src/common/quartz.rs +++ b/libs/scrap/src/common/quartz.rs @@ -55,7 +55,12 @@ impl crate::TraitCapturer for Capturer { Some(mut frame) => { crate::would_block_if_equal(&mut self.saved_raw_data, frame.inner())?; frame.surface_to_bgra(self.height()); - Ok(Frame(frame, PhantomData)) + Ok(Frame { + frame, + data: PhantomData, + width: self.width(), + height: self.height(), + }) } None => Err(io::ErrorKind::WouldBlock.into()), @@ -69,16 +74,29 @@ impl crate::TraitCapturer for Capturer { } } -pub struct Frame<'a>(pub quartz::Frame, PhantomData<&'a [u8]>); +pub struct Frame<'a> { + frame: quartz::Frame, + data: PhantomData<&'a [u8]>, + width: usize, + height: usize, +} impl<'a> crate::TraitFrame for Frame<'a> { fn data(&self) -> &[u8] { - &*self.0 + &*self.frame + } + + fn width(&self) -> usize { + self.width + } + + fn height(&self) -> usize { + self.height } fn stride(&self) -> Vec { let mut v = Vec::new(); - v.push(self.0.stride()); + v.push(self.frame.stride()); v } diff --git a/libs/scrap/src/common/vpxcodec.rs b/libs/scrap/src/common/vpxcodec.rs index d3fb9c7d3..19ede9bba 100644 --- a/libs/scrap/src/common/vpxcodec.rs +++ b/libs/scrap/src/common/vpxcodec.rs @@ -8,7 +8,7 @@ use hbb_common::message_proto::{Chroma, EncodedVideoFrame, EncodedVideoFrames, V use hbb_common::ResultType; use crate::codec::{base_bitrate, codec_thread_num, EncoderApi, Quality}; -use crate::{GoogleImage, Pixfmt, STRIDE_ALIGN}; +use crate::{EncodeYuvFormat, GoogleImage, Pixfmt, STRIDE_ALIGN}; use super::vpx::{vp8e_enc_control_id::*, vpx_codec_err_t::*, *}; use crate::{generate_call_macro, generate_call_ptr_macro, Error, Result}; @@ -40,6 +40,7 @@ pub struct VpxEncoder { height: usize, id: VpxVideoCodecId, i444: bool, + yuvfmt: EncodeYuvFormat, } pub struct VpxDecoder { @@ -175,6 +176,7 @@ impl EncoderApi for VpxEncoder { height: config.height as _, id: config.codec, i444, + yuvfmt: Self::get_yuvfmt(config.width, config.height, i444), }) } _ => Err(anyhow!("encoder type mismatch")), @@ -202,35 +204,7 @@ impl EncoderApi for VpxEncoder { } fn yuvfmt(&self) -> crate::EncodeYuvFormat { - let mut img = Default::default(); - let fmt = if self.i444 { - vpx_img_fmt::VPX_IMG_FMT_I444 - } else { - vpx_img_fmt::VPX_IMG_FMT_I420 - }; - unsafe { - vpx_img_wrap( - &mut img, - fmt, - self.width as _, - self.height as _, - crate::STRIDE_ALIGN as _, - 0x1 as _, - ); - } - let pixfmt = if self.i444 { - Pixfmt::I444 - } else { - Pixfmt::I420 - }; - crate::EncodeYuvFormat { - pixfmt, - w: img.w as _, - h: img.h as _, - stride: img.stride.map(|s| s as usize).to_vec(), - u: img.planes[1] as usize - img.planes[0] as usize, - v: img.planes[2] as usize - img.planes[0] as usize, - } + self.yuvfmt.clone() } fn set_quality(&mut self, quality: Quality) -> ResultType<()> { @@ -362,6 +336,34 @@ impl VpxEncoder { (q_min, q_max) } + + fn get_yuvfmt(width: u32, height: u32, i444: bool) -> EncodeYuvFormat { + let mut img = Default::default(); + let fmt = if i444 { + vpx_img_fmt::VPX_IMG_FMT_I444 + } else { + vpx_img_fmt::VPX_IMG_FMT_I420 + }; + unsafe { + vpx_img_wrap( + &mut img, + fmt, + width as _, + height as _, + crate::STRIDE_ALIGN as _, + 0x1 as _, + ); + } + let pixfmt = if i444 { Pixfmt::I444 } else { Pixfmt::I420 }; + EncodeYuvFormat { + pixfmt, + w: img.w as _, + h: img.h as _, + stride: img.stride.map(|s| s as usize).to_vec(), + u: img.planes[1] as usize - img.planes[0] as usize, + v: img.planes[2] as usize - img.planes[0] as usize, + } + } } impl Drop for VpxEncoder { diff --git a/libs/scrap/src/common/wayland.rs b/libs/scrap/src/common/wayland.rs index 5c5b74e5b..cf36a83a4 100644 --- a/libs/scrap/src/common/wayland.rs +++ b/libs/scrap/src/common/wayland.rs @@ -62,8 +62,8 @@ impl Capturer { impl TraitCapturer for Capturer { 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::new(x, crate::Pixfmt::BGRA, h)), - PixelProvider::RGB0(_w, h, x) => Ok(Frame::new(x, crate::Pixfmt::RGBA, h)), + PixelProvider::BGR0(w, h, x) => Ok(Frame::new(x, crate::Pixfmt::BGRA, w, h)), + PixelProvider::RGB0(w, h, x) => Ok(Frame::new(x, crate::Pixfmt::RGBA, w,h)), PixelProvider::NONE => Err(std::io::ErrorKind::WouldBlock.into()), _ => Err(map_err("Invalid data")), } diff --git a/libs/scrap/src/common/x11.rs b/libs/scrap/src/common/x11.rs index f5009095e..08ec5e1f1 100644 --- a/libs/scrap/src/common/x11.rs +++ b/libs/scrap/src/common/x11.rs @@ -1,4 +1,4 @@ -use crate::{common::TraitCapturer, x11, TraitFrame, Pixfmt}; +use crate::{common::TraitCapturer, x11, Pixfmt, TraitFrame}; use std::{io, time::Duration}; pub struct Capturer(x11::Capturer); @@ -25,26 +25,42 @@ impl TraitCapturer for Capturer { } } -pub struct Frame<'a>{ +pub struct Frame<'a> { pub data: &'a [u8], - pub pixfmt:Pixfmt, - pub stride:Vec, + pub pixfmt: Pixfmt, + pub width: usize, + pub height: usize, + pub stride: Vec, } -impl<'a> Frame<'a> { - pub fn new(data:&'a [u8], pixfmt:Pixfmt, h:usize) -> Self { - let stride = data.len() / h; - let mut v = Vec::new(); - v.push(stride); - Self { data, pixfmt, stride: v } +impl<'a> Frame<'a> { + pub fn new(data: &'a [u8], pixfmt: Pixfmt, width: usize, height: usize) -> Self { + let stride0 = data.len() / height; + let mut stride = Vec::new(); + stride.push(stride0); + Self { + data, + pixfmt, + width, + height, + stride, + } } } -impl<'a> TraitFrame for Frame<'a> { +impl<'a> TraitFrame for Frame<'a> { fn data(&self) -> &[u8] { self.data } + fn width(&self) -> usize { + self.width + } + + fn height(&self) -> usize { + self.height + } + fn stride(&self) -> Vec { self.stride.clone() } diff --git a/libs/scrap/src/x11/capturer.rs b/libs/scrap/src/x11/capturer.rs index 52b882bbf..308df1651 100644 --- a/libs/scrap/src/x11/capturer.rs +++ b/libs/scrap/src/x11/capturer.rs @@ -102,7 +102,7 @@ impl Capturer { let result = unsafe { slice::from_raw_parts(self.buffer, self.size) }; crate::would_block_if_equal(&mut self.saved_raw_data, result)?; Ok( - Frame::new(result, crate::Pixfmt::BGRA, self.display.h()) + Frame::new(result, crate::Pixfmt::BGRA, self.display.w(), self.display.h()) ) } } diff --git a/src/server/connection.rs b/src/server/connection.rs index a31fcb8d4..da12f6fee 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -670,7 +670,6 @@ impl Connection { conn.lr.my_id.clone(), ); video_service::notify_video_frame_fetched(id, None); - scrap::codec::Encoder::update(id, scrap::codec::EncodingUpdate::Remove); if conn.authorized { password::update_temporary_password(); } @@ -1173,7 +1172,7 @@ impl Connection { sub_service = true; } } - Self::on_remote_authorized(); + self.on_remote_authorized(); } let mut msg_out = Message::new(); msg_out.set_login_response(res); @@ -1212,9 +1211,10 @@ impl Connection { } } - fn on_remote_authorized() { + fn on_remote_authorized(&self) { use std::sync::Once; static _ONCE: Once = Once::new(); + self.update_codec_on_login(); #[cfg(any(target_os = "windows", target_os = "linux"))] if !Config::get_option("allow-remove-wallpaper").is_empty() { // multi connections set once @@ -1412,8 +1412,8 @@ impl Connection { return Config::get_option(enable_prefix_option).is_empty(); } - fn update_codec_on_login(&self, lr: &LoginRequest) { - if let Some(o) = lr.option.as_ref() { + fn update_codec_on_login(&self) { + if let Some(o) = self.lr.clone().option.as_ref() { if let Some(q) = o.supported_decoding.clone().take() { scrap::codec::Encoder::update( self.inner.id(), @@ -1438,9 +1438,6 @@ impl Connection { if let Some(o) = lr.option.as_ref() { self.options_in_login = Some(o.clone()); } - if lr.union.is_none() { - self.update_codec_on_login(&lr); - } self.video_ack_required = lr.video_ack_required; } @@ -2969,18 +2966,6 @@ mod raii { fn drop(&mut self) { let mut active_conns_lock = ALIVE_CONNS.lock().unwrap(); active_conns_lock.retain(|&c| c != self.0); - #[cfg(not(any(target_os = "android", target_os = "ios")))] - if active_conns_lock.is_empty() { - display_service::reset_resolutions(); - } - #[cfg(all(windows, feature = "virtual_display_driver"))] - if active_conns_lock.is_empty() { - let _ = virtual_display_manager::reset_all(); - } - #[cfg(all(windows))] - if active_conns_lock.is_empty() { - crate::privacy_win_mag::stop(); - } video_service::VIDEO_QOS .lock() .unwrap() @@ -2988,17 +2973,20 @@ mod raii { } } - pub struct AuthedConnID(i32); + pub struct AuthedConnID(i32, AuthConnType); impl AuthedConnID { pub fn new(id: i32, conn_type: AuthConnType) -> Self { AUTHED_CONNS.lock().unwrap().push((id, conn_type)); - Self(id) + Self(id, conn_type) } } impl Drop for AuthedConnID { fn drop(&mut self) { + if self.1 == AuthConnType::Remote { + scrap::codec::Encoder::update(self.0, scrap::codec::EncodingUpdate::Remove); + } let mut lock = AUTHED_CONNS.lock().unwrap(); lock.retain(|&c| c.0 != self.0); if lock.iter().filter(|c| c.1 == AuthConnType::Remote).count() == 0 { @@ -3006,6 +2994,12 @@ mod raii { { *WALLPAPER_REMOVER.lock().unwrap() = None; } + #[cfg(not(any(target_os = "android", target_os = "ios")))] + display_service::reset_resolutions(); + #[cfg(all(windows, feature = "virtual_display_driver"))] + let _ = virtual_display_manager::reset_all(); + #[cfg(all(windows))] + crate::privacy_win_mag::stop(); } } } diff --git a/src/server/portable_service.rs b/src/server/portable_service.rs index 65d861bea..51d665d0a 100644 --- a/src/server/portable_service.rs +++ b/src/server/portable_service.rs @@ -704,7 +704,7 @@ pub mod client { } let frame_ptr = base.add(ADDR_CAPTURE_FRAME); let data = slice::from_raw_parts(frame_ptr, (*frame_info).length); - Ok(Frame::new(data, self.height)) + Ok(Frame::new(data, self.width, self.height)) } else { let ptr = base.add(ADDR_CAPTURE_WOULDBLOCK); let wouldblock = utils::ptr_to_i32(ptr);