fix mediacodec bad encoding quality (#8159)
Signed-off-by: 21pages <sunboeasy@gmail.com>
This commit is contained in:
parent
9ce62dc584
commit
c7308dbbc9
4
Cargo.lock
generated
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")]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user