fix android bit rate

This commit is contained in:
csf 2022-06-01 17:52:21 +08:00
parent 20f6bdb8e7
commit 16fd96aa96
7 changed files with 51 additions and 21 deletions

1
Cargo.lock generated
View File

@ -4265,6 +4265,7 @@ dependencies = [
"quest", "quest",
"repng", "repng",
"serde 1.0.136", "serde 1.0.136",
"serde_json 1.0.79",
"target_build_utils", "target_build_utils",
"tracing", "tracing",
"webm", "webm",

View File

@ -72,7 +72,13 @@ class MainService : Service() {
@Keep @Keep
fun rustGetByName(name: String): String { fun rustGetByName(name: String): String {
return when (name) { return when (name) {
"screen_size" -> "${SCREEN_INFO.width}:${SCREEN_INFO.height}" "screen_size" -> {
JSONObject().apply {
put("width",SCREEN_INFO.width)
put("height",SCREEN_INFO.height)
put("scale",SCREEN_INFO.scale)
}.toString()
}
else -> "" else -> ""
} }
} }

View File

@ -28,6 +28,7 @@ android_logger = "0.10"
jni = "0.19" jni = "0.19"
lazy_static = "1.4" lazy_static = "1.4"
log = "0.4" log = "0.4"
serde_json = "1.0"
[target.'cfg(not(target_os = "android"))'.dev-dependencies] [target.'cfg(not(target_os = "android"))'.dev-dependencies]
repng = "0.2" repng = "0.2"

View File

@ -1,11 +1,13 @@
use crate::android::ffi::*; use crate::android::ffi::*;
use crate::rgba_to_i420; use crate::rgba_to_i420;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use serde_json::Value;
use std::collections::HashMap;
use std::io; use std::io;
use std::sync::Mutex; use std::sync::Mutex;
lazy_static! { lazy_static! {
static ref SCREEN_SIZE: Mutex<(u16, u16)> = Mutex::new((0, 0)); static ref SCREEN_SIZE: Mutex<(u16, u16, u16)> = Mutex::new((0, 0, 0)); // (width, height, scale)
} }
pub struct Capturer { pub struct Capturer {
@ -65,9 +67,7 @@ impl Display {
pub fn primary() -> io::Result<Display> { pub fn primary() -> io::Result<Display> {
let mut size = SCREEN_SIZE.lock().unwrap(); let mut size = SCREEN_SIZE.lock().unwrap();
if size.0 == 0 || size.1 == 0 { if size.0 == 0 || size.1 == 0 {
let (w, h) = get_size().unwrap_or((0, 0)); *size = get_size().unwrap_or_default();
size.0 = w;
size.1 = h;
} }
Ok(Display { Ok(Display {
default: true, default: true,
@ -111,19 +111,33 @@ impl Display {
pub fn refresh_size() { pub fn refresh_size() {
let mut size = SCREEN_SIZE.lock().unwrap(); let mut size = SCREEN_SIZE.lock().unwrap();
let (w, h) = get_size().unwrap_or((0, 0)); *size = get_size().unwrap_or_default();
size.0 = w; }
size.1 = h;
// Big android screen size will be shrinked, to improve performance when screen-capturing and encoding
// e.g 2280x1080 size will be set to 1140x540, and `scale` is 2
// need to multiply by `4` (2*2) when compute the bitrate
pub fn fix_quality() -> u16 {
let scale = SCREEN_SIZE.lock().unwrap().2;
if scale <= 0 {
1
} else {
scale * scale
}
} }
} }
fn get_size() -> Option<(u16, u16)> { fn get_size() -> Option<(u16, u16, u16)> {
let res = call_main_service_get_by_name("screen_size").ok()?; let res = call_main_service_get_by_name("screen_size").ok()?;
if res.len() > 0 { if let Ok(json) = serde_json::from_str::<HashMap<String, Value>>(&res) {
let mut sp = res.split(":"); if let (Some(Value::Number(w)), Some(Value::Number(h)), Some(Value::Number(scale))) =
let w = sp.next()?.parse::<u16>().ok()?; (json.get("width"), json.get("height"), json.get("scale"))
let h = sp.next()?.parse::<u16>().ok()?; {
return Some((w, h)); let w = w.as_i64()? as _;
let h = h.as_i64()? as _;
let scale = scale.as_i64()? as _;
return Some((w, h, scale));
}
} }
None None
} }

View File

@ -19,7 +19,7 @@ cfg_if! {
} else if #[cfg(dxgi)] { } else if #[cfg(dxgi)] {
mod dxgi; mod dxgi;
pub use self::dxgi::*; pub use self::dxgi::*;
} else if #[cfg(android)] { } else if #[cfg(target_os = "android")] {
mod android; mod android;
pub use self::android::*; pub use self::android::*;
}else { }else {
@ -36,9 +36,7 @@ mod vpx;
#[inline] #[inline]
pub fn would_block_if_equal(old: &mut Vec<u128>, b: &[u8]) -> std::io::Result<()> { pub fn would_block_if_equal(old: &mut Vec<u128>, b: &[u8]) -> std::io::Result<()> {
let b = unsafe { let b = unsafe { std::slice::from_raw_parts::<u128>(b.as_ptr() as _, b.len() / 16) };
std::slice::from_raw_parts::<u128>(b.as_ptr() as _, b.len() / 16)
};
if b == &old[..] { if b == &old[..] {
return Err(std::io::ErrorKind::WouldBlock.into()); return Err(std::io::ErrorKind::WouldBlock.into());
} }

View File

@ -20,7 +20,7 @@ pub mod wayland;
#[cfg(dxgi)] #[cfg(dxgi)]
pub mod dxgi; pub mod dxgi;
#[cfg(android)] #[cfg(target_os = "android")]
pub mod android; pub mod android;
mod common; mod common;

View File

@ -567,5 +567,15 @@ fn get_quality(w: usize, h: usize, q: i32) -> (u32, u32, u32, i32) {
let bitrate = q >> 8 & 0xFF; let bitrate = q >> 8 & 0xFF;
let quantizer = q & 0xFF; let quantizer = q & 0xFF;
let b = ((w * h) / 1000) as u32; let b = ((w * h) / 1000) as u32;
#[cfg(target_os = "android")]
{
// fix when andorid screen shrinks
let fix = Display::fix_quality() as u32;
log::debug!("Android screen, fix quality:{}", fix);
let b = b * fix;
return (bitrate as u32 * b / 100, quantizer as _, 56, 7);
}
(bitrate as u32 * b / 100, quantizer as _, 56, 7) (bitrate as u32 * b / 100, quantizer as _, 56, 7)
} }