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",
"repng",
"serde 1.0.136",
"serde_json 1.0.79",
"target_build_utils",
"tracing",
"webm",

View File

@ -72,7 +72,13 @@ class MainService : Service() {
@Keep
fun rustGetByName(name: String): String {
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 -> ""
}
}

View File

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

View File

@ -1,11 +1,13 @@
use crate::android::ffi::*;
use crate::rgba_to_i420;
use lazy_static::lazy_static;
use serde_json::Value;
use std::collections::HashMap;
use std::io;
use std::sync::Mutex;
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 {
@ -65,9 +67,7 @@ impl Display {
pub fn primary() -> io::Result<Display> {
let mut size = SCREEN_SIZE.lock().unwrap();
if size.0 == 0 || size.1 == 0 {
let (w, h) = get_size().unwrap_or((0, 0));
size.0 = w;
size.1 = h;
*size = get_size().unwrap_or_default();
}
Ok(Display {
default: true,
@ -111,19 +111,33 @@ impl Display {
pub fn refresh_size() {
let mut size = SCREEN_SIZE.lock().unwrap();
let (w, h) = get_size().unwrap_or((0, 0));
size.0 = w;
size.1 = h;
*size = get_size().unwrap_or_default();
}
// 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()?;
if res.len() > 0 {
let mut sp = res.split(":");
let w = sp.next()?.parse::<u16>().ok()?;
let h = sp.next()?.parse::<u16>().ok()?;
return Some((w, h));
if let Ok(json) = serde_json::from_str::<HashMap<String, Value>>(&res) {
if let (Some(Value::Number(w)), Some(Value::Number(h)), Some(Value::Number(scale))) =
(json.get("width"), json.get("height"), json.get("scale"))
{
let w = w.as_i64()? as _;
let h = h.as_i64()? as _;
let scale = scale.as_i64()? as _;
return Some((w, h, scale));
}
}
None
}

View File

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

View File

@ -14,13 +14,13 @@ pub mod quartz;
#[cfg(x11)]
pub mod x11;
#[cfg(all(x11, feature="wayland"))]
#[cfg(all(x11, feature = "wayland"))]
pub mod wayland;
#[cfg(dxgi)]
pub mod dxgi;
#[cfg(android)]
#[cfg(target_os = "android")]
pub mod android;
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 quantizer = q & 0xFF;
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)
}