Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(868)

Unified Diff: media/base/android/java/src/org/chromium/media/MediaCodecUtil.java

Issue 2358683002: Android: enable/disable WebRTC HW H264 with a flag. (Closed)
Patch Set: loop codecs in fineHWEncoder() and other fixes. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: media/base/android/java/src/org/chromium/media/MediaCodecUtil.java
diff --git a/media/base/android/java/src/org/chromium/media/MediaCodecUtil.java b/media/base/android/java/src/org/chromium/media/MediaCodecUtil.java
index f6d97af9f23fd9c05cb4d45dcdbe26f5cffca74e..433bfae4626bb79729cadeac970a686b8ddc01b0 100644
--- a/media/base/android/java/src/org/chromium/media/MediaCodecUtil.java
+++ b/media/base/android/java/src/org/chromium/media/MediaCodecUtil.java
@@ -15,6 +15,8 @@ import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.MainDex;
+import java.util.Arrays;
+import java.util.List;
import java.util.Locale;
/**
@@ -22,7 +24,7 @@ import java.util.Locale;
*/
@JNINamespace("media")
class MediaCodecUtil {
- private static final String TAG = "MediaCodecUtil";
+ private static final String TAG = "cr_MediaCodecUtil";
// Codec direction. Keep this in sync with media_codec_direction.h.
static final int MEDIA_CODEC_DECODER = 0;
@@ -356,4 +358,135 @@ class MediaCodecUtil {
}
return false;
}
+
+ // Class describing supported media codec encoder properties.
+ private static class MediaCodecProperties {
watk 2016/10/01 01:06:54 I think this would be simpler if you used an enum
braveyao 2016/10/03 23:50:15 Done.
+ public final String codecPrefix;
+ // Minimum Android SDK required for this codec to be used.
+ public final int minSdk;
+
+ MediaCodecProperties(String codecPrefix, int minSdk) {
+ this.codecPrefix = codecPrefix;
+ this.minSdk = minSdk;
+ }
+ }
+
+ // List of supported HW VP8 encoders.
+ private static final MediaCodecProperties sQcomVp8HwProperties =
+ new MediaCodecProperties("OMX.qcom.", Build.VERSION_CODES.KITKAT);
+ private static final MediaCodecProperties sExynosVp8HwProperties =
+ new MediaCodecProperties("OMX.Exynos.", Build.VERSION_CODES.M);
+ private static final MediaCodecProperties[] sVp8HwList =
+ new MediaCodecProperties[] {sQcomVp8HwProperties, sExynosVp8HwProperties};
+
+ // List of supported HW H.264 encoders.
+ private static final MediaCodecProperties sQcomH264HwProperties =
+ new MediaCodecProperties("OMX.qcom.", Build.VERSION_CODES.KITKAT);
+ private static final MediaCodecProperties sExynosH264HwProperties =
+ new MediaCodecProperties("OMX.Exynos.", Build.VERSION_CODES.LOLLIPOP);
+ private static final MediaCodecProperties[] sH264HwList =
+ new MediaCodecProperties[] {sQcomH264HwProperties, sExynosH264HwProperties};
+
+ // List of devices with poor H.264 encoder quality.
+ private static final String[] H264_HW_EXCEPTION_MODELS = new String[] {
+ // HW H.264 encoder on below devices has poor bitrate control - actual bitrates deviates
+ // a lot from the target value.
+ "SAMSUNG-SGH-I337", "Nexus 7", "Nexus 4"};
watk 2016/10/01 01:06:54 "Blacklist" is a more common term for this. What a
braveyao 2016/10/03 23:50:15 Done.
+
+ /**
+ * Creates MediaCodec encoder.
+ * @param mime MIME type of the media.
+ * @return CodecCreationInfo object
+ */
+ static CodecCreationInfo createEncoder(String mime) {
+ // Always return a valid CodecCreationInfo, its |mediaCodec| field will be null
+ // if we cannot create the codec.
+ CodecCreationInfo result = new CodecCreationInfo();
+
+ assert result.mediaCodec == null;
watk 2016/10/01 01:06:54 I see that you copied this from above, but I don't
braveyao 2016/10/03 23:50:15 Done.
+
+ if (mime.equals(MimeTypes.VIDEO_H264)) {
+ if (!findHwEncoder(MimeTypes.VIDEO_H264, sH264HwList)) return result;
+ } else if (mime.equals(MimeTypes.VIDEO_VP8)) {
+ if (!findHwEncoder(MimeTypes.VIDEO_VP8, sVp8HwList)) return result;
+ }
+
+ try {
+ result.mediaCodec = MediaCodec.createEncoderByType(mime);
+ result.supportsAdaptivePlayback = false;
+ } catch (Exception e) {
+ Log.e(TAG, "Failed to create MediaCodec: %s", mime, e);
+ result.mediaCodec = null;
watk 2016/10/01 01:06:54 This is already null?
braveyao 2016/10/03 23:50:15 Done.
+ }
+ return result;
+ }
+
+ /**
+ * This is a way to blacklist misbehaving devices.
+ * @param mime MIME type as passed to mediaCodec.createEncoderByType(mime).
+ * @param supportedHwCodecProperties MediaCodecProperties of the given MIME type.
+ * @return true if this codec is supported for encoder on this device.
+ */
+ private static boolean findHwEncoder(
watk 2016/10/01 01:06:54 Rename this to isEncoderSupportedByDevice to mirro
braveyao 2016/10/03 23:50:14 Done.
+ String mime, MediaCodecProperties[] supportedHwCodecProperties) {
+ // MediaCodec.setParameters is missing for JB and below, so bitrate
+ // can not be adjusted dynamically.
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
+ return false;
+ }
+
+ // Check if this is supported HW encoder.
+ if (mime.equals(MimeTypes.VIDEO_H264)) {
+ // Check if device is in H.264 exception list.
+ List<String> exceptionModels = Arrays.asList(H264_HW_EXCEPTION_MODELS);
+ if (exceptionModels.contains(Build.MODEL)) {
+ Log.w(TAG, "Model: " + Build.MODEL + " has black listed H.264 encoder.");
watk 2016/10/01 01:06:54 s/black listed/blacklisted
braveyao 2016/10/03 23:50:15 Done.
+ return false;
+ }
+ }
+
+ MediaCodecListHelper codecListHelper = new MediaCodecListHelper();
+ int codecCount = codecListHelper.getCodecCount();
+ for (int i = 0; i < codecCount; ++i) {
+ MediaCodecInfo info = codecListHelper.getCodecInfoAt(i);
+
+ if (!info.isEncoder() || isSoftwareCodec(info.getName())) continue;
+
+ String encoderName = null;
+ for (String mimeType : info.getSupportedTypes()) {
+ if (mimeType.equalsIgnoreCase(mime)) {
+ encoderName = info.getName();
+ break;
+ }
+ }
+
+ if (encoderName == null) {
+ continue; // No HW support in this codec; try the next one.
+ }
+
+ for (MediaCodecProperties codecProperties : supportedHwCodecProperties) {
+ if (encoderName.startsWith(codecProperties.codecPrefix)) {
+ if (Build.VERSION.SDK_INT < codecProperties.minSdk) {
+ Log.w(TAG, "Codec " + encoderName + " is disabled due to SDK version "
+ + Build.VERSION.SDK_INT);
+ continue;
+ }
+ Log.d(TAG, "Found target encoder for mime " + mime + " : " + encoderName);
+ return true;
+ }
+ }
+ }
+
+ Log.w(TAG, "HW encoder for " + mime + " is not available on this device.");
+ return false;
+ }
+
+ /**
+ * Check if H264 HW accelerated encoder is supported.
+ * @return true if HW encoder is found on this device.
+ */
+ @CalledByNative
+ static boolean isH264EncoderSupported() {
+ return findHwEncoder(MimeTypes.VIDEO_H264, sH264HwList);
+ }
}

Powered by Google App Engine
This is Rietveld 408576698