commit
						217a9808b2
					
				@ -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,
 | 
			
		||||
 | 
			
		||||
@ -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<double>(
 | 
			
		||||
    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,
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
@ -1113,6 +1113,7 @@ pub struct LoginConfigHandler {
 | 
			
		||||
    switch_uuid: Option<String>,
 | 
			
		||||
    pub save_ab_password_to_recent: bool, // true: connected with ab password
 | 
			
		||||
    pub other_server: Option<(String, String, String)>,
 | 
			
		||||
    pub custom_fps: Arc<Mutex<Option<usize>>>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -939,6 +939,12 @@ impl<T: InvokeUiSession> Remote<T> {
 | 
			
		||||
 | 
			
		||||
    #[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<T: InvokeUiSession> Remote<T> {
 | 
			
		||||
 | 
			
		||||
            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<T: InvokeUiSession> Remote<T> {
 | 
			
		||||
                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<i32>,
 | 
			
		||||
    last_custom_fps: Option<i32>,
 | 
			
		||||
    last_auto_fps: Option<i32>,
 | 
			
		||||
    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,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -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()
 | 
			
		||||
 | 
			
		||||
@ -30,8 +30,7 @@ struct Delay {
 | 
			
		||||
 | 
			
		||||
#[derive(Default, Debug, Copy, Clone)]
 | 
			
		||||
struct UserData {
 | 
			
		||||
    full_speed_fps: Option<u32>,
 | 
			
		||||
    auto_adjust_fps: Option<u32>,
 | 
			
		||||
    auto_adjust_fps: Option<u32>, // reserve for compatibility
 | 
			
		||||
    custom_fps: Option<u32>,
 | 
			
		||||
    quality: Option<(i64, Quality)>, // (time, quality)
 | 
			
		||||
    delay: Option<Delay>,
 | 
			
		||||
@ -126,20 +125,14 @@ impl VideoQoS {
 | 
			
		||||
    pub fn refresh(&mut self, typ: Option<RefreshType>) {
 | 
			
		||||
        // 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);
 | 
			
		||||
 | 
			
		||||
@ -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<T: InvokeUiSession> Session<T> {
 | 
			
		||||
        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<T: InvokeUiSession> Session<T> {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user