add enable directx option, android software encoding half resolution option (#8435)

* add option enable directx capture screen, default true

Signed-off-by: 21pages <sunboeasy@gmail.com>

* option android software encoding half scale, check isStart flag

Signed-off-by: 21pages <sunboeasy@gmail.com>

---------

Signed-off-by: 21pages <sunboeasy@gmail.com>
This commit is contained in:
21pages 2024-06-21 18:54:32 +08:00 committed by GitHub
parent ff2e055a5a
commit 0f6538c1a7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
50 changed files with 133 additions and 30 deletions

View File

@ -103,6 +103,9 @@ class MainService : Service() {
put("scale",SCREEN_INFO.scale)
}.toString()
}
"is_start" -> {
isStart.toString()
}
else -> ""
}
}
@ -172,10 +175,10 @@ class MainService : Service() {
Log.d(logTag, "from rust:stop_capture")
stopCapture()
}
"is_hardware_codec" -> {
val isHwCodec = arg1.toBoolean()
if (isHardwareCodec != isHwCodec) {
isHardwareCodec = isHwCodec
"half_scale" -> {
val halfScale = arg1.toBoolean()
if (isHalfScale != halfScale) {
isHalfScale = halfScale
updateScreenInfo(resources.configuration.orientation)
}
@ -251,7 +254,7 @@ class MainService : Service() {
super.onDestroy()
}
private var isHardwareCodec: Boolean? = null;
private var isHalfScale: Boolean? = null;
private fun updateScreenInfo(orientation: Int) {
var w: Int
var h: Int
@ -284,7 +287,7 @@ class MainService : Service() {
Log.d(logTag,"updateScreenInfo:w:$w,h:$h")
var scale = 1
if (w != 0 && h != 0) {
if (isHardwareCodec == false && (w > MAX_SCREEN_SIZE || h > MAX_SCREEN_SIZE)) {
if (isHalfScale == true && (w > MAX_SCREEN_SIZE || h > MAX_SCREEN_SIZE)) {
scale = 2
w /= scale
h /= scale

View File

@ -134,6 +134,7 @@ const String kOptionEnableCheckUpdate = "enable-check-update";
const String kOptionAllowLinuxHeadless = "allow-linux-headless";
const String kOptionAllowRemoveWallpaper = "allow-remove-wallpaper";
const String kOptionStopService = "stop-service";
const String kOptionDirectxCapture = "enable-directx-capture";
const String kOptionToggleViewOnly = "view-only";

View File

@ -315,11 +315,11 @@ class _GeneralState extends State<_General> {
children: [
service(),
theme(),
_Card(title: 'Language', children: [language()]),
hwcodec(),
audio(context),
record(context),
WaylandCard(),
_Card(title: 'Language', children: [language()]),
other()
],
).marginOnly(bottom: _kListViewBottomMargin));
@ -413,6 +413,12 @@ class _GeneralState extends State<_General> {
'Check for software update on startup',
kOptionEnableCheckUpdate,
isServer: false,
),
if (isWindows && !bind.isOutgoingOnly())
_OptionCheckBox(
context,
'Capture screen using DirectX',
kOptionDirectxCapture,
)
],
];

View File

@ -2084,6 +2084,9 @@ pub mod keys {
pub const OPTION_KEY: &str = "key";
pub const OPTION_PRESET_ADDRESS_BOOK_NAME: &str = "preset-address-book-name";
pub const OPTION_PRESET_ADDRESS_BOOK_TAG: &str = "preset-address-book-tag";
pub const OPTION_ENABLE_DIRECTX_CAPTURE: &str = "enable-directx-capture";
pub const OPTION_ENABLE_ANDRIOD_SOFTWARE_ENCODING_HALF_SCALE: &str =
"enable-andriod-software-encoding-half-scale";
// flutter local options
pub const OPTION_FLUTTER_REMOTE_MENUBAR_STATE: &str = "remoteMenubarState";
@ -2206,6 +2209,8 @@ pub mod keys {
OPTION_KEY,
OPTION_PRESET_ADDRESS_BOOK_NAME,
OPTION_PRESET_ADDRESS_BOOK_TAG,
OPTION_ENABLE_DIRECTX_CAPTURE,
OPTION_ENABLE_ANDRIOD_SOFTWARE_ENCODING_HALF_SCALE,
];
}

View File

@ -182,3 +182,8 @@ fn get_size() -> Option<(u16, u16, u16)> {
}
None
}
pub fn is_start() -> Option<bool> {
let res = call_main_service_get_by_name("is_start").ok()?;
Some(res == "true")
}

View File

@ -21,8 +21,8 @@ use crate::{
use hbb_common::{
anyhow::anyhow,
bail,
config::PeerConfig,
log,
config::{keys::OPTION_ENABLE_HWCODEC, option2bool, Config, PeerConfig},
lazy_static, log,
message_proto::{
supported_decoding::PreferCodec, video_frame, Chroma, CodecAbility, EncodedVideoFrames,
SupportedDecoding, SupportedEncoding, VideoFrame,
@ -31,8 +31,6 @@ use hbb_common::{
tokio::time::Instant,
ResultType,
};
#[cfg(any(feature = "hwcodec", feature = "mediacodec", feature = "vram"))]
use hbb_common::{config::Config2, lazy_static};
lazy_static::lazy_static! {
static ref PEER_DECODINGS: Arc<Mutex<HashMap<i32, SupportedDecoding>>> = Default::default();
@ -201,7 +199,7 @@ impl Encoder {
#[allow(unused_mut)]
let mut h265vram_encoding = false;
#[cfg(feature = "vram")]
if enable_vram_option() {
if enable_vram_option(true) {
if _all_support_h264_decoding {
if VRamEncoder::available(CodecFormat::H264).len() > 0 {
h264vram_encoding = true;
@ -340,7 +338,7 @@ impl Encoder {
encoding.h265 |= HwRamEncoder::try_get(CodecFormat::H265).is_some();
}
#[cfg(feature = "vram")]
if enable_vram_option() {
if enable_vram_option(true) {
encoding.h264 |= VRamEncoder::available(CodecFormat::H264).len() > 0;
encoding.h265 |= VRamEncoder::available(CodecFormat::H265).len() > 0;
}
@ -451,7 +449,7 @@ impl Decoder {
};
}
#[cfg(feature = "vram")]
if enable_vram_option() && _use_texture_render {
if enable_vram_option(false) && _use_texture_render {
decoding.ability_h264 |= if VRamDecoder::available(CodecFormat::H264, _luid).len() > 0 {
1
} else {
@ -530,7 +528,7 @@ impl Decoder {
}
CodecFormat::H264 => {
#[cfg(feature = "vram")]
if !valid && enable_vram_option() && _luid.clone().unwrap_or_default() != 0 {
if !valid && enable_vram_option(false) && _luid.clone().unwrap_or_default() != 0 {
match VRamDecoder::new(format, _luid) {
Ok(v) => h264_vram = Some(v),
Err(e) => log::error!("create H264 vram decoder failed: {}", e),
@ -556,7 +554,7 @@ impl Decoder {
}
CodecFormat::H265 => {
#[cfg(feature = "vram")]
if !valid && enable_vram_option() && _luid.clone().unwrap_or_default() != 0 {
if !valid && enable_vram_option(false) && _luid.clone().unwrap_or_default() != 0 {
match VRamDecoder::new(format, _luid) {
Ok(v) => h265_vram = Some(v),
Err(e) => log::error!("create H265 vram decoder failed: {}", e),
@ -839,19 +837,37 @@ impl Decoder {
#[cfg(any(feature = "hwcodec", feature = "mediacodec"))]
pub fn enable_hwcodec_option() -> bool {
if cfg!(windows) || cfg!(target_os = "linux") || cfg!(target_os = "android") {
if let Some(v) = Config2::get().options.get("enable-hwcodec") {
return v != "N";
}
return true; // default is true
return option2bool(
OPTION_ENABLE_HWCODEC,
&Config::get_option(OPTION_ENABLE_HWCODEC),
);
}
false
}
#[cfg(feature = "vram")]
pub fn enable_vram_option() -> bool {
if let Some(v) = Config2::get().options.get("enable-hwcodec") {
return v != "N";
pub fn enable_vram_option(encode: bool) -> bool {
if cfg!(windows) {
let enable = option2bool(
OPTION_ENABLE_HWCODEC,
&Config::get_option(OPTION_ENABLE_HWCODEC),
);
if encode {
enable && enable_directx_capture()
} else {
enable
}
} else {
false
}
return true; // default is true
}
#[cfg(windows)]
pub fn enable_directx_capture() -> bool {
use hbb_common::config::keys::OPTION_ENABLE_DIRECTX_CAPTURE as OPTION;
option2bool(
OPTION,
&Config::get_option(hbb_common::config::keys::OPTION_ENABLE_DIRECTX_CAPTURE),
)
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]

View File

@ -491,3 +491,8 @@ pub trait GoogleImage {
pub fn screen_size() -> (u16, u16, u16) {
SCREEN_SIZE.lock().unwrap().clone()
}
#[cfg(target_os = "android")]
pub fn is_start() -> Option<bool> {
android::is_start()
}

View File

@ -354,7 +354,7 @@ impl VRamDecoder {
}
pub fn possible_available_without_check() -> (bool, bool) {
if !enable_vram_option() {
if !enable_vram_option(false) {
return (false, false);
}
let v = crate::hwcodec::HwCodecConfig::get().vram_decode;

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", ""),
("During controlled", ""),
("During service is on", ""),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", ""),
("During controlled", ""),
("During service is on", ""),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", ""),
("During controlled", ""),
("During service is on", ""),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", "从不"),
("During controlled", "被控期间"),
("During service is on", "服务开启期间"),
("Capture screen using DirectX", "使用 DirectX 捕获屏幕"),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", "Nikdy"),
("During controlled", "Během řízeného"),
("During service is on", "Během služby je v provozu"),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", ""),
("During controlled", ""),
("During service is on", ""),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", "Niemals"),
("During controlled", "Wenn kontrolliert"),
("During service is on", "Wenn der Dienst läuft"),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", ""),
("During controlled", ""),
("During service is on", ""),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", ""),
("During controlled", ""),
("During service is on", ""),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", "Nunca"),
("During controlled", "Mientras está siendo controlado"),
("During service is on", "Mientras el servicio está activo"),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", ""),
("During controlled", ""),
("During service is on", ""),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", ""),
("During controlled", ""),
("During service is on", ""),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", ""),
("During controlled", ""),
("During service is on", ""),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", ""),
("During controlled", ""),
("During service is on", ""),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", ""),
("During controlled", ""),
("During service is on", ""),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", ""),
("During controlled", ""),
("During service is on", ""),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", ""),
("During controlled", ""),
("During service is on", ""),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", "Mai"),
("During controlled", "Durante il controllo"),
("During service is on", "Quando il servizio è attivo"),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", ""),
("During controlled", ""),
("During service is on", ""),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", ""),
("During controlled", ""),
("During service is on", ""),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", ""),
("During controlled", ""),
("During service is on", ""),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", ""),
("During controlled", ""),
("During service is on", ""),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", "Nekad"),
("During controlled", "Lietošanas laikā"),
("During service is on", "Kamēr pakalpojums ir ieslēgts"),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", ""),
("During controlled", ""),
("During service is on", ""),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", ""),
("During controlled", ""),
("During service is on", ""),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", ""),
("During controlled", ""),
("During service is on", ""),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", ""),
("During controlled", ""),
("During service is on", ""),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", ""),
("During controlled", ""),
("During service is on", ""),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", ""),
("During controlled", ""),
("During service is on", ""),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -125,7 +125,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Good image quality", "Лучшее качество изображения"),
("Balanced", "Баланс между качеством и откликом"),
("Optimize reaction time", "Лучшее время отклика"),
("Custom", "Заданное пользователем"),
("Custom", "Заданное пользователем"),
("Show remote cursor", "Показывать удалённый курсор"),
("Show quality monitor", "Показывать монитор качества"),
("Disable clipboard", "Отключить буфер обмена"),
@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", "Нет"),
("During controlled", "При управлении"),
("During service is on", "При запущенной службе"),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", "Nikdy"),
("During controlled", "Počas kontrolovaného"),
("During service is on", "Počas služby je v prevádzke"),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", ""),
("During controlled", ""),
("During service is on", ""),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", ""),
("During controlled", ""),
("During service is on", ""),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", ""),
("During controlled", ""),
("During service is on", ""),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", ""),
("During controlled", ""),
("During service is on", ""),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", ""),
("During controlled", ""),
("During service is on", ""),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", ""),
("During controlled", ""),
("During service is on", ""),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", ""),
("During controlled", ""),
("During service is on", ""),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", "從不"),
("During controlled", "被控期間"),
("During service is on", "服務開啟期間"),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", ""),
("During controlled", ""),
("During service is on", ""),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -621,5 +621,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Never", ""),
("During controlled", ""),
("During service is on", ""),
("Capture screen using DirectX", ""),
].iter().cloned().collect();
}

View File

@ -407,7 +407,11 @@ fn run(vs: VideoService) -> ResultType<()> {
let display_idx = vs.idx;
let sp = vs.sp;
let mut c = get_capturer(display_idx, last_portable_service_running)?;
#[cfg(windows)]
if !scrap::codec::enable_directx_capture() && !c.is_gdi() {
log::info!("disable dxgi with option, fall back to gdi");
c.set_gdi();
}
let mut video_qos = VIDEO_QOS.lock().unwrap();
video_qos.refresh(None);
let mut spf;
@ -837,16 +841,33 @@ fn get_recorder(
#[cfg(target_os = "android")]
fn check_change_scale(hardware: bool) -> ResultType<()> {
use hbb_common::config::keys::OPTION_ENABLE_ANDRIOD_SOFTWARE_ENCODING_HALF_SCALE as SCALE_SOFT;
// isStart flag is set at the end of startCapture() in Android, wait it to be set.
for i in 0..6 {
if scrap::is_start() == Some(true) {
log::info!("start flag is set");
break;
}
log::info!("wait for start, {i}");
std::thread::sleep(Duration::from_millis(50));
if i == 5 {
log::error!("wait for start timeout");
}
}
let screen_size = scrap::screen_size();
log::info!("hardware: {hardware}, screen_size: {screen_size:?}",);
let scale_soft = hbb_common::config::option2bool(SCALE_SOFT, &Config::get_option(SCALE_SOFT));
let half_scale = !hardware && scale_soft;
log::info!("hardware: {hardware}, scale_soft: {scale_soft}, screen_size: {screen_size:?}",);
scrap::android::call_main_service_set_by_name(
"is_hardware_codec",
Some(hardware.to_string().as_str()),
"half_scale",
Some(half_scale.to_string().as_str()),
None,
)
.ok();
let old_scale = screen_size.2;
let new_scale = scrap::screen_size().2;
log::info!("old_scale: {old_scale}, new_scale: {new_scale}");
if old_scale != new_scale {
log::info!("switch due to scale changed, {old_scale} -> {new_scale}");
// switch is not a must, but it is better to do so.