fix mediacodec bad encoding quality ()

Signed-off-by: 21pages <sunboeasy@gmail.com>
This commit is contained in:
21pages 2024-05-27 19:34:40 +08:00 committed by GitHub
parent 9ce62dc584
commit c7308dbbc9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 23 additions and 16 deletions
Cargo.lock
libs/scrap/src/common

4
Cargo.lock generated

@ -3037,8 +3037,8 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]] [[package]]
name = "hwcodec" name = "hwcodec"
version = "0.4.11" version = "0.4.12"
source = "git+https://github.com/21pages/hwcodec#a5864080e41836b94feb9f73732280c651162fec" source = "git+https://github.com/21pages/hwcodec#6fbafe7dd25adad5e897b3192b2b40b720a9b118"
dependencies = [ dependencies = [
"bindgen 0.59.2", "bindgen 0.59.2",
"cc", "cc",

@ -14,14 +14,16 @@ use hbb_common::{
serde_json, ResultType, serde_json, ResultType,
}; };
use hwcodec::{ use hwcodec::{
common::DataFormat, common::{
DataFormat,
Quality::{self, *},
RateControl::{self, *},
},
ffmpeg::AVPixelFormat, ffmpeg::AVPixelFormat,
ffmpeg_ram::{ ffmpeg_ram::{
decode::{DecodeContext, DecodeFrame, Decoder}, decode::{DecodeContext, DecodeFrame, Decoder},
encode::{EncodeContext, EncodeFrame, Encoder}, encode::{EncodeContext, EncodeFrame, Encoder},
CodecInfo, CodecInfo,
Quality::{self, *},
RateControl::{self, *},
}, },
}; };
@ -29,10 +31,6 @@ const DEFAULT_PIXFMT: AVPixelFormat = AVPixelFormat::AV_PIX_FMT_NV12;
pub const DEFAULT_TIME_BASE: [i32; 2] = [1, 30]; pub const DEFAULT_TIME_BASE: [i32; 2] = [1, 30];
const DEFAULT_GOP: i32 = i32::MAX; const DEFAULT_GOP: i32 = i32::MAX;
const DEFAULT_HW_QUALITY: Quality = Quality_Default; const DEFAULT_HW_QUALITY: Quality = Quality_Default;
#[cfg(target_os = "android")]
const DEFAULT_RC: RateControl = RC_VBR; // android cbr poor quality
#[cfg(not(target_os = "android"))]
const DEFAULT_RC: RateControl = RC_CBR;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct HwRamEncoderConfig { pub struct HwRamEncoderConfig {
@ -59,6 +57,7 @@ impl EncoderApi for HwRamEncoder {
{ {
match cfg { match cfg {
EncoderCfg::HWRAM(config) => { EncoderCfg::HWRAM(config) => {
let rc = Self::rate_control(&config);
let b = Self::convert_quality(&config.name, config.quality); let b = Self::convert_quality(&config.name, config.quality);
let base_bitrate = base_bitrate(config.width as _, config.height as _); let base_bitrate = base_bitrate(config.width as _, config.height as _);
let mut bitrate = base_bitrate * b / 100; let mut bitrate = base_bitrate * b / 100;
@ -78,7 +77,8 @@ impl EncoderApi for HwRamEncoder {
timebase: DEFAULT_TIME_BASE, timebase: DEFAULT_TIME_BASE,
gop, gop,
quality: DEFAULT_HW_QUALITY, quality: DEFAULT_HW_QUALITY,
rc: DEFAULT_RC, rc,
q: -1,
thread_count: codec_thread_num(16) as _, // ffmpeg's thread_count is used for cpu thread_count: codec_thread_num(16) as _, // ffmpeg's thread_count is used for cpu
}; };
let format = match Encoder::format_from_name(config.name.clone()) { let format = match Encoder::format_from_name(config.name.clone()) {
@ -175,6 +175,7 @@ impl EncoderApi for HwRamEncoder {
self.encoder.set_bitrate(bitrate as _).ok(); self.encoder.set_bitrate(bitrate as _).ok();
self.bitrate = bitrate; self.bitrate = bitrate;
} }
self.config.quality = quality;
Ok(()) Ok(())
} }
@ -232,6 +233,14 @@ impl HwRamEncoder {
} }
} }
fn rate_control(config: &HwRamEncoderConfig) -> RateControl {
#[cfg(target_os = "android")]
if config.name.contains("mediacodec") {
return RC_VBR;
}
RC_CBR
}
pub fn convert_quality(name: &str, quality: crate::codec::Quality) -> u32 { pub fn convert_quality(name: &str, quality: crate::codec::Quality) -> u32 {
use crate::codec::Quality; use crate::codec::Quality;
let quality = match quality { let quality = match quality {
@ -241,11 +250,8 @@ impl HwRamEncoder {
Quality::Custom(b) => b, Quality::Custom(b) => b,
}; };
let factor = if name.contains("mediacodec") { let factor = if name.contains("mediacodec") {
if name.contains("h264") { // https://stackoverflow.com/questions/26110337/what-are-valid-bit-rates-to-set-for-mediacodec?rq=3
6 5
} else {
3
}
} else { } else {
1 1
}; };
@ -510,7 +516,8 @@ pub fn check_available_hwcodec() {
timebase: DEFAULT_TIME_BASE, timebase: DEFAULT_TIME_BASE,
gop: DEFAULT_GOP, gop: DEFAULT_GOP,
quality: DEFAULT_HW_QUALITY, quality: DEFAULT_HW_QUALITY,
rc: DEFAULT_RC, rc: RC_CBR,
q: -1,
thread_count: 4, thread_count: 4,
}; };
#[cfg(feature = "vram")] #[cfg(feature = "vram")]