Merge pull request #3 from Heap-Hop/hwcodec
Hwcodec: show codec name && add hwcodec option
This commit is contained in:
commit
6c9e601c59
@ -479,10 +479,18 @@ message OptionMessage {
|
||||
}
|
||||
|
||||
message TestDelay {
|
||||
enum CodecFormat {
|
||||
Unknown = 0;
|
||||
VP8 = 1;
|
||||
VP9 = 2;
|
||||
H264 = 3;
|
||||
H265 = 4;
|
||||
}
|
||||
int64 time = 1;
|
||||
bool from_client = 2;
|
||||
uint32 last_delay = 3;
|
||||
uint32 target_bitrate = 4;
|
||||
CodecFormat codec_format = 5;
|
||||
}
|
||||
|
||||
message PublicKey {
|
||||
|
@ -12,11 +12,12 @@ use crate::vpxcodec::*;
|
||||
use hbb_common::{
|
||||
anyhow::anyhow,
|
||||
log,
|
||||
message_proto::{video_frame, Message, VP9s, VideoCodecState},
|
||||
message_proto::{test_delay, video_frame, Message, VP9s, VideoCodecState},
|
||||
ResultType,
|
||||
};
|
||||
#[cfg(feature = "hwcodec")]
|
||||
use hbb_common::{
|
||||
config::Config2,
|
||||
lazy_static,
|
||||
message_proto::{H264s, H265s},
|
||||
};
|
||||
@ -52,6 +53,8 @@ pub trait EncoderApi {
|
||||
fn use_yuv(&self) -> bool;
|
||||
|
||||
fn set_bitrate(&mut self, bitrate: u32) -> ResultType<()>;
|
||||
|
||||
fn get_codec_format(&self) -> test_delay::CodecFormat;
|
||||
}
|
||||
|
||||
pub struct DecoderCfg {
|
||||
@ -185,7 +188,11 @@ impl Encoder {
|
||||
#[inline]
|
||||
pub fn current_hw_encoder_name() -> Option<String> {
|
||||
#[cfg(feature = "hwcodec")]
|
||||
return HwEncoder::current_name().lock().unwrap().clone();
|
||||
if check_hwcodec_config() {
|
||||
return HwEncoder::current_name().lock().unwrap().clone();
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
#[cfg(not(feature = "hwcodec"))]
|
||||
return None;
|
||||
}
|
||||
@ -206,7 +213,14 @@ impl Decoder {
|
||||
// video_codec_state is mainted by creation and destruction of Decoder.
|
||||
// It has been ensured to use after Decoder's creation.
|
||||
#[cfg(feature = "hwcodec")]
|
||||
return MY_DECODER_STATE.lock().unwrap().clone();
|
||||
if check_hwcodec_config() {
|
||||
return MY_DECODER_STATE.lock().unwrap().clone();
|
||||
} else {
|
||||
return VideoCodecState {
|
||||
ScoreVpx: SCORE_VPX,
|
||||
..Default::default()
|
||||
};
|
||||
}
|
||||
#[cfg(not(feature = "hwcodec"))]
|
||||
VideoCodecState {
|
||||
ScoreVpx: SCORE_VPX,
|
||||
@ -328,3 +342,11 @@ impl Decoder {
|
||||
return Ok(ret);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "hwcodec")]
|
||||
fn check_hwcodec_config() -> bool {
|
||||
if let Some(v) = Config2::get().options.get("enable-hwcodec") {
|
||||
return v != "N";
|
||||
}
|
||||
return true; // default is true
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ use hbb_common::{
|
||||
anyhow::{anyhow, Context},
|
||||
config::HwCodecConfig,
|
||||
lazy_static, log,
|
||||
message_proto::{H264s, H265s, Message, VideoFrame, H264, H265},
|
||||
message_proto::{test_delay, H264s, H265s, Message, VideoFrame, H264, H265},
|
||||
ResultType,
|
||||
};
|
||||
use hwcodec::{
|
||||
@ -143,6 +143,13 @@ impl EncoderApi for HwEncoder {
|
||||
self.encoder.set_bitrate((bitrate * 1000) as _).ok();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_codec_format(&self) -> test_delay::CodecFormat {
|
||||
match self.format {
|
||||
DataFormat::H264 => test_delay::CodecFormat::H264,
|
||||
DataFormat::H265 => test_delay::CodecFormat::H265,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl HwEncoder {
|
||||
|
@ -3,7 +3,7 @@
|
||||
// https://github.com/rust-av/vpx-rs/blob/master/src/decoder.rs
|
||||
|
||||
use hbb_common::anyhow::{anyhow, Context};
|
||||
use hbb_common::message_proto::{Message, VP9s, VideoFrame, VP9};
|
||||
use hbb_common::message_proto::{test_delay, Message, VP9s, VideoFrame, VP9};
|
||||
use hbb_common::ResultType;
|
||||
|
||||
use crate::codec::EncoderApi;
|
||||
@ -27,6 +27,7 @@ impl Default for VpxVideoCodecId {
|
||||
|
||||
pub struct VpxEncoder {
|
||||
ctx: vpx_codec_ctx_t,
|
||||
format: VpxVideoCodecId,
|
||||
width: usize,
|
||||
height: usize,
|
||||
}
|
||||
@ -96,14 +97,17 @@ impl EncoderApi for VpxEncoder {
|
||||
{
|
||||
match cfg {
|
||||
crate::codec::EncoderCfg::VPX(config) => {
|
||||
let format;
|
||||
let i;
|
||||
if cfg!(feature = "VP8") {
|
||||
i = match config.codec {
|
||||
VpxVideoCodecId::VP8 => call_vpx_ptr!(vpx_codec_vp8_cx()),
|
||||
VpxVideoCodecId::VP9 => call_vpx_ptr!(vpx_codec_vp9_cx()),
|
||||
};
|
||||
format = config.codec;
|
||||
} else {
|
||||
i = call_vpx_ptr!(vpx_codec_vp9_cx());
|
||||
format = VpxVideoCodecId::VP9;
|
||||
}
|
||||
let mut c = unsafe { std::mem::MaybeUninit::zeroed().assume_init() };
|
||||
call_vpx!(vpx_codec_enc_config_default(i, &mut c, 0));
|
||||
@ -190,6 +194,7 @@ impl EncoderApi for VpxEncoder {
|
||||
|
||||
Ok(Self {
|
||||
ctx,
|
||||
format,
|
||||
width: config.width as _,
|
||||
height: config.height as _,
|
||||
})
|
||||
@ -228,6 +233,13 @@ impl EncoderApi for VpxEncoder {
|
||||
call_vpx!(vpx_codec_enc_config_set(&mut self.ctx, &new_enc_cfg));
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
fn get_codec_format(&self) -> test_delay::CodecFormat {
|
||||
match self.format {
|
||||
VpxVideoCodecId::VP8 => test_delay::CodecFormat::VP8,
|
||||
VpxVideoCodecId::VP9 => test_delay::CodecFormat::VP9,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl VpxEncoder {
|
||||
|
@ -914,7 +914,7 @@ impl LoginConfigHandler {
|
||||
n += 1;
|
||||
} else if q == "custom" {
|
||||
let config = PeerConfig::load(&self.id);
|
||||
msg.custom_image_quality = config.custom_image_quality[0] as _;
|
||||
msg.custom_image_quality = config.custom_image_quality[0] << 8;
|
||||
n += 1;
|
||||
}
|
||||
if self.get_toggle_option("show-remote-cursor") {
|
||||
@ -1212,6 +1212,14 @@ where
|
||||
return (video_sender, audio_sender);
|
||||
}
|
||||
|
||||
pub async fn handle_test_delay(t: TestDelay, peer: &mut Stream) {
|
||||
if !t.from_client {
|
||||
let mut msg_out = Message::new();
|
||||
msg_out.set_test_delay(t);
|
||||
allow_err!(peer.send(&msg_out).await);
|
||||
}
|
||||
}
|
||||
|
||||
// mask = buttons << 3 | type
|
||||
// type, 1: down, 2: up, 3: wheel
|
||||
// buttons, 1: left, 2: right, 4: middle
|
||||
|
@ -35,6 +35,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("About", "关于"),
|
||||
("Mute", "静音"),
|
||||
("Audio Input", "音频输入"),
|
||||
("Enhancements", "增强功能"),
|
||||
("Hardware Codec", "硬件编解码"),
|
||||
("Adaptive Bitrate", "自适应码率"),
|
||||
("ID Server", "ID服务器"),
|
||||
("Relay Server", "中继服务器"),
|
||||
("API Server", "API服务器"),
|
||||
@ -105,6 +108,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Optimize reaction time", "优化反应时间"),
|
||||
("Custom", "自定义画质"),
|
||||
("Show remote cursor", "显示远程光标"),
|
||||
("Show quality monitor", "显示质量监测"),
|
||||
("Disable clipboard", "禁止剪贴板"),
|
||||
("Lock after session end", "断开后锁定远程电脑"),
|
||||
("Insert", "插入"),
|
||||
|
@ -35,6 +35,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("About", "O aplikaci"),
|
||||
("Mute", "Ztlumit"),
|
||||
("Audio Input", "Vstup zvuku"),
|
||||
("Enhancements", ""),
|
||||
("Hardware Codec", ""),
|
||||
("Adaptive Bitrate", ""),
|
||||
("ID Server", "Server pro identif."),
|
||||
("Relay Server", "Předávací (relay) server"),
|
||||
("API Server", "Server s API rozhraním"),
|
||||
@ -105,6 +108,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Optimize reaction time", "Optimalizovat pro co nejnižší prodlevu odezvy"),
|
||||
("Custom", "Uživatelsky určené"),
|
||||
("Show remote cursor", "Zobrazovat ukazatel myši z protějšku"),
|
||||
("Show quality monitor", ""),
|
||||
("Disable clipboard", "Vypnout schránku"),
|
||||
("Lock after session end", "Po ukončení relace zamknout plochu"),
|
||||
("Insert", "Vložit"),
|
||||
|
@ -35,6 +35,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("About", "Omkring"),
|
||||
("Mute", "Sluk for mikrofonen"),
|
||||
("Audio Input", "Lydindgang"),
|
||||
("Enhancements", ""),
|
||||
("Hardware Codec", ""),
|
||||
("Adaptive Bitrate", ""),
|
||||
("ID Server", "identifikations Server"),
|
||||
("Relay Server", "Relæ Server"),
|
||||
("API Server", "API Server"),
|
||||
@ -105,6 +108,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Optimize reaction time", "Optimeret responstid"),
|
||||
("Custom", "Brugerdefineret"),
|
||||
("Show remote cursor", "Vis fjernbetjeningskontrolleret markør"),
|
||||
("Show quality monitor", ""),
|
||||
("Disable clipboard", "Deaktiver udklipsholder"),
|
||||
("Lock after session end", "Lås efter afslutningen af fjernstyring"),
|
||||
("Insert", "Indsæt"),
|
||||
|
@ -35,6 +35,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("About", "Über"),
|
||||
("Mute", "Stummschalten"),
|
||||
("Audio Input", "Audio-Eingang"),
|
||||
("Enhancements", ""),
|
||||
("Hardware Codec", ""),
|
||||
("Adaptive Bitrate", ""),
|
||||
("ID Server", "ID Server"),
|
||||
("Relay Server", "Verbindungsserver Server"),
|
||||
("API Server", "API Server"),
|
||||
@ -105,6 +108,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Optimize reaction time", "Optimierte Reaktionszeit"),
|
||||
("Custom", "Benutzerdefiniert"),
|
||||
("Show remote cursor", "Ferngesteuerten Cursor anzeigen"),
|
||||
("Show quality monitor", ""),
|
||||
("Disable clipboard", "Zwischenablage deaktivieren"),
|
||||
("Lock after session end", "Sperren nach Sitzungsende"),
|
||||
("Insert", "Einfügen"),
|
||||
|
@ -35,6 +35,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("About", "Pri"),
|
||||
("Mute", "Muta"),
|
||||
("Audio Input", "Aŭdia enigo"),
|
||||
("Enhancements", ""),
|
||||
("Hardware Codec", ""),
|
||||
("Adaptive Bitrate", ""),
|
||||
("ID Server", "Servilo de identigiloj"),
|
||||
("Relay Server", "Relajsa servilo"),
|
||||
("API Server", "Servilo de API"),
|
||||
@ -105,6 +108,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Optimize reaction time", "Optimigi reakcia tempo"),
|
||||
("Custom", "Personigi bilda kvalito"),
|
||||
("Show remote cursor", "Montri foran kursoron"),
|
||||
("Show quality monitor", ""),
|
||||
("Disable clipboard", "Malebligi poŝon"),
|
||||
("Lock after session end", "Ŝlosi foran komputilon post malkonektado"),
|
||||
("Insert", "Enmeti"),
|
||||
|
@ -35,6 +35,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("About", "Sobre"),
|
||||
("Mute", "Silencio"),
|
||||
("Audio Input", "Entrada de audio"),
|
||||
("Enhancements", ""),
|
||||
("Hardware Codec", ""),
|
||||
("Adaptive Bitrate", ""),
|
||||
("ID Server", "ID server"),
|
||||
("Relay Server", "Server relay"),
|
||||
("API Server", "Server API"),
|
||||
@ -105,6 +108,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Optimize reaction time", "Optimizar el tiempo de reacción"),
|
||||
("Custom", "Personalizado"),
|
||||
("Show remote cursor", "Mostrar cursor remoto"),
|
||||
("Show quality monitor", ""),
|
||||
("Disable clipboard", "Deshabilitar portapapeles"),
|
||||
("Lock after session end", "Bloquear después del final de la sesión"),
|
||||
("Insert", "Insertar"),
|
||||
|
@ -35,6 +35,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("About", "À propos de"),
|
||||
("Mute", "Muet"),
|
||||
("Audio Input", "Entrée audio"),
|
||||
("Enhancements", ""),
|
||||
("Hardware Codec", ""),
|
||||
("Adaptive Bitrate", ""),
|
||||
("ID Server", "Serveur ID"),
|
||||
("Relay Server", "Serveur relais"),
|
||||
("API Server", "Serveur API"),
|
||||
@ -105,6 +108,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Optimize reaction time", "Optimiser le temps de réaction"),
|
||||
("Custom", "Qualité d'image personnalisée"),
|
||||
("Show remote cursor", "Afficher le curseur distant"),
|
||||
("Show quality monitor", ""),
|
||||
("Disable clipboard", "Désactiver le presse-papier"),
|
||||
("Lock after session end", "Verrouiller l'ordinateur distant après la déconnexion"),
|
||||
("Insert", "Insérer"),
|
||||
|
@ -35,6 +35,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("About", "Tentang"),
|
||||
("Mute", "Bisukan"),
|
||||
("Audio Input", "Masukkan Audio"),
|
||||
("Enhancements", ""),
|
||||
("Hardware Codec", ""),
|
||||
("Adaptive Bitrate", ""),
|
||||
("ID Server", "Server ID"),
|
||||
("Relay Server", "Server Relay"),
|
||||
("API Server", "API Server"),
|
||||
@ -105,6 +108,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Optimize reaction time", "Optimalkan waktu reaksi"),
|
||||
("Custom", "Custom"),
|
||||
("Show remote cursor", "Tampilkan remote kursor"),
|
||||
("Show quality monitor", ""),
|
||||
("Disable clipboard", "Matikan papan klip"),
|
||||
("Lock after session end", "Kunci setelah sesi berakhir"),
|
||||
("Insert", "Menyisipkan"),
|
||||
@ -158,7 +162,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Allow using clipboard", "Izinkan menggunakan papan klip"),
|
||||
("Allow hearing sound", "Izinkan mendengarkan suara"),
|
||||
("Allow file copy and paste", "Izinkan penyalinan dan tempel file"),
|
||||
("File transfer", "Transfer file"),
|
||||
("Connected", "Terkoneksi"),
|
||||
("Direct and encrypted connection", "Koneksi langsung dan terenkripsi"),
|
||||
("Relayed and encrypted connection", "Koneksi relai dan terenkripsi"),
|
||||
|
@ -35,6 +35,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("About", "Informazioni"),
|
||||
("Mute", "Silenzia"),
|
||||
("Audio Input", "Input audio"),
|
||||
("Enhancements", ""),
|
||||
("Hardware Codec", ""),
|
||||
("Adaptive Bitrate", ""),
|
||||
("ID Server", "ID server"),
|
||||
("Relay Server", "Server relay"),
|
||||
("API Server", "Server API"),
|
||||
@ -105,6 +108,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Optimize reaction time", "Ottimizza il tempo di reazione"),
|
||||
("Custom", "Personalizzato"),
|
||||
("Show remote cursor", "Mostra il cursore remoto"),
|
||||
("Show quality monitor", ""),
|
||||
("Disable clipboard", "Disabilita appunti"),
|
||||
("Lock after session end", "Blocca al termine della sessione"),
|
||||
("Insert", "Inserisci"),
|
||||
|
@ -35,6 +35,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("About", "Sobre"),
|
||||
("Mute", "Emudecer"),
|
||||
("Audio Input", "Entrada de Áudio"),
|
||||
("Enhancements", ""),
|
||||
("Hardware Codec", ""),
|
||||
("Adaptive Bitrate", ""),
|
||||
("ID Server", "Servidor de ID"),
|
||||
("Relay Server", "Servidor de Relay"),
|
||||
("API Server", "Servidor da API"),
|
||||
@ -105,6 +108,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Optimize reaction time", "Otimizar tempo de reação"),
|
||||
("Custom", "Personalizado"),
|
||||
("Show remote cursor", "Mostrar cursor remoto"),
|
||||
("Show quality monitor", ""),
|
||||
("Disable clipboard", "Desabilitar área de transferência"),
|
||||
("Lock after session end", "Bloquear após o fim da sessão"),
|
||||
("Insert", "Inserir"),
|
||||
|
@ -35,6 +35,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("About", "О RustDesk"),
|
||||
("Mute", "Отключить звук"),
|
||||
("Audio Input", "Аудиовход"),
|
||||
("Enhancements", ""),
|
||||
("Hardware Codec", ""),
|
||||
("Adaptive Bitrate", ""),
|
||||
("ID Server", "ID-сервер"),
|
||||
("Relay Server", "Сервер ретрансляции"),
|
||||
("API Server", "API-сервер"),
|
||||
@ -105,6 +108,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Optimize reaction time", "Оптимизировать время реакции"),
|
||||
("Custom", "Пользовательский"),
|
||||
("Show remote cursor", "Показать удаленный курсор"),
|
||||
("Show quality monitor", ""),
|
||||
("Disable clipboard", "Отключить буфер обмена"),
|
||||
("Lock after session end", "Выход из учётной записи после завершения сеанса"),
|
||||
("Insert", "Вставить"),
|
||||
@ -263,9 +267,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("android_version_audio_tip", "Текущая версия Android не поддерживает захват звука, обновите ее до Android 10 или выше."),
|
||||
("android_start_service_tip", "Нажмите [Запуск промежуточного сервера] или ОТКРЫТЬ разрешение [Захват экрана], чтобы запустить службу демонстрации экрана."),
|
||||
("Account", "Аккаунт"),
|
||||
("Quit", "Выйти"),
|
||||
("Overwrite", "Перезаписать"),
|
||||
("This file exists, skip or overwrite this file?", "Этот файл существует, пропустить или перезаписать этот файл?"),
|
||||
("Quit", "Выйти"),
|
||||
("doc_mac_permission", "https://rustdesk.com/docs/ru/manual/mac/#включение-разрешений"),
|
||||
("Help", "Помощь"),
|
||||
("Failed", "Неуспешный"),
|
||||
|
@ -35,6 +35,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("About", "O RustDesk"),
|
||||
("Mute", "Stíšiť"),
|
||||
("Audio Input", "Zvukový vstup"),
|
||||
("Enhancements", ""),
|
||||
("Hardware Codec", ""),
|
||||
("Adaptive Bitrate", ""),
|
||||
("ID Server", "ID server"),
|
||||
("Relay Server", "Prepojovací server"),
|
||||
("API Server", "API server"),
|
||||
@ -105,6 +108,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Optimize reaction time", "Optimalizované pre čas odozvy"),
|
||||
("Custom", "Vlastné"),
|
||||
("Show remote cursor", "Zobrazovať vzdialený ukazovateľ myši"),
|
||||
("Show quality monitor", ""),
|
||||
("Disable clipboard", "Vypnúť schránku"),
|
||||
("Lock after session end", "Po skončení uzamknúť plochu"),
|
||||
("Insert", "Vložiť"),
|
||||
|
@ -35,6 +35,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("About", ""),
|
||||
("Mute", ""),
|
||||
("Audio Input", ""),
|
||||
("Enhancements", ""),
|
||||
("Hardware Codec", ""),
|
||||
("Adaptive Bitrate", ""),
|
||||
("ID Server", ""),
|
||||
("Relay Server", ""),
|
||||
("API Server", ""),
|
||||
@ -105,6 +108,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Optimize reaction time", ""),
|
||||
("Custom", ""),
|
||||
("Show remote cursor", ""),
|
||||
("Show quality monitor", ""),
|
||||
("Disable clipboard", ""),
|
||||
("Lock after session end", ""),
|
||||
("Insert", ""),
|
||||
@ -264,7 +268,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("android_start_service_tip", ""),
|
||||
("Account", ""),
|
||||
("Overwrite", ""),
|
||||
("This file exists, skip or overwrite this file?", "")
|
||||
("This file exists, skip or overwrite this file?", ""),
|
||||
("Quit", ""),
|
||||
("doc_mac_permission", ""),
|
||||
("Help", ""),
|
||||
|
@ -35,6 +35,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("About", "Hakkında"),
|
||||
("Mute", "Sesi Kapat"),
|
||||
("Audio Input", "Ses Girişi"),
|
||||
("Enhancements", ""),
|
||||
("Hardware Codec", ""),
|
||||
("Adaptive Bitrate", ""),
|
||||
("ID Server", "ID Sunucu"),
|
||||
("Relay Server", "Relay Sunucu"),
|
||||
("API Server", "API Sunucu"),
|
||||
@ -105,6 +108,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Optimize reaction time", "Tepki süresini optimize et"),
|
||||
("Custom", "Özel"),
|
||||
("Show remote cursor", "Uzaktaki fare imlecini göster"),
|
||||
("Show quality monitor", ""),
|
||||
("Disable clipboard", "Hafızadaki kopyalanmışları engelle"),
|
||||
("Lock after session end", "Bağlantıdan sonra kilitle"),
|
||||
("Insert", "Ekle"),
|
||||
|
@ -35,6 +35,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("About", "關於"),
|
||||
("Mute", "靜音"),
|
||||
("Audio Input", "音訊輸入"),
|
||||
("Enhancements", "增強功能"),
|
||||
("Hardware Codec", "硬件編解碼"),
|
||||
("Adaptive Bitrate", "自適應碼率"),
|
||||
("ID Server", "ID 伺服器"),
|
||||
("Relay Server", "轉送伺服器"),
|
||||
("API Server", "API 伺服器"),
|
||||
@ -105,6 +108,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("Optimize reaction time", "回應速度最佳化"),
|
||||
("Custom", "自訂"),
|
||||
("Show remote cursor", "顯示遠端游標"),
|
||||
("Show quality monitor", "顯示質量監測"),
|
||||
("Disable clipboard", "停用剪貼簿"),
|
||||
("Lock after session end", "工作階段結束後鎖定電腦"),
|
||||
("Insert", "插入"),
|
||||
@ -262,13 +266,12 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("android_stop_service_tip", "關閉服務將自動關閉所有已建立的連接。"),
|
||||
("android_version_audio_tip", "目前的 Android 版本不支持音訊錄製,請升級至 Android 10 或以上版本。"),
|
||||
("android_start_service_tip", "點擊 「啟動服務」 或啟用 「畫面錄製」 權限以開啟手機畫面共享服務。"),
|
||||
("Account", "帳號"),
|
||||
("Quit", "退出"),
|
||||
("Account", "帳戶"),
|
||||
("Overwrite", "覆寫"),
|
||||
("This file exists, skip or overwrite this file?", "此檔案/資料夾已存在,要跳過或是覆寫此檔案嗎?"),
|
||||
("Quit", "退出"),
|
||||
("doc_mac_permission", "https://rustdesk.com/docs/zh-tw/manual/mac/#啟用權限"),
|
||||
("Help", "幫助"),
|
||||
("Account", "帳戶"),
|
||||
("Failed", "失敗"),
|
||||
("Succeeded", "成功"),
|
||||
("Someone turns on privacy mode, exit", "其他用戶開啟隱私模式,退出"),
|
||||
|
@ -380,6 +380,7 @@ impl Connection {
|
||||
time,
|
||||
last_delay:qos.current_delay,
|
||||
target_bitrate:qos.target_bitrate,
|
||||
codec_format:qos.codec_format.into(),
|
||||
..Default::default()
|
||||
});
|
||||
conn.inner.send(msg_out.into());
|
||||
|
@ -72,11 +72,11 @@ pub struct VideoQoS {
|
||||
height: u32,
|
||||
user_image_quality: u32,
|
||||
current_image_quality: u32,
|
||||
|
||||
enable_abr: bool,
|
||||
pub codec_format: test_delay::CodecFormat,
|
||||
pub current_delay: u32,
|
||||
pub fps: u8, // abr
|
||||
pub target_bitrate: u32, // abr
|
||||
|
||||
updated: bool,
|
||||
state: DelayState,
|
||||
debounce_count: u32,
|
||||
@ -110,6 +110,8 @@ impl Default for VideoQoS {
|
||||
fps: FPS,
|
||||
user_image_quality: ImageQuality::Balanced.as_percent(),
|
||||
current_image_quality: ImageQuality::Balanced.as_percent(),
|
||||
enable_abr: false,
|
||||
codec_format: Default::default(),
|
||||
width: 0,
|
||||
height: 0,
|
||||
current_delay: 0,
|
||||
@ -137,6 +139,8 @@ impl VideoQoS {
|
||||
time::Duration::from_secs_f32(1. / (self.fps as f32))
|
||||
}
|
||||
|
||||
// update_network_delay periodically
|
||||
// decrease the bitrate when the delay gets bigger
|
||||
pub fn update_network_delay(&mut self, delay: u32) {
|
||||
if self.current_delay.eq(&0) {
|
||||
self.current_delay = delay;
|
||||
@ -145,14 +149,16 @@ impl VideoQoS {
|
||||
|
||||
self.current_delay = delay / 2 + self.current_delay / 2;
|
||||
log::trace!(
|
||||
"VideoQoS update_network_delay:{}, {}, state:{:?},count:{}",
|
||||
"VideoQoS update_network_delay:{}, {}, state:{:?}",
|
||||
self.current_delay,
|
||||
delay,
|
||||
self.state,
|
||||
self.debounce_count
|
||||
);
|
||||
|
||||
// ABR
|
||||
if !self.enable_abr {
|
||||
return;
|
||||
}
|
||||
let current_state = DelayState::from_delay(self.current_delay);
|
||||
if current_state != self.state && self.debounce_count > 5 {
|
||||
log::debug!(
|
||||
@ -191,9 +197,10 @@ impl VideoQoS {
|
||||
self.updated = true;
|
||||
}
|
||||
|
||||
// handle image_quality change from peer
|
||||
pub fn update_image_quality(&mut self, image_quality: i32) {
|
||||
let image_quality = Self::convert_quality(image_quality) as _;
|
||||
log::debug!("VideoQoS update_image_quality{}", image_quality);
|
||||
log::debug!("VideoQoS update_image_quality: {}", image_quality);
|
||||
if self.current_image_quality != image_quality {
|
||||
self.current_image_quality = image_quality;
|
||||
let _ = self.generate_bitrate().ok();
|
||||
@ -220,11 +227,14 @@ impl VideoQoS {
|
||||
let fix = Display::fix_quality() as u32;
|
||||
log::debug!("Android screen, fix quality:{}", fix);
|
||||
let base_bitrate = base_bitrate * fix;
|
||||
self.target_bitrate = base_bitrate * self.image_quality / 100;
|
||||
self.target_bitrate = base_bitrate * self.current_image_quality / 100;
|
||||
Ok(self.target_bitrate)
|
||||
}
|
||||
#[cfg(not(target_os = "android"))]
|
||||
{
|
||||
self.target_bitrate = base_bitrate * self.current_image_quality / 100;
|
||||
Ok(self.target_bitrate)
|
||||
}
|
||||
self.target_bitrate = base_bitrate * self.current_image_quality / 100;
|
||||
Ok(self.target_bitrate)
|
||||
}
|
||||
|
||||
pub fn check_if_updated(&mut self) -> bool {
|
||||
@ -239,6 +249,15 @@ impl VideoQoS {
|
||||
*self = Default::default();
|
||||
}
|
||||
|
||||
fn check_abr_config(&mut self) -> bool {
|
||||
self.enable_abr = if let Some(v) = Config2::get().options.get("enable-abr") {
|
||||
v != "N"
|
||||
} else {
|
||||
true // default is true
|
||||
};
|
||||
self.enable_abr
|
||||
}
|
||||
|
||||
pub fn convert_quality(q: i32) -> i32 {
|
||||
if q == ImageQuality::Balanced.value() {
|
||||
100 * 2 / 3
|
||||
@ -544,9 +563,9 @@ fn run(sp: GenericService) -> ResultType<()> {
|
||||
video_qos.set_size(width as _, height as _);
|
||||
let mut spf = video_qos.spf();
|
||||
let bitrate = video_qos.generate_bitrate()?;
|
||||
drop(video_qos);
|
||||
let abr = video_qos.check_abr_config();
|
||||
|
||||
log::info!("init bitrate={}", bitrate);
|
||||
log::info!("init bitrate={}, abr enabled:{}", bitrate, abr);
|
||||
|
||||
let encoder_cfg = match Encoder::current_hw_encoder_name() {
|
||||
Some(codec_name) => EncoderCfg::HW(HwEncoderConfig {
|
||||
@ -571,6 +590,9 @@ fn run(sp: GenericService) -> ResultType<()> {
|
||||
Err(err) => bail!("Failed to create encoder: {}", err),
|
||||
}
|
||||
|
||||
video_qos.codec_format = encoder.get_codec_format();
|
||||
drop(video_qos);
|
||||
|
||||
let privacy_mode_id = *PRIVACY_MODE_CONN_ID.lock().unwrap();
|
||||
#[cfg(not(windows))]
|
||||
let captuerer_privacy_mode_id = privacy_mode_id;
|
||||
|
10
src/ui.rs
10
src/ui.rs
@ -702,7 +702,7 @@ impl UI {
|
||||
let p = "explorer";
|
||||
#[cfg(target_os = "macos")]
|
||||
let p = "open";
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(target_os = "linux")]
|
||||
let p = if std::path::Path::new("/usr/bin/firefox").exists() {
|
||||
"firefox"
|
||||
} else {
|
||||
@ -753,6 +753,13 @@ impl UI {
|
||||
self.get_option_("custom-rendezvous-server"),
|
||||
)
|
||||
}
|
||||
|
||||
fn has_hwcodec(&self) -> bool {
|
||||
#[cfg(not(feature = "hwcodec"))]
|
||||
return false;
|
||||
#[cfg(feature = "hwcodec")]
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
impl sciter::EventHandler for UI {
|
||||
@ -829,6 +836,7 @@ impl sciter::EventHandler for UI {
|
||||
fn discover();
|
||||
fn get_lan_peers();
|
||||
fn get_uuid();
|
||||
fn has_hwcodec();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -165,6 +165,44 @@ class AudioInputs: Reactor.Component {
|
||||
}
|
||||
}
|
||||
|
||||
var enhancementsMenu;
|
||||
class Enhancements: Reactor.Component {
|
||||
function this() {
|
||||
enhancementsMenu = this;
|
||||
}
|
||||
|
||||
function render() {
|
||||
var has_hwcodec = handler.has_hwcodec();
|
||||
var me = this;
|
||||
self.timer(1ms, function() { me.toggleMenuState() });
|
||||
return <li>{translate('Enhancements')}
|
||||
<menu #enhancements-menu>
|
||||
{has_hwcodec ? <li #enable-hwcodec><span>{svg_checkmark}</span>{translate("Hardware Codec")}{"(beta)"}</li> : ""}
|
||||
<li #enable-abr><span>{svg_checkmark}</span>{translate("Adaptive Bitrate")}{"(beta)"}</li>
|
||||
</menu>
|
||||
</li>;
|
||||
}
|
||||
|
||||
function toggleMenuState() {
|
||||
for (var el in $$(menu#enhancements-menu>li)) {
|
||||
if (el.id && el.id.indexOf("enable-") == 0) {
|
||||
var enabled = handler.get_option(el.id) != "N";
|
||||
el.attributes.toggleClass("selected", enabled);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
event click $(menu#enhancements-menu>li) (_, me) {
|
||||
var v = me.id;
|
||||
if (v.indexOf("enable-") == 0) {
|
||||
handler.set_option(v, handler.get_option(v) != 'N' ? 'N' : '');
|
||||
}
|
||||
this.toggleMenuState();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function getUserName() {
|
||||
try {
|
||||
return JSON.parse(handler.get_local_option("user_info")).name;
|
||||
@ -204,6 +242,7 @@ class MyIdMenu: Reactor.Component {
|
||||
<li #enable-file-transfer><span>{svg_checkmark}</span>{translate('Enable File Transfer')}</li>
|
||||
<li #enable-tunnel><span>{svg_checkmark}</span>{translate('Enable TCP Tunneling')}</li>
|
||||
<AudioInputs />
|
||||
<Enhancements />
|
||||
<li #allow-remote-config-modification><span>{svg_checkmark}</span>{translate('Enable remote configuration modification')}</li>
|
||||
<div .separator />
|
||||
<li #custom-server>{translate('ID/Relay Server')}</li>
|
||||
|
@ -240,6 +240,7 @@ struct QualityStatus {
|
||||
fps: i32,
|
||||
delay: i32,
|
||||
target_bitrate: i32,
|
||||
codec_format: test_delay::CodecFormat,
|
||||
}
|
||||
|
||||
impl Default for QualityStatus {
|
||||
@ -249,6 +250,7 @@ impl Default for QualityStatus {
|
||||
fps: -1,
|
||||
delay: -1,
|
||||
target_bitrate: -1,
|
||||
codec_format: test_delay::CodecFormat::Unknown,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -269,13 +271,21 @@ impl Handler {
|
||||
}
|
||||
|
||||
fn update_quality_status(&self, status: QualityStatus) {
|
||||
let codec_format = match status.codec_format {
|
||||
test_delay::CodecFormat::Unknown => "Unknown",
|
||||
test_delay::CodecFormat::VP8 => "VP8",
|
||||
test_delay::CodecFormat::VP9 => "VP9",
|
||||
test_delay::CodecFormat::H264 => "H264",
|
||||
test_delay::CodecFormat::H265 => "H265",
|
||||
};
|
||||
self.call2(
|
||||
"updateQualityStatus",
|
||||
&make_args!(
|
||||
status.speed,
|
||||
status.fps,
|
||||
status.delay,
|
||||
status.target_bitrate
|
||||
status.target_bitrate,
|
||||
codec_format
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -2604,11 +2614,10 @@ impl Interface for Handler {
|
||||
self.update_quality_status(QualityStatus {
|
||||
delay: t.last_delay as _,
|
||||
target_bitrate: t.target_bitrate as _,
|
||||
codec_format: t.codec_format.enum_value_or_default(),
|
||||
..Default::default()
|
||||
});
|
||||
let mut msg_out = Message::new();
|
||||
msg_out.set_test_delay(t);
|
||||
allow_err!(peer.send(&msg_out).await);
|
||||
handle_test_delay(t, peer).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -482,16 +482,20 @@ class QualityMonitor: Reactor.Component
|
||||
<div>
|
||||
Target Bitrate: {qualityMonitorData[3]}kb
|
||||
</div>
|
||||
<div>
|
||||
Codec: {qualityMonitorData[4]}
|
||||
</div>
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
|
||||
$(#quality-monitor).content(<QualityMonitor />);
|
||||
handler.updateQualityStatus = function(speed, fps, delay, bitrate) {
|
||||
handler.updateQualityStatus = function(speed, fps, delay, bitrate, codec_format) {
|
||||
speed ? qualityMonitorData[0] = speed:null;
|
||||
fps > -1 ? qualityMonitorData[1] = fps:null;
|
||||
delay > -1 ? qualityMonitorData[2] = delay:null;
|
||||
bitrate > -1 ? qualityMonitorData[3] = bitrate:null;
|
||||
codec_format != "Unknown" ? qualityMonitorData[4] = codec_format:null;
|
||||
qualityMonitor.update();
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user