From 1b08adb1783d536de24578be5947239db541bdad Mon Sep 17 00:00:00 2001 From: 21pages Date: Mon, 13 Nov 2023 19:29:16 +0800 Subject: [PATCH] not use max fps by default Signed-off-by: 21pages --- flutter/lib/common/widgets/dialog.dart | 38 +++++------ .../lib/common/widgets/setting_widgets.dart | 38 +++++------ flutter/lib/consts.dart | 9 +++ libs/hbb_common/protos/message.proto | 2 +- src/client.rs | 32 +++++++--- src/client/io_loop.rs | 64 +++++++------------ src/server/connection.rs | 4 -- src/server/video_qos.rs | 28 +------- src/ui_session_interface.rs | 16 +++-- 9 files changed, 111 insertions(+), 120 deletions(-) diff --git a/flutter/lib/common/widgets/dialog.dart b/flutter/lib/common/widgets/dialog.dart index 2d2fbe63d..cd1ad83c8 100644 --- a/flutter/lib/common/widgets/dialog.dart +++ b/flutter/lib/common/widgets/dialog.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_hbb/common/shared_state.dart'; import 'package:flutter_hbb/common/widgets/setting_widgets.dart'; +import 'package:flutter_hbb/consts.dart'; import 'package:get/get.dart'; import '../../common.dart'; @@ -1244,8 +1245,8 @@ void showConfirmSwitchSidesDialog( } customImageQualityDialog(SessionID sessionId, String id, FFI ffi) async { - double qualityInitValue = 50; - double fpsInitValue = 30; + double initQuality = kDefaultQuality; + double initFps = kDefaultFps; bool qualitySet = false; bool fpsSet = false; @@ -1261,28 +1262,25 @@ customImageQualityDialog(SessionID sessionId, String id, FFI ffi) async { versionCmp(ffi.ffiModel.pi.version, '1.2.2') < 0; setCustomValues({double? quality, double? fps}) async { + debugPrint("setCustomValues quality:$quality, fps:$fps"); if (quality != null) { qualitySet = true; await bind.sessionSetCustomImageQuality( sessionId: sessionId, value: quality.toInt()); - print("quality:$quality"); } if (fps != null) { fpsSet = true; await bind.sessionSetCustomFps(sessionId: sessionId, fps: fps.toInt()); - print("fps:$fps"); } if (!qualitySet) { qualitySet = true; await bind.sessionSetCustomImageQuality( - sessionId: sessionId, value: qualityInitValue.toInt()); - print("qualityInitValue:$qualityInitValue"); + sessionId: sessionId, value: initQuality.toInt()); } if (!hideFps && !fpsSet) { fpsSet = true; await bind.sessionSetCustomFps( - sessionId: sessionId, fps: fpsInitValue.toInt()); - print("fpsInitValue:$fpsInitValue"); + sessionId: sessionId, fps: initFps.toInt()); } } @@ -1293,24 +1291,26 @@ customImageQualityDialog(SessionID sessionId, String id, FFI ffi) async { // quality final quality = await bind.sessionGetCustomImageQuality(sessionId: sessionId); - qualityInitValue = - quality != null && quality.isNotEmpty ? quality[0].toDouble() : 50.0; - if ((hideMoreQuality && qualityInitValue > 100) || - qualityInitValue < 10 || - qualityInitValue > 2000) { - qualityInitValue = 50; + initQuality = quality != null && quality.isNotEmpty + ? quality[0].toDouble() + : kDefaultQuality; + if (initQuality < kMinQuality || + initQuality > (!hideMoreQuality ? kMaxMoreQuality : kMaxQuality)) { + initQuality = kDefaultQuality; } // fps final fpsOption = await bind.sessionGetOption(sessionId: sessionId, arg: 'custom-fps'); - fpsInitValue = fpsOption == null ? 30 : double.tryParse(fpsOption) ?? 30; - if (fpsInitValue < 5 || fpsInitValue > 120) { - fpsInitValue = 30; + initFps = fpsOption == null + ? kDefaultFps + : double.tryParse(fpsOption) ?? kDefaultFps; + if (initFps < kMinFps || initFps > kMaxFps) { + initFps = kDefaultFps; } final content = customImageQualityWidget( - initQuality: qualityInitValue, - initFps: fpsInitValue, + initQuality: initQuality, + initFps: initFps, setQuality: (v) => setCustomValues(quality: v), setFps: (v) => setCustomValues(fps: v), showFps: !hideFps, diff --git a/flutter/lib/common/widgets/setting_widgets.dart b/flutter/lib/common/widgets/setting_widgets.dart index 26fd219ed..e5a7c0e76 100644 --- a/flutter/lib/common/widgets/setting_widgets.dart +++ b/flutter/lib/common/widgets/setting_widgets.dart @@ -2,6 +2,7 @@ import 'package:debounce_throttle/debounce_throttle.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_hbb/common.dart'; +import 'package:flutter_hbb/consts.dart'; import 'package:flutter_hbb/models/platform_model.dart'; import 'package:get/get.dart'; @@ -12,13 +13,17 @@ customImageQualityWidget( required Function(double) setFps, required bool showFps, required bool showMoreQuality}) { - if (!showMoreQuality && initQuality > 100) { - initQuality = 50; + if (initQuality < kMinQuality || + initQuality > (showMoreQuality ? kMaxMoreQuality : kMaxQuality)) { + initQuality = kDefaultQuality; + } + if (initFps < kMinFps || initFps > kMaxFps) { + initFps = kDefaultFps; } final qualityValue = initQuality.obs; final fpsValue = initFps.obs; - final RxBool moreQualityChecked = RxBool(qualityValue.value > 100); + final RxBool moreQualityChecked = RxBool(qualityValue.value > kMaxQuality); final debouncerQuality = Debouncer( Duration(milliseconds: 1000), onChanged: (double v) { @@ -51,9 +56,11 @@ customImageQualityWidget( flex: 3, child: Slider( value: qualityValue.value, - min: 10.0, - max: moreQualityChecked.value ? 2000 : 100, - divisions: moreQualityChecked.value ? 199 : 18, + min: kMinQuality, + max: moreQualityChecked.value ? kMaxMoreQuality : kMaxQuality, + divisions: moreQualityChecked.value + ? ((kMaxMoreQuality - kMinQuality) / 10).round() + : ((kMaxQuality - kMinQuality) / 5).round(), onChanged: (double value) async { qualityValue.value = value; debouncerQuality.value = value; @@ -113,9 +120,9 @@ customImageQualityWidget( flex: 3, child: Slider( value: fpsValue.value, - min: 5.0, - max: 120.0, - divisions: 23, + min: kMinFps, + max: kMaxFps, + divisions: ((kMaxFps - kMinFps) / 5).round(), onChanged: (double value) async { fpsValue.value = value; debouncerFps.value = value; @@ -145,15 +152,10 @@ customImageQualitySetting() { final fpsKey = 'custom-fps'; var initQuality = - (double.tryParse(bind.mainGetUserDefaultOption(key: qualityKey)) ?? 50.0); - if (initQuality < 10 || initQuality > 2000) { - initQuality = 50; - } - var initFps = - (double.tryParse(bind.mainGetUserDefaultOption(key: fpsKey)) ?? 30.0); - if (initFps < 5 || initFps > 120) { - initFps = 30; - } + (double.tryParse(bind.mainGetUserDefaultOption(key: qualityKey)) ?? + kDefaultQuality); + var initFps = (double.tryParse(bind.mainGetUserDefaultOption(key: fpsKey)) ?? + kDefaultFps); return customImageQualityWidget( initQuality: initQuality, diff --git a/flutter/lib/consts.dart b/flutter/lib/consts.dart index 460894c31..3ea9774bf 100644 --- a/flutter/lib/consts.dart +++ b/flutter/lib/consts.dart @@ -102,6 +102,15 @@ const int kDesktopMaxDisplaySize = 3840; const double kDesktopFileTransferRowHeight = 30.0; const double kDesktopFileTransferHeaderHeight = 25.0; +const double kMinFps = 5; +const double kDefaultFps = 30; +const double kMaxFps = 120; + +const double kMinQuality = 10; +const double kDefaultQuality = 50; +const double kMaxQuality = 100; +const double kMaxMoreQuality = 2000; + double kNewWindowOffset = Platform.isWindows ? 56.0 : Platform.isLinux diff --git a/libs/hbb_common/protos/message.proto b/libs/hbb_common/protos/message.proto index 5fddf2cd4..1433cd1eb 100644 --- a/libs/hbb_common/protos/message.proto +++ b/libs/hbb_common/protos/message.proto @@ -715,7 +715,7 @@ message Misc { Resolution change_resolution = 24; PluginRequest plugin_request = 25; PluginFailure plugin_failure = 26; - uint32 full_speed_fps = 27; + uint32 full_speed_fps = 27; // deprecated uint32 auto_adjust_fps = 28; bool client_record_status = 29; CaptureDisplays capture_displays = 30; diff --git a/src/client.rs b/src/client.rs index f7da1c5dc..58112abaf 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1113,6 +1113,7 @@ pub struct LoginConfigHandler { switch_uuid: Option, pub save_ab_password_to_recent: bool, // true: connected with ab password pub other_server: Option<(String, String, String)>, + pub custom_fps: Arc>>, } impl Deref for LoginConfigHandler { @@ -1483,15 +1484,26 @@ impl LoginConfigHandler { n += 1; } else if q == "custom" { let config = self.load_config(); + let allow_more = + !crate::ui_interface::using_public_server() || self.direct == Some(true); let quality = if config.custom_image_quality.is_empty() { 50 } else { - config.custom_image_quality[0] + let mut quality = config.custom_image_quality[0]; + if !allow_more && quality > 100 { + quality = 50; + } + quality }; msg.custom_image_quality = quality << 8; #[cfg(feature = "flutter")] if let Some(custom_fps) = self.options.get("custom-fps") { - msg.custom_fps = custom_fps.parse().unwrap_or(30); + let mut custom_fps = custom_fps.parse().unwrap_or(30); + if !allow_more && custom_fps > 30 { + custom_fps = 30; + } + msg.custom_fps = custom_fps; + *self.custom_fps.lock().unwrap() = Some(custom_fps as _); } n += 1; } @@ -1678,7 +1690,8 @@ impl LoginConfigHandler { /// # Arguments /// /// * `fps` - The given fps. - pub fn set_custom_fps(&mut self, fps: i32) -> Message { + /// * `save_config` - Save the config. + pub fn set_custom_fps(&mut self, fps: i32, save_config: bool) -> Message { let mut misc = Misc::new(); misc.set_option(OptionMessage { custom_fps: fps, @@ -1686,11 +1699,14 @@ impl LoginConfigHandler { }); 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); + if save_config { + let mut config = self.load_config(); + config + .options + .insert("custom-fps".to_owned(), fps.to_string()); + self.save_config(config); + } + *self.custom_fps.lock().unwrap() = Some(fps as _); msg_out } diff --git a/src/client/io_loop.rs b/src/client/io_loop.rs index d6488e401..721fe6d81 100644 --- a/src/client/io_loop.rs +++ b/src/client/io_loop.rs @@ -939,6 +939,12 @@ impl Remote { #[inline] fn fps_control(&mut self, direct: bool) { + let custom_fps = self.handler.lc.read().unwrap().custom_fps.clone(); + let custom_fps = custom_fps.lock().unwrap().clone(); + let mut custom_fps = custom_fps.unwrap_or(30); + if custom_fps < 5 || custom_fps > 120 { + custom_fps = 30; + } let decode_fps_read = self.decode_fps_map.read().unwrap(); for (display, decode_fps) in decode_fps_read.iter() { let video_queue_map_read = self.video_queue_map.read().unwrap(); @@ -955,32 +961,15 @@ impl Remote { let len = video_queue.len(); let decode_fps = *decode_fps; - let limited_fps = if direct { + let mut limited_fps = if direct { decode_fps * 9 / 10 // 30 got 27 } else { decode_fps * 4 / 5 // 30 got 24 }; - // send full speed fps - let version = self.handler.lc.read().unwrap().version; - let max_encode_speed = 144 * 10 / 9; - if version >= hbb_common::get_version_number("1.2.1") - && (ctl.last_full_speed_fps.is_none() // First time - || ((ctl.last_full_speed_fps.unwrap_or_default() - decode_fps as i32).abs() >= 5 // diff 5 - && !(decode_fps > max_encode_speed // already exceed max encoding speed - && ctl.last_full_speed_fps.unwrap_or_default() > max_encode_speed as i32))) - { - let mut misc = Misc::new(); - misc.set_full_speed_fps(decode_fps as _); - let mut msg = Message::new(); - msg.set_misc(misc); - self.sender.send(Data::Message(msg)).ok(); - ctl.last_full_speed_fps = Some(decode_fps as _); + if limited_fps > custom_fps { + limited_fps = custom_fps; } - // decrease judgement - let debounce = if decode_fps > 10 { decode_fps / 2 } else { 5 }; // 500ms - let should_decrease = len >= debounce // exceed debounce - && len > ctl.last_queue_size + 5 // still caching - && !ctl.last_custom_fps.unwrap_or(i32::MAX) < limited_fps as i32; // NOT already set a smaller one + let should_decrease = len > 1 && ctl.last_auto_fps.unwrap_or(0) > limited_fps as i32; // increase judgement if len <= 1 { @@ -989,35 +978,30 @@ impl Remote { ctl.idle_counter = 0; } let mut should_increase = false; - if let Some(last_custom_fps) = ctl.last_custom_fps { + if let Some(last_auto_fps) = ctl.last_auto_fps { // ever set - if last_custom_fps + 5 < limited_fps as i32 && ctl.idle_counter > 3 { + if last_auto_fps + 3 <= limited_fps as i32 && ctl.idle_counter > 3 { // limited_fps is 5 larger than last set, and idle time is more than 3 seconds should_increase = true; } } - if should_decrease || should_increase { + if ctl.last_auto_fps.is_none() || should_decrease || should_increase { // limited_fps to ensure decoding is faster than encoding - let mut custom_fps = limited_fps as i32; - if custom_fps < 1 { - custom_fps = 1; + let mut auto_fps = limited_fps as i32; + if auto_fps < 1 { + auto_fps = 1; } // send custom fps let mut misc = Misc::new(); - if version > hbb_common::get_version_number("1.2.1") { - // avoid confusion with custom image quality fps - misc.set_auto_adjust_fps(custom_fps as _); - } else { - misc.set_option(OptionMessage { - custom_fps, - ..Default::default() - }); - } + misc.set_option(OptionMessage { + custom_fps: auto_fps, + ..Default::default() + }); let mut msg = Message::new(); msg.set_misc(misc); self.sender.send(Data::Message(msg)).ok(); ctl.last_queue_size = len; - ctl.last_custom_fps = Some(custom_fps); + ctl.last_auto_fps = Some(auto_fps); } // send refresh if ctl.refresh_times < 10 // enough @@ -1805,8 +1789,7 @@ struct FpsControl { last_queue_size: usize, refresh_times: usize, last_refresh_instant: Instant, - last_full_speed_fps: Option, - last_custom_fps: Option, + last_auto_fps: Option, idle_counter: usize, } @@ -1816,8 +1799,7 @@ impl Default for FpsControl { last_queue_size: Default::default(), refresh_times: Default::default(), last_refresh_instant: Instant::now(), - last_full_speed_fps: None, - last_custom_fps: None, + last_auto_fps: None, idle_counter: 0, } } diff --git a/src/server/connection.rs b/src/server/connection.rs index f881a27d0..f55041f41 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -2179,10 +2179,6 @@ impl Connection { crate::plugin::handle_client_event(&p.id, &self.lr.my_id, &p.content); self.send(msg).await; } - Some(misc::Union::FullSpeedFps(fps)) => video_service::VIDEO_QOS - .lock() - .unwrap() - .user_full_speed_fps(self.inner.id(), fps), Some(misc::Union::AutoAdjustFps(fps)) => video_service::VIDEO_QOS .lock() .unwrap() diff --git a/src/server/video_qos.rs b/src/server/video_qos.rs index e9eb9dc79..772948e4b 100644 --- a/src/server/video_qos.rs +++ b/src/server/video_qos.rs @@ -30,8 +30,7 @@ struct Delay { #[derive(Default, Debug, Copy, Clone)] struct UserData { - full_speed_fps: Option, - auto_adjust_fps: Option, + auto_adjust_fps: Option, // reserve for compatibility custom_fps: Option, quality: Option<(i64, Quality)>, // (time, quality) delay: Option, @@ -126,20 +125,14 @@ impl VideoQoS { pub fn refresh(&mut self, typ: Option) { // fps let user_fps = |u: &UserData| { - // full_speed_fps - let mut fps = u.full_speed_fps.unwrap_or_default() * 9 / 10; + // custom_fps + let mut fps = u.custom_fps.unwrap_or(FPS); // auto adjust fps if let Some(auto_adjust_fps) = u.auto_adjust_fps { if fps == 0 || auto_adjust_fps < fps { fps = auto_adjust_fps; } } - // custom_fps - if let Some(custom_fps) = u.custom_fps { - if fps == 0 || custom_fps < fps { - fps = custom_fps; - } - } // delay if let Some(delay) = u.delay { fps = match delay.state { @@ -264,21 +257,6 @@ impl VideoQoS { self.refresh(None); } - pub fn user_full_speed_fps(&mut self, id: i32, full_speed_fps: u32) { - if let Some(user) = self.users.get_mut(&id) { - user.full_speed_fps = Some(full_speed_fps); - } else { - self.users.insert( - id, - UserData { - full_speed_fps: Some(full_speed_fps), - ..Default::default() - }, - ); - } - self.refresh(None); - } - pub fn user_auto_adjust_fps(&mut self, id: i32, fps: u32) { if let Some(user) = self.users.get_mut(&id) { user.auto_adjust_fps = Some(fps); diff --git a/src/ui_session_interface.rs b/src/ui_session_interface.rs index c82b91029..d635af793 100644 --- a/src/ui_session_interface.rs +++ b/src/ui_session_interface.rs @@ -1,4 +1,7 @@ -use crate::{input::{MOUSE_BUTTON_LEFT, MOUSE_TYPE_DOWN, MOUSE_TYPE_UP, MOUSE_TYPE_WHEEL}, common::{is_keyboard_mode_supported, get_supported_keyboard_modes}}; +use crate::{ + common::{get_supported_keyboard_modes, is_keyboard_mode_supported}, + input::{MOUSE_BUTTON_LEFT, MOUSE_TYPE_DOWN, MOUSE_TYPE_UP, MOUSE_TYPE_WHEEL}, +}; use async_trait::async_trait; use bytes::Bytes; use rdev::{Event, EventType::*, KeyCode}; @@ -213,7 +216,7 @@ impl Session { self.lc.read().unwrap().version.clone() } - pub fn fallback_keyboard_mode(&self) -> String { + pub fn fallback_keyboard_mode(&self) -> String { let peer_version = self.get_peer_version(); let platform = self.peer_platform(); @@ -386,14 +389,19 @@ impl Session { } pub fn save_image_quality(&self, value: String) { - let msg = self.lc.write().unwrap().save_image_quality(value); + let msg = self.lc.write().unwrap().save_image_quality(value.clone()); if let Some(msg) = msg { self.send(Data::Message(msg)); } + if value != "custom" { + // non custom quality use 30 fps + let msg = self.lc.write().unwrap().set_custom_fps(30, false); + self.send(Data::Message(msg)); + } } pub fn set_custom_fps(&self, custom_fps: i32) { - let msg = self.lc.write().unwrap().set_custom_fps(custom_fps); + let msg = self.lc.write().unwrap().set_custom_fps(custom_fps, true); self.send(Data::Message(msg)); }