user fps adjust

Signed-off-by: 21pages <pages21@163.com>
This commit is contained in:
21pages
2022-10-19 10:19:49 +08:00
parent 829f30fe29
commit 32ad458b25
7 changed files with 218 additions and 45 deletions

View File

@@ -1092,7 +1092,12 @@ impl LoginConfigHandler {
n += 1;
} else if q == "custom" {
let config = PeerConfig::load(&self.id);
msg.custom_image_quality = config.custom_image_quality[0] << 8;
let quality = if config.custom_image_quality.is_empty() {
50
} else {
config.custom_image_quality[0]
};
msg.custom_image_quality = quality << 8;
n += 1;
}
if self.get_toggle_option("show-remote-cursor") {
@@ -1253,6 +1258,27 @@ impl LoginConfigHandler {
res
}
/// Create a [`Message`] for saving custom fps.
///
/// # Arguments
///
/// * `fps` - The given fps.
pub fn set_custom_fps(&mut self, fps: i32) -> Message {
let mut misc = Misc::new();
misc.set_option(OptionMessage {
custom_fps: fps,
..Default::default()
});
let mut msg_out = Message::new();
msg_out.set_misc(misc);
let mut config = self.load_config();
config
.options
.insert("custom-fps".to_owned(), fps.to_string());
self.save_config(config);
msg_out
}
pub fn get_option(&self, k: &str) -> String {
if let Some(v) = self.config.options.get(k) {
v.clone()

View File

@@ -186,6 +186,12 @@ pub fn session_set_custom_image_quality(id: String, value: i32) {
}
}
pub fn session_set_custom_fps(id: String, fps: i32) {
if let Some(session) = SESSIONS.write().unwrap().get_mut(&id) {
session.set_custom_fps(fps);
}
}
pub fn session_lock_screen(id: String) {
if let Some(session) = SESSIONS.read().unwrap().get(&id) {
session.lock_screen();
@@ -1000,6 +1006,10 @@ pub fn query_onlines(ids: Vec<String>) {
crate::rendezvous_mediator::query_online_states(ids, handle_query_onlines)
}
pub fn version_to_number(v: String) -> i64 {
hbb_common::get_version_number(&v)
}
pub fn main_is_installed() -> SyncReturn<bool> {
SyncReturn(is_installed())
}

View File

@@ -1316,16 +1316,25 @@ impl Connection {
if o.custom_image_quality > 0 {
image_quality = o.custom_image_quality;
} else {
image_quality = ImageQuality::Balanced.value();
image_quality = -1;
}
} else {
image_quality = q.value();
}
if image_quality > 0 {
video_service::VIDEO_QOS
.lock()
.unwrap()
.update_image_quality(image_quality);
}
}
if o.custom_fps > 0 {
video_service::VIDEO_QOS
.lock()
.unwrap()
.update_image_quality(image_quality);
.update_user_fps(o.custom_fps as _);
}
if let Ok(q) = o.lock_after_session_end.enum_value() {
if q != BoolOption::NotSet {
self.lock_after_session_end = q == BoolOption::Yes;

View File

@@ -1,6 +1,8 @@
use super::*;
use std::time::Duration;
const FPS: u8 = 30;
const MIN_FPS: u8 = 10;
const MAX_FPS: u8 = 120;
trait Percent {
fn as_percent(&self) -> u32;
}
@@ -23,7 +25,8 @@ pub struct VideoQoS {
current_image_quality: u32,
enable_abr: bool,
pub current_delay: u32,
pub fps: u8, // abr
pub fps: u8, // abr
pub user_fps: u8,
pub target_bitrate: u32, // abr
updated: bool,
state: DelayState,
@@ -56,6 +59,7 @@ impl Default for VideoQoS {
fn default() -> Self {
VideoQoS {
fps: FPS,
user_fps: FPS,
user_image_quality: ImageQuality::Balanced.as_percent(),
current_image_quality: ImageQuality::Balanced.as_percent(),
enable_abr: false,
@@ -80,12 +84,19 @@ impl VideoQoS {
}
pub fn spf(&mut self) -> Duration {
if self.fps <= 0 {
self.fps = FPS;
if self.fps < MIN_FPS || self.fps > MAX_FPS {
self.fps = self.base_fps();
}
Duration::from_secs_f32(1. / (self.fps as f32))
}
fn base_fps(&self) -> u8 {
if self.user_fps >= MIN_FPS && self.user_fps <= MAX_FPS {
return self.user_fps;
}
return FPS;
}
// update_network_delay periodically
// decrease the bitrate when the delay gets bigger
pub fn update_network_delay(&mut self, delay: u32) {
@@ -124,19 +135,19 @@ impl VideoQoS {
fn refresh_quality(&mut self) {
match self.state {
DelayState::Normal => {
self.fps = FPS;
self.fps = self.base_fps();
self.current_image_quality = self.user_image_quality;
}
DelayState::LowDelay => {
self.fps = FPS;
self.fps = self.base_fps();
self.current_image_quality = std::cmp::min(self.user_image_quality, 50);
}
DelayState::HighDelay => {
self.fps = FPS / 2;
self.fps = self.base_fps() / 2;
self.current_image_quality = std::cmp::min(self.user_image_quality, 25);
}
DelayState::Broken => {
self.fps = FPS / 4;
self.fps = self.base_fps() / 4;
self.current_image_quality = 10;
}
}
@@ -146,6 +157,14 @@ impl VideoQoS {
// handle image_quality change from peer
pub fn update_image_quality(&mut self, image_quality: i32) {
if image_quality == ImageQuality::Low.value()
|| image_quality == ImageQuality::Balanced.value()
|| image_quality == ImageQuality::Best.value()
{
// not custom
self.user_fps = FPS;
self.fps = FPS;
}
let image_quality = Self::convert_quality(image_quality) as _;
if self.current_image_quality != image_quality {
self.current_image_quality = image_quality;
@@ -156,6 +175,16 @@ impl VideoQoS {
self.user_image_quality = self.current_image_quality;
}
pub fn update_user_fps(&mut self, fps: u8) {
if fps >= MIN_FPS && fps <= MAX_FPS {
if self.user_fps != fps {
self.user_fps = fps;
self.fps = fps;
self.updated = true;
}
}
}
pub fn generate_bitrate(&mut self) -> ResultType<u32> {
// https://www.nvidia.com/en-us/geforce/guides/broadcasting-guide/
if self.width == 0 || self.height == 0 {

View File

@@ -134,6 +134,11 @@ impl<T: InvokeUiSession> Session<T> {
}
}
pub fn set_custom_fps(&mut self, custom_fps: i32) {
let msg = self.lc.write().unwrap().set_custom_fps(custom_fps);
self.send(Data::Message(msg));
}
pub fn get_remember(&self) -> bool {
self.lc.read().unwrap().remember
}
@@ -1181,7 +1186,12 @@ impl<T: InvokeUiSession> Interface for Session<T> {
if self.is_file_transfer() {
self.close_success();
} else if !self.is_port_forward() {
self.msgbox("success", "Successful", "Connected, waiting for image...", "");
self.msgbox(
"success",
"Successful",
"Connected, waiting for image...",
"",
);
}
#[cfg(windows)]
{