Bug 1360626 - create a blacklist for adaptive playback support. draft
authorJames Cheng <jacheng@mozilla.com>
Wed, 03 May 2017 13:49:23 +0800
changeset 572399 b013f9d86906647be3d7b195bc4356dfd4ef93e7
parent 571618 a748acbebbde373a88868dc02910fb2bc5e6a023
child 627014 e7e4d041075a37b2a52cea10cb6b29aba49e92bd
push id57064
push userbmo:jacheng@mozilla.com
push dateThu, 04 May 2017 04:17:37 +0000
bugs1360626
milestone55.0a1
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
mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/HardwareCodecCapabilityUtils.java
--- 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;