|
|
|
|
@ -13,6 +13,7 @@ import java.util.Map; |
|
|
|
|
import java.util.TreeMap; |
|
|
|
|
|
|
|
|
|
public class IjkMediaCodecInfo { |
|
|
|
|
|
|
|
|
|
private final static String TAG = "IjkMediaCodecInfo"; |
|
|
|
|
|
|
|
|
|
public static final int RANK_MAX = 1000; |
|
|
|
|
@ -31,11 +32,9 @@ public class IjkMediaCodecInfo { |
|
|
|
|
private static Map<String, Integer> sKnownCodecList; |
|
|
|
|
|
|
|
|
|
private static synchronized Map<String, Integer> getKnownCodecList() { |
|
|
|
|
if (sKnownCodecList != null) |
|
|
|
|
return sKnownCodecList; |
|
|
|
|
if (sKnownCodecList != null) return sKnownCodecList; |
|
|
|
|
|
|
|
|
|
sKnownCodecList = new TreeMap<String, Integer>( |
|
|
|
|
String.CASE_INSENSITIVE_ORDER); |
|
|
|
|
sKnownCodecList = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); |
|
|
|
|
|
|
|
|
|
// ----- Nvidia -----
|
|
|
|
|
// Tegra3
|
|
|
|
|
@ -135,15 +134,11 @@ public class IjkMediaCodecInfo { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@TargetApi(Build.VERSION_CODES.JELLY_BEAN) |
|
|
|
|
public static IjkMediaCodecInfo setupCandidate(MediaCodecInfo codecInfo, |
|
|
|
|
String mimeType) { |
|
|
|
|
if (codecInfo == null |
|
|
|
|
|| Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) |
|
|
|
|
return null; |
|
|
|
|
public static IjkMediaCodecInfo setupCandidate(MediaCodecInfo codecInfo, String mimeType) { |
|
|
|
|
if (codecInfo == null || Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) return null; |
|
|
|
|
|
|
|
|
|
String name = codecInfo.getName(); |
|
|
|
|
if (TextUtils.isEmpty(name)) |
|
|
|
|
return null; |
|
|
|
|
if (TextUtils.isEmpty(name)) return null; |
|
|
|
|
|
|
|
|
|
name = name.toLowerCase(Locale.US); |
|
|
|
|
int rank = RANK_NO_SENSE; |
|
|
|
|
@ -165,22 +160,17 @@ public class IjkMediaCodecInfo { |
|
|
|
|
} else if (name.startsWith("omx.mtk.")) { |
|
|
|
|
// 1. MTK only works on 4.3 and above
|
|
|
|
|
// 2. MTK works on MIUI 6 (4.2.1)
|
|
|
|
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) |
|
|
|
|
rank = RANK_NO_SENSE; |
|
|
|
|
else |
|
|
|
|
rank = RANK_TESTED; |
|
|
|
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) rank = RANK_NO_SENSE; |
|
|
|
|
else rank = RANK_TESTED; |
|
|
|
|
} else { |
|
|
|
|
Integer knownRank = getKnownCodecList().get(name); |
|
|
|
|
if (knownRank != null) { |
|
|
|
|
rank = knownRank; |
|
|
|
|
} else { |
|
|
|
|
try { |
|
|
|
|
CodecCapabilities cap = codecInfo |
|
|
|
|
.getCapabilitiesForType(mimeType); |
|
|
|
|
if (cap != null) |
|
|
|
|
rank = RANK_ACCEPTABLE; |
|
|
|
|
else |
|
|
|
|
rank = RANK_LAST_CHANCE; |
|
|
|
|
CodecCapabilities cap = codecInfo.getCapabilitiesForType(mimeType); |
|
|
|
|
if (cap != null) rank = RANK_ACCEPTABLE; |
|
|
|
|
else rank = RANK_LAST_CHANCE; |
|
|
|
|
} catch (Throwable e) { |
|
|
|
|
rank = RANK_LAST_CHANCE; |
|
|
|
|
} |
|
|
|
|
@ -196,98 +186,89 @@ public class IjkMediaCodecInfo { |
|
|
|
|
|
|
|
|
|
@TargetApi(Build.VERSION_CODES.JELLY_BEAN) |
|
|
|
|
public void dumpProfileLevels(String mimeType) { |
|
|
|
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) return; |
|
|
|
|
try { |
|
|
|
|
CodecCapabilities caps = mCodecInfo |
|
|
|
|
.getCapabilitiesForType(mimeType); |
|
|
|
|
CodecCapabilities caps = mCodecInfo.getCapabilitiesForType(mimeType); |
|
|
|
|
int maxProfile = 0; |
|
|
|
|
int maxLevel = 0; |
|
|
|
|
if (caps != null) { |
|
|
|
|
if (caps.profileLevels != null) { |
|
|
|
|
for (CodecProfileLevel profileLevel : caps.profileLevels) { |
|
|
|
|
if (profileLevel == null) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
if (profileLevel == null) continue; |
|
|
|
|
maxProfile = Math.max(maxProfile, profileLevel.profile); |
|
|
|
|
maxLevel = Math.max(maxLevel, profileLevel.level); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Log.i(TAG, |
|
|
|
|
String.format(Locale.US, "%s", |
|
|
|
|
getProfileLevelName(maxProfile, maxLevel))); |
|
|
|
|
Log.i(TAG, String.format(Locale.US, "%s", getProfileLevelName(maxProfile, maxLevel))); |
|
|
|
|
} catch (Throwable e) { |
|
|
|
|
Log.i(TAG, "profile-level: exception"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static String getProfileLevelName(int profile, int level) { |
|
|
|
|
return String.format(Locale.US, " %s Profile Level %s (%d,%d)", |
|
|
|
|
getProfileName(profile), getLevelName(level), profile, level); |
|
|
|
|
return String.format(Locale.US, " %s Profile Level %s (%d,%d)", getProfileName(profile), getLevelName(level), profile, level); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static String getProfileName(int profile) { |
|
|
|
|
switch (profile) { |
|
|
|
|
case CodecProfileLevel.AVCProfileBaseline: |
|
|
|
|
return "Baseline"; |
|
|
|
|
case CodecProfileLevel.AVCProfileMain: |
|
|
|
|
return "Main"; |
|
|
|
|
case CodecProfileLevel.AVCProfileExtended: |
|
|
|
|
return "Extends"; |
|
|
|
|
case CodecProfileLevel.AVCProfileHigh: |
|
|
|
|
return "High"; |
|
|
|
|
case CodecProfileLevel.AVCProfileHigh10: |
|
|
|
|
return "High10"; |
|
|
|
|
case CodecProfileLevel.AVCProfileHigh422: |
|
|
|
|
return "High422"; |
|
|
|
|
case CodecProfileLevel.AVCProfileHigh444: |
|
|
|
|
return "High444"; |
|
|
|
|
default: |
|
|
|
|
return "Unknown"; |
|
|
|
|
case CodecProfileLevel.AVCProfileBaseline: |
|
|
|
|
return "Baseline"; |
|
|
|
|
case CodecProfileLevel.AVCProfileMain: |
|
|
|
|
return "Main"; |
|
|
|
|
case CodecProfileLevel.AVCProfileExtended: |
|
|
|
|
return "Extends"; |
|
|
|
|
case CodecProfileLevel.AVCProfileHigh: |
|
|
|
|
return "High"; |
|
|
|
|
case CodecProfileLevel.AVCProfileHigh10: |
|
|
|
|
return "High10"; |
|
|
|
|
case CodecProfileLevel.AVCProfileHigh422: |
|
|
|
|
return "High422"; |
|
|
|
|
case CodecProfileLevel.AVCProfileHigh444: |
|
|
|
|
return "High444"; |
|
|
|
|
default: |
|
|
|
|
return "Unknown"; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static String getLevelName(int level) { |
|
|
|
|
switch (level) { |
|
|
|
|
case CodecProfileLevel.AVCLevel1: |
|
|
|
|
return "1"; |
|
|
|
|
case CodecProfileLevel.AVCLevel1b: |
|
|
|
|
return "1b"; |
|
|
|
|
case CodecProfileLevel.AVCLevel11: |
|
|
|
|
return "11"; |
|
|
|
|
case CodecProfileLevel.AVCLevel12: |
|
|
|
|
return "12"; |
|
|
|
|
case CodecProfileLevel.AVCLevel13: |
|
|
|
|
return "13"; |
|
|
|
|
case CodecProfileLevel.AVCLevel2: |
|
|
|
|
return "2"; |
|
|
|
|
case CodecProfileLevel.AVCLevel21: |
|
|
|
|
return "21"; |
|
|
|
|
case CodecProfileLevel.AVCLevel22: |
|
|
|
|
return "22"; |
|
|
|
|
case CodecProfileLevel.AVCLevel3: |
|
|
|
|
return "3"; |
|
|
|
|
case CodecProfileLevel.AVCLevel31: |
|
|
|
|
return "31"; |
|
|
|
|
case CodecProfileLevel.AVCLevel32: |
|
|
|
|
return "32"; |
|
|
|
|
case CodecProfileLevel.AVCLevel4: |
|
|
|
|
return "4"; |
|
|
|
|
case CodecProfileLevel.AVCLevel41: |
|
|
|
|
return "41"; |
|
|
|
|
case CodecProfileLevel.AVCLevel42: |
|
|
|
|
return "42"; |
|
|
|
|
case CodecProfileLevel.AVCLevel5: |
|
|
|
|
return "5"; |
|
|
|
|
case CodecProfileLevel.AVCLevel51: |
|
|
|
|
return "51"; |
|
|
|
|
case 65536: // CodecProfileLevel.AVCLevel52:
|
|
|
|
|
return "52"; |
|
|
|
|
default: |
|
|
|
|
return "0"; |
|
|
|
|
case CodecProfileLevel.AVCLevel1: |
|
|
|
|
return "1"; |
|
|
|
|
case CodecProfileLevel.AVCLevel1b: |
|
|
|
|
return "1b"; |
|
|
|
|
case CodecProfileLevel.AVCLevel11: |
|
|
|
|
return "11"; |
|
|
|
|
case CodecProfileLevel.AVCLevel12: |
|
|
|
|
return "12"; |
|
|
|
|
case CodecProfileLevel.AVCLevel13: |
|
|
|
|
return "13"; |
|
|
|
|
case CodecProfileLevel.AVCLevel2: |
|
|
|
|
return "2"; |
|
|
|
|
case CodecProfileLevel.AVCLevel21: |
|
|
|
|
return "21"; |
|
|
|
|
case CodecProfileLevel.AVCLevel22: |
|
|
|
|
return "22"; |
|
|
|
|
case CodecProfileLevel.AVCLevel3: |
|
|
|
|
return "3"; |
|
|
|
|
case CodecProfileLevel.AVCLevel31: |
|
|
|
|
return "31"; |
|
|
|
|
case CodecProfileLevel.AVCLevel32: |
|
|
|
|
return "32"; |
|
|
|
|
case CodecProfileLevel.AVCLevel4: |
|
|
|
|
return "4"; |
|
|
|
|
case CodecProfileLevel.AVCLevel41: |
|
|
|
|
return "41"; |
|
|
|
|
case CodecProfileLevel.AVCLevel42: |
|
|
|
|
return "42"; |
|
|
|
|
case CodecProfileLevel.AVCLevel5: |
|
|
|
|
return "5"; |
|
|
|
|
case CodecProfileLevel.AVCLevel51: |
|
|
|
|
return "51"; |
|
|
|
|
case 65536: // CodecProfileLevel.AVCLevel52:
|
|
|
|
|
return "52"; |
|
|
|
|
default: |
|
|
|
|
return "0"; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|