diff --git a/libs/scrap/src/common/codec.rs b/libs/scrap/src/common/codec.rs index 2c383b99a..5a429fcc8 100644 --- a/libs/scrap/src/common/codec.rs +++ b/libs/scrap/src/common/codec.rs @@ -15,7 +15,7 @@ use crate::{ aom::{self, AomDecoder, AomEncoder, AomEncoderConfig}, common::GoogleImage, vpxcodec::{self, VpxDecoder, VpxDecoderConfig, VpxEncoder, VpxEncoderConfig, VpxVideoCodecId}, - CodecFormat, CodecName, EncodeInput, EncodeYuvFormat, ImageRgb, + CodecFormat, EncodeInput, EncodeYuvFormat, ImageRgb, }; use hbb_common::{ @@ -38,6 +38,7 @@ lazy_static::lazy_static! { static ref PEER_DECODINGS: Arc>> = Default::default(); static ref ENCODE_CODEC_FORMAT: Arc> = Arc::new(Mutex::new(CodecFormat::VP9)); static ref THREAD_LOG_TIME: Arc>> = Arc::new(Mutex::new(None)); + static ref USABLE_ENCODING: Arc>> = Arc::new(Mutex::new(None)); } pub const ENCODE_NEED_SWITCH: &'static str = "ENCODE_NEED_SWITCH"; @@ -235,6 +236,13 @@ impl Encoder { }) .map(|(_, s)| s.prefer) .collect(); + *USABLE_ENCODING.lock().unwrap() = Some(SupportedEncoding { + vp8: vp8_useable, + av1: av1_useable, + h264: h264_useable, + h265: h265_useable, + ..Default::default() + }); // find the most frequent preference let mut counts = Vec::new(); for pref in &preferences { @@ -323,6 +331,10 @@ impl Encoder { encoding } + pub fn usable_encoding() -> Option { + USABLE_ENCODING.lock().unwrap().clone() + } + pub fn set_fallback(config: &EncoderCfg) { let format = match config { EncoderCfg::VPX(vpx) => match vpx.codec { diff --git a/libs/scrap/src/common/record.rs b/libs/scrap/src/common/record.rs index eecf80b4d..54c9c1864 100644 --- a/libs/scrap/src/common/record.rs +++ b/libs/scrap/src/common/record.rs @@ -2,9 +2,7 @@ use crate::CodecFormat; #[cfg(feature = "hwcodec")] use hbb_common::anyhow::anyhow; use hbb_common::{ - bail, chrono, - config::Config, - log, + bail, chrono, log, message_proto::{message, video_frame, EncodedVideoFrame, Message}, ResultType, }; diff --git a/libs/scrap/src/common/vram.rs b/libs/scrap/src/common/vram.rs index 0a8b5c2d0..ce9bfd8a9 100644 --- a/libs/scrap/src/common/vram.rs +++ b/libs/scrap/src/common/vram.rs @@ -6,7 +6,7 @@ use std::{ use crate::{ codec::{base_bitrate, enable_vram_option, EncoderApi, EncoderCfg, Quality}, - AdapterDevice, CodecFormat, CodecName, EncodeInput, EncodeYuvFormat, Pixfmt, + AdapterDevice, CodecFormat, EncodeInput, EncodeYuvFormat, Pixfmt, }; use hbb_common::{ anyhow::{anyhow, bail, Context}, @@ -284,10 +284,6 @@ impl VRamEncoder { log::info!("set display#{display} not use vram encode to {not_use}"); ENOCDE_NOT_USE.lock().unwrap().insert(display, not_use); } - - pub fn not_use() -> bool { - ENOCDE_NOT_USE.lock().unwrap().iter().any(|v| *v.1) - } } pub struct VRamDecoder { diff --git a/src/server/connection.rs b/src/server/connection.rs index 1a402713f..76436f061 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -231,8 +231,7 @@ pub struct Connection { auto_disconnect_timer: Option<(Instant, u64)>, authed_conn_id: Option, file_remove_log_control: FileRemoveLogControl, - #[cfg(feature = "vram")] - supported_encoding_flag: (bool, Option), + last_supported_encoding: Option, services_subed: bool, delayed_read_dir: Option<(String, bool)>, #[cfg(target_os = "macos")] @@ -386,8 +385,7 @@ impl Connection { auto_disconnect_timer: None, authed_conn_id: None, file_remove_log_control: FileRemoveLogControl::new(id), - #[cfg(feature = "vram")] - supported_encoding_flag: (false, None), + last_supported_encoding: None, services_subed: false, delayed_read_dir: None, #[cfg(target_os = "macos")] @@ -1161,10 +1159,6 @@ impl Connection { pi.platform_additions = serde_json::to_string(&platform_additions).unwrap_or("".into()); } - let supported_encoding = scrap::codec::Encoder::supported_encoding(); - log::info!("peer info supported_encoding: {:?}", supported_encoding); - pi.encoding = Some(supported_encoding).into(); - if self.port_forward_socket.is_some() { let mut msg_out = Message::new(); res.set_peer_info(pi); @@ -1228,6 +1222,10 @@ impl Connection { if self.file_transfer.is_some() { res.set_peer_info(pi); } else { + let supported_encoding = scrap::codec::Encoder::supported_encoding(); + self.last_supported_encoding = Some(supported_encoding.clone()); + log::info!("peer info supported_encoding: {:?}", supported_encoding); + pi.encoding = Some(supported_encoding).into(); if let Some(msg_out) = super::display_service::is_inited_msg() { self.send(msg_out).await; } @@ -3140,22 +3138,34 @@ impl Connection { .map(|t| t.0 = Instant::now()); } - #[cfg(feature = "vram")] fn update_supported_encoding(&mut self) { - let not_use = Some(scrap::vram::VRamEncoder::not_use()); - if !self.authorized - || self.supported_encoding_flag.0 && self.supported_encoding_flag.1 == not_use - { + let Some(last) = &self.last_supported_encoding else { return; - } - let mut misc: Misc = Misc::new(); - let supported_encoding = scrap::codec::Encoder::supported_encoding(); - log::info!("update supported encoding: {:?}", supported_encoding); - misc.set_supported_encoding(supported_encoding); - let mut msg = Message::new(); - msg.set_misc(misc); - self.inner.send(msg.into()); - self.supported_encoding_flag = (true, not_use); + }; + let usable = scrap::codec::Encoder::usable_encoding(); + let Some(usable) = usable else { + return; + }; + if usable.vp8 != last.vp8 + || usable.av1 != last.av1 + || usable.h264 != last.h264 + || usable.h265 != last.h265 + { + let mut misc: Misc = Misc::new(); + let supported_encoding = SupportedEncoding { + vp8: usable.vp8, + av1: usable.av1, + h264: usable.h264, + h265: usable.h265, + ..last.clone() + }; + log::info!("update supported encoding: {:?}", supported_encoding); + self.last_supported_encoding = Some(supported_encoding.clone()); + misc.set_supported_encoding(supported_encoding); + let mut msg = Message::new(); + msg.set_misc(misc); + self.inner.send(msg.into()); + }; } #[cfg(not(any(target_os = "android", target_os = "ios")))] diff --git a/src/server/video_service.rs b/src/server/video_service.rs index 8a66575c4..53f9b1b21 100644 --- a/src/server/video_service.rs +++ b/src/server/video_service.rs @@ -638,6 +638,8 @@ impl Drop for Raii { fn drop(&mut self) { #[cfg(feature = "vram")] VRamEncoder::set_not_use(self.0, false); + #[cfg(feature = "vram")] + Encoder::update(scrap::codec::EncodingUpdate::Check); VIDEO_QOS.lock().unwrap().set_support_abr(self.0, true); } }