videotoolbox ram codec (#8683)

* h265 encoding: the second frame always fails, use repeat encoding to achieve real-time encoding
* h264 encoding: Not supported because encoding fails too frequently, about 50%, with one failure followed by another success.
* h264/h265 decoding: No issues found.
* Does not support dynamically changing the bitrate and changing the quality by resetting the encoder.

Signed-off-by: 21pages <sunboeasy@gmail.com>
This commit is contained in:
21pages 2024-07-12 11:08:51 +08:00 committed by GitHub
parent 0ea88ce6ff
commit 821f7245b0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 22 additions and 21 deletions

4
Cargo.lock generated
View File

@ -3087,8 +3087,8 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]] [[package]]
name = "hwcodec" name = "hwcodec"
version = "0.4.18" version = "0.4.19"
source = "git+https://github.com/21pages/hwcodec#4b15d782512f95cb158577853e6cdb67a37502c1" source = "git+https://github.com/21pages/hwcodec#852de98224605db7a2495cf276776dabaf8aa139"
dependencies = [ dependencies = [
"bindgen 0.59.2", "bindgen 0.59.2",
"cc", "cc",

View File

@ -838,7 +838,7 @@ impl Decoder {
pub fn enable_hwcodec_option() -> bool { pub fn enable_hwcodec_option() -> bool {
use hbb_common::config::keys::OPTION_ENABLE_HWCODEC; use hbb_common::config::keys::OPTION_ENABLE_HWCODEC;
if cfg!(windows) || cfg!(target_os = "linux") || cfg!(target_os = "android") { if !cfg!(target_os = "ios") {
return option2bool( return option2bool(
OPTION_ENABLE_HWCODEC, OPTION_ENABLE_HWCODEC,
&Config::get_option(OPTION_ENABLE_HWCODEC), &Config::get_option(OPTION_ENABLE_HWCODEC),

View File

@ -192,19 +192,21 @@ impl EncoderApi for HwRamEncoder {
} }
fn support_abr(&self) -> bool { fn support_abr(&self) -> bool {
["qsv", "vaapi", "mediacodec"] ["qsv", "vaapi", "mediacodec", "videotoolbox"]
.iter() .iter()
.all(|&x| !self.config.name.contains(x)) .all(|&x| !self.config.name.contains(x))
} }
fn support_changing_quality(&self) -> bool { fn support_changing_quality(&self) -> bool {
["vaapi", "mediacodec"] ["vaapi", "mediacodec", "videotoolbox"]
.iter() .iter()
.all(|&x| !self.config.name.contains(x)) .all(|&x| !self.config.name.contains(x))
} }
fn latency_free(&self) -> bool { fn latency_free(&self) -> bool {
!self.config.name.contains("mediacodec") ["mediacodec", "videotoolbox"]
.iter()
.all(|&x| !self.config.name.contains(x))
} }
fn is_hardware(&self) -> bool { fn is_hardware(&self) -> bool {
@ -501,12 +503,12 @@ pub struct HwCodecConfig {
// portable: ui start check process, check process send to ui // portable: ui start check process, check process send to ui
// sciter and unilink: get from ipc server // sciter and unilink: get from ipc server
impl HwCodecConfig { impl HwCodecConfig {
#[cfg(any(target_os = "windows", target_os = "linux"))] #[cfg(not(any(target_os = "android", target_os = "ios")))]
pub fn set(config: String) { pub fn set(config: String) {
let config = serde_json::from_str(&config).unwrap_or_default(); let config = serde_json::from_str(&config).unwrap_or_default();
log::info!("set hwcodec config"); log::info!("set hwcodec config");
log::debug!("{config:?}"); log::debug!("{config:?}");
#[cfg(windows)] #[cfg(any(windows, target_os = "macos"))]
hbb_common::config::common_store(&config, "_hwcodec"); hbb_common::config::common_store(&config, "_hwcodec");
*CONFIG.lock().unwrap() = Some(config); *CONFIG.lock().unwrap() = Some(config);
*CONFIG_SET_BY_IPC.lock().unwrap() = true; *CONFIG_SET_BY_IPC.lock().unwrap() = true;
@ -578,7 +580,7 @@ impl HwCodecConfig {
..Default::default() ..Default::default()
} }
} }
#[cfg(windows)] #[cfg(any(windows, target_os = "macos"))]
{ {
let config = CONFIG.lock().unwrap().clone(); let config = CONFIG.lock().unwrap().clone();
match config { match config {
@ -606,13 +608,13 @@ impl HwCodecConfig {
{ {
CONFIG.lock().unwrap().clone().unwrap_or_default() CONFIG.lock().unwrap().clone().unwrap_or_default()
} }
#[cfg(any(target_os = "macos", target_os = "ios"))] #[cfg(target_os = "ios")]
{ {
HwCodecConfig::default() HwCodecConfig::default()
} }
} }
#[cfg(any(target_os = "windows", target_os = "linux"))] #[cfg(not(any(target_os = "android", target_os = "ios")))]
pub fn get_set_value() -> Option<HwCodecConfig> { pub fn get_set_value() -> Option<HwCodecConfig> {
let set = CONFIG_SET_BY_IPC.lock().unwrap().clone(); let set = CONFIG_SET_BY_IPC.lock().unwrap().clone();
if set { if set {
@ -622,7 +624,7 @@ impl HwCodecConfig {
} }
} }
#[cfg(any(target_os = "windows", target_os = "linux"))] #[cfg(not(any(target_os = "android", target_os = "ios")))]
pub fn already_set() -> bool { pub fn already_set() -> bool {
CONFIG_SET_BY_IPC.lock().unwrap().clone() CONFIG_SET_BY_IPC.lock().unwrap().clone()
} }
@ -690,7 +692,7 @@ pub fn check_available_hwcodec() -> String {
serde_json::to_string(&c).unwrap_or_default() serde_json::to_string(&c).unwrap_or_default()
} }
#[cfg(any(target_os = "windows", target_os = "linux"))] #[cfg(not(any(target_os = "android", target_os = "ios")))]
pub fn start_check_process() { pub fn start_check_process() {
if !enable_hwcodec_option() || HwCodecConfig::already_set() { if !enable_hwcodec_option() || HwCodecConfig::already_set() {
return; return;

View File

@ -553,12 +553,12 @@ async fn handle(data: Data, stream: &mut Connection) {
); );
} }
#[cfg(feature = "hwcodec")] #[cfg(feature = "hwcodec")]
#[cfg(any(target_os = "windows", target_os = "linux"))] #[cfg(not(any(target_os = "android", target_os = "ios")))]
Data::CheckHwcodec => { Data::CheckHwcodec => {
scrap::hwcodec::start_check_process(); scrap::hwcodec::start_check_process();
} }
#[cfg(feature = "hwcodec")] #[cfg(feature = "hwcodec")]
#[cfg(any(target_os = "windows", target_os = "linux"))] #[cfg(not(any(target_os = "android", target_os = "ios")))]
Data::HwCodecConfig(c) => { Data::HwCodecConfig(c) => {
match c { match c {
None => { None => {
@ -1047,7 +1047,7 @@ pub async fn notify_server_to_check_hwcodec() -> ResultType<()> {
} }
#[cfg(feature = "hwcodec")] #[cfg(feature = "hwcodec")]
#[cfg(any(target_os = "windows", target_os = "linux"))] #[cfg(not(any(target_os = "android", target_os = "ios")))]
#[tokio::main(flavor = "current_thread")] #[tokio::main(flavor = "current_thread")]
pub async fn get_hwcodec_config_from_server() -> ResultType<()> { pub async fn get_hwcodec_config_from_server() -> ResultType<()> {
if !scrap::codec::enable_hwcodec_option() || scrap::hwcodec::HwCodecConfig::already_set() { if !scrap::codec::enable_hwcodec_option() || scrap::hwcodec::HwCodecConfig::already_set() {
@ -1070,7 +1070,7 @@ pub async fn get_hwcodec_config_from_server() -> ResultType<()> {
} }
#[cfg(feature = "hwcodec")] #[cfg(feature = "hwcodec")]
#[cfg(any(target_os = "windows", target_os = "linux"))] #[cfg(not(any(target_os = "android", target_os = "ios")))]
pub fn client_get_hwcodec_config_thread(wait_sec: u64) { pub fn client_get_hwcodec_config_thread(wait_sec: u64) {
static ONCE: std::sync::Once = std::sync::Once::new(); static ONCE: std::sync::Once = std::sync::Once::new();
if !crate::platform::is_installed() if !crate::platform::is_installed()

View File

@ -489,7 +489,7 @@ pub async fn start_server(is_server: bool) {
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
crate::platform::try_kill_broker(); crate::platform::try_kill_broker();
#[cfg(feature = "hwcodec")] #[cfg(feature = "hwcodec")]
#[cfg(any(target_os = "windows", target_os = "linux"))] #[cfg(not(any(target_os = "android", target_os = "ios")))]
scrap::hwcodec::start_check_process(); scrap::hwcodec::start_check_process();
crate::RendezvousMediator::start_all().await; crate::RendezvousMediator::start_all().await;
} else { } else {

View File

@ -904,8 +904,7 @@ pub fn get_api_server() -> String {
#[inline] #[inline]
pub fn has_hwcodec() -> bool { pub fn has_hwcodec() -> bool {
// Has real hardware codec using gpu // Has real hardware codec using gpu
(cfg!(feature = "hwcodec") && (cfg!(windows) || cfg!(target_os = "linux"))) (cfg!(feature = "hwcodec") && cfg!(not(target_os = "ios"))) || cfg!(feature = "mediacodec")
|| cfg!(feature = "mediacodec")
} }
#[inline] #[inline]
@ -1408,7 +1407,7 @@ pub fn verify_bot(token: String) -> String {
pub fn check_hwcodec() { pub fn check_hwcodec() {
#[cfg(feature = "hwcodec")] #[cfg(feature = "hwcodec")]
#[cfg(any(target_os = "windows", target_os = "linux"))] #[cfg(not(any(target_os = "android", target_os = "ios")))]
{ {
use std::sync::Once; use std::sync::Once;
static ONCE: Once = Once::new(); static ONCE: Once = Once::new();