Bug 1360626 - create a blacklist for adaptive playback support.
On some devices / os combinations, enabling adaptive playback causes decoded frame unusable.
It may cause the decode frame to be black and white or return tiled frames.
So we should do the blacklist according to the report.
MozReview-Commit-ID: j3PZXTtkXG
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/HardwareCodecCapabilityUtils.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/HardwareCodecCapabilityUtils.java
@@ -10,16 +10,18 @@ import org.mozilla.gecko.annotation.Wrap
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaCodecInfo.CodecCapabilities;
import android.media.MediaCodecList;
import android.os.Build;
import android.util.Log;
+import java.util.Locale;
+
public final class HardwareCodecCapabilityUtils {
private static final String LOGTAG = "GeckoHardwareCodecCapabilityUtils";
// List of supported HW VP8 encoders.
private static final String[] supportedVp8HwEncCodecPrefixes =
{"OMX.qcom.", "OMX.Intel." };
// List of supported HW VP8 decoders.
private static final String[] supportedVp8HwDecCodecPrefixes =
@@ -32,16 +34,21 @@ public final class HardwareCodecCapabili
COLOR_QCOM_FORMATYUV420PackedSemiPlanar32m = 0x7FA30C04;
// Allowable color formats supported by codec - in order of preference.
private static final int[] supportedColorList = {
CodecCapabilities.COLOR_FormatYUV420Planar,
CodecCapabilities.COLOR_FormatYUV420SemiPlanar,
CodecCapabilities.COLOR_QCOM_FormatYUV420SemiPlanar,
COLOR_QCOM_FORMATYUV420PackedSemiPlanar32m
};
+ private static final String[] adaptivePlaybackBlacklist =
+ {
+ "GT-I9300", // S3 (I9300 / I9300I)
+ "SCH-I535" // S3
+ };
@WrapForJNI
public static boolean findDecoderCodecInfoForMimeType(String aMimeType) {
int numCodecs = 0;
try {
numCodecs = MediaCodecList.getCodecCount();
} catch (final RuntimeException e) {
Log.e(LOGTAG, "Failed to retrieve media codec count", e);
@@ -59,31 +66,55 @@ public final class HardwareCodecCapabili
}
}
}
return false;
}
@WrapForJNI
public static boolean checkSupportsAdaptivePlayback(MediaCodec aCodec, String aMimeType) {
- // isFeatureSupported supported on API level >= 19.
- if (!(Build.VERSION.SDK_INT >= 19)) {
- return false;
- }
+ // isFeatureSupported supported on API level >= 19.
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT ||
+ isAdaptivePlaybackBlacklisted(aMimeType)) {
+ return false;
+ }
+
+ try {
+ MediaCodecInfo info = aCodec.getCodecInfo();
+ MediaCodecInfo.CodecCapabilities capabilities = info.getCapabilitiesForType(aMimeType);
+ return capabilities != null &&
+ capabilities.isFeatureSupported(
+ MediaCodecInfo.CodecCapabilities.FEATURE_AdaptivePlayback);
+ } catch (IllegalArgumentException e) {
+ Log.e(LOGTAG, "Retrieve codec information failed", e);
+ }
+ return false;
+ }
- try {
- MediaCodecInfo info = aCodec.getCodecInfo();
- MediaCodecInfo.CodecCapabilities capabilities = info.getCapabilitiesForType(aMimeType);
- return capabilities != null &&
- capabilities.isFeatureSupported(
- MediaCodecInfo.CodecCapabilities.FEATURE_AdaptivePlayback);
- } catch (IllegalArgumentException e) {
- Log.e(LOGTAG, "Retrieve codec information failed", e);
+ // See Bug1360626 and
+ // https://codereview.chromium.org/1869103002 for details.
+ private static boolean isAdaptivePlaybackBlacklisted(String aMimeType) {
+ if (!aMimeType.equals("video/avc") && !aMimeType.equals("video/avc1")) {
+ return false;
+ }
+
+ if (!Build.VERSION.RELEASE.equals("4.4.2")) {
+ return false;
+ }
+
+ if (!Build.MANUFACTURER.toLowerCase(Locale.getDefault()).equals("samsung")) {
+ return false;
+ }
+
+ for (String model : adaptivePlaybackBlacklist) {
+ if (Build.MODEL.startsWith(model)) {
+ return true;
}
- return false;
+ }
+ return false;
}
public static boolean getHWEncoderCapability() {
if (Build.VERSION.SDK_INT >= 20) {
for (int i = 0; i < MediaCodecList.getCodecCount(); ++i) {
MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i);
if (!info.isEncoder()) {
continue;