Not require both max-width and max-height of mediacodec larger than (#8036)

screen width and screen height

* Only use hardware codec, when api < 29, judge with codec name prefix.

Signed-off-by: 21pages <pages21@163.com>
This commit is contained in:
21pages 2024-05-13 20:24:50 +08:00 committed by GitHub
parent 7e09809ad8
commit d70b0cdd4f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 28 additions and 8 deletions

View File

@ -264,8 +264,12 @@ class MainActivity : FlutterActivity() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
hw = codec.isHardwareAccelerated
} else {
if (listOf("OMX.google.", "OMX.SEC.", "c2.android").any { codec.name.startsWith(it) }) {
// https://chromium.googlesource.com/external/webrtc/+/HEAD/sdk/android/src/java/org/webrtc/MediaCodecUtils.java#29
// https://chromium.googlesource.com/external/webrtc/+/master/sdk/android/api/org/webrtc/HardwareVideoEncoderFactory.java#229
if (listOf("OMX.google.", "OMX.SEC.", "c2.android").any { codec.name.startsWith(it, true) }) {
hw = false
} else if (listOf("c2.qti", "OMX.qcom.video", "OMX.Exynos", "OMX.hisi", "OMX.MTK", "OMX.Intel", "OMX.Nvidia").any { codec.name.startsWith(it, true) }) {
hw = true
}
}
codecObject.put("hw", hw)
@ -280,7 +284,8 @@ class MainActivity : FlutterActivity() {
val caps = codec.getCapabilitiesForType(mime_type)
var usable = true;
if (codec.isEncoder) {
if (!caps.videoCapabilities.isSizeSupported(w,h) || !caps.videoCapabilities.isSizeSupported(h,w)) {
// Encoders max_height and max_width are interchangeable
if (!caps.videoCapabilities.isSizeSupported(w,h) && !caps.videoCapabilities.isSizeSupported(h,w)) {
usable = false
}
}
@ -309,6 +314,8 @@ class MainActivity : FlutterActivity() {
}
val result = JSONObject()
result.put("version", Build.VERSION.SDK_INT)
result.put("w", w)
result.put("h", h)
result.put("codecs", codecArray)
FFI.setCodecInfo(result.toString())
}

View File

@ -178,6 +178,8 @@ pub struct MediaCodecInfo {
#[derive(Debug, Deserialize, Clone)]
pub struct MediaCodecInfos {
pub version: usize,
pub w: usize,
pub h: usize,
pub codecs: Vec<MediaCodecInfo>,
}

View File

@ -416,6 +416,7 @@ fn get_config() -> ResultType<Available> {
#[cfg(target_os = "android")]
{
let info = crate::android::ffi::get_codec_info();
log::info!("all codec info: {info:?}");
struct T {
name_prefix: &'static str,
data_format: DataFormat,
@ -440,16 +441,26 @@ fn get_config() -> ResultType<Available> {
c.is_encoder
&& c.mime_type.as_str() == get_mime_type(t.data_format)
&& c.nv12
&& c.hw == Some(true) //only use hardware codec
})
.collect();
log::debug!("available {:?} encoders: {codecs:?}", t.data_format);
let screen_wh = std::cmp::max(info.w, info.h);
let mut best = None;
if let Some(c) = codecs.iter().find(|c| c.hw == Some(true)) {
best = Some(c.name.clone());
} else if let Some(c) = codecs.iter().find(|c| c.hw == None) {
best = Some(c.name.clone());
} else if let Some(c) = codecs.first() {
best = Some(c.name.clone());
if let Some(codec) = codecs
.iter()
.find(|c| c.max_width >= screen_wh && c.max_height >= screen_wh)
{
best = Some(codec.name.clone());
} else {
// find the max resolution
let mut max_area = 0;
for codec in codecs.iter() {
if codec.max_width * codec.max_height > max_area {
best = Some(codec.name.clone());
max_area = codec.max_width * codec.max_height;
}
}
}
if let Some(best) = best {
e.push(CodecInfo {