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

Side by Side 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: address comments Created 4 years, 2 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 unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.media; 5 package org.chromium.media;
6 6
7 import android.annotation.TargetApi; 7 import android.annotation.TargetApi;
8 import android.media.MediaCodec; 8 import android.media.MediaCodec;
9 import android.media.MediaCodecInfo; 9 import android.media.MediaCodecInfo;
10 import android.media.MediaCodecList; 10 import android.media.MediaCodecList;
11 import android.os.Build; 11 import android.os.Build;
12 12
13 import org.chromium.base.Log; 13 import org.chromium.base.Log;
14 import org.chromium.base.annotations.CalledByNative; 14 import org.chromium.base.annotations.CalledByNative;
15 import org.chromium.base.annotations.JNINamespace; 15 import org.chromium.base.annotations.JNINamespace;
16 import org.chromium.base.annotations.MainDex; 16 import org.chromium.base.annotations.MainDex;
17 17
18 import java.util.Arrays;
19 import java.util.List;
18 import java.util.Locale; 20 import java.util.Locale;
19 21
20 /** 22 /**
21 * A collection of MediaCodec utility functions. 23 * A collection of MediaCodec utility functions.
22 */ 24 */
23 @JNINamespace("media") 25 @JNINamespace("media")
24 class MediaCodecUtil { 26 class MediaCodecUtil {
25 private static final String TAG = "MediaCodecUtil"; 27 private static final String TAG = "cr_MediaCodecUtil";
26 28
27 // Codec direction. Keep this in sync with media_codec_direction.h. 29 // Codec direction. Keep this in sync with media_codec_direction.h.
28 static final int MEDIA_CODEC_DECODER = 0; 30 static final int MEDIA_CODEC_DECODER = 0;
29 static final int MEDIA_CODEC_ENCODER = 1; 31 static final int MEDIA_CODEC_ENCODER = 1;
30 32
31 /** 33 /**
32 * Class to pass parameters from createDecoder() 34 * Class to pass parameters from createDecoder()
33 */ 35 */
34 @MainDex 36 @MainDex
35 public static class CodecCreationInfo { 37 public static class CodecCreationInfo {
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 351
350 MediaCodecInfo.CodecCapabilities capabilities = info.getCapabilities ForType(mime); 352 MediaCodecInfo.CodecCapabilities capabilities = info.getCapabilities ForType(mime);
351 return (capabilities != null) 353 return (capabilities != null)
352 && capabilities.isFeatureSupported( 354 && capabilities.isFeatureSupported(
353 MediaCodecInfo.CodecCapabilities.FEATURE_Adaptive Playback); 355 MediaCodecInfo.CodecCapabilities.FEATURE_Adaptive Playback);
354 } catch (IllegalArgumentException e) { 356 } catch (IllegalArgumentException e) {
355 Log.e(TAG, "Cannot retrieve codec information", e); 357 Log.e(TAG, "Cannot retrieve codec information", e);
356 } 358 }
357 return false; 359 return false;
358 } 360 }
361
362 // Class describing supported media codec encoder properties.
363 private static class MediaCodecProperties {
364 public final String codecPrefix;
365 // Minimum Android SDK required for this codec to be used.
366 public final int minSdk;
367
368 MediaCodecProperties(String codecPrefix, int minSdk) {
369 this.codecPrefix = codecPrefix;
370 this.minSdk = minSdk;
371 }
372 }
373
374 // List of supported HW VP8 encoders.
375 private static final MediaCodecProperties sQcomVp8HwProperties =
376 new MediaCodecProperties("OMX.qcom.", Build.VERSION_CODES.KITKAT);
377 private static final MediaCodecProperties sExynosVp8HwProperties =
378 new MediaCodecProperties("OMX.Exynos.", Build.VERSION_CODES.M);
379 private static final MediaCodecProperties[] sVp8HwList =
380 new MediaCodecProperties[] {sQcomVp8HwProperties, sExynosVp8HwProper ties};
381
382 // List of supported HW H.264 encoders.
383 private static final MediaCodecProperties sQcomH264HwProperties =
384 new MediaCodecProperties("OMX.qcom.", Build.VERSION_CODES.KITKAT);
385 private static final MediaCodecProperties sExynosH264HwProperties =
386 new MediaCodecProperties("OMX.Exynos.", Build.VERSION_CODES.LOLLIPOP );
387 private static final MediaCodecProperties[] sH264HwList =
388 new MediaCodecProperties[] {sQcomH264HwProperties, sExynosH264HwProp erties};
389
390 // List of devices with poor H.264 encoder quality.
391 private static final String[] H264_HW_EXCEPTION_MODELS = new String[] {
392 // HW H.264 encoder on below devices has poor bitrate control - actu al bitrates deviates
393 // a lot from the target value.
394 "SAMSUNG-SGH-I337", "Nexus 7", "Nexus 4"};
395
396 /**
397 * Creates MediaCodec encoder.
398 * @param mime MIME type of the media.
399 * @return CodecCreationInfo object
400 */
401 static CodecCreationInfo createEncoder(String mime) {
402 // Always return a valid CodecCreationInfo, its |mediaCodec| field will be null
403 // if we cannot create the codec.
404 CodecCreationInfo result = new CodecCreationInfo();
405
406 assert result.mediaCodec == null;
407
408 if (mime.equals(MimeTypes.VIDEO_H264)) {
409 if (!findHwEncoder(MimeTypes.VIDEO_H264, sH264HwList)) return result ;
410 } else if (mime.equals(MimeTypes.VIDEO_VP8)) {
411 if (!findHwEncoder(MimeTypes.VIDEO_VP8, sVp8HwList)) return result;
412 }
413
414 try {
415 result.mediaCodec = MediaCodec.createEncoderByType(mime);
416 result.supportsAdaptivePlayback = false;
417 } catch (Exception e) {
418 Log.e(TAG, "Failed to create MediaCodec: %s", mime, e);
419 result.mediaCodec = null;
420 }
421 return result;
422 }
423
424 /**
425 * This is a way to blacklist misbehaving devices.
426 * @param mime MIME type as passed to mediaCodec.createEncoderByType(mime).
427 * @param supportedHwCodecProperties MediaCodecProperties of the given MIME type.
428 * @return true if this codec is supported for encoder on this device.
429 */
430 private static boolean findHwEncoder(
431 String mime, MediaCodecProperties[] supportedHwCodecProperties) {
432 // MediaCodec.setParameters is missing for JB and below, so bitrate
433 // can not be adjusted dynamically.
434 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
435 return false;
436 }
437
438 String encoderName = getDefaultCodecName(mime, MEDIA_CODEC_ENCODER, fals e);
439 if (encoderName.equals("")) return false;
440
441 // Check if this is supported HW encoder.
442 if (mime.equals(MimeTypes.VIDEO_H264)) {
443 // Check if device is in H.264 exception list.
444 List<String> exceptionModels = Arrays.asList(H264_HW_EXCEPTION_MODEL S);
445 if (exceptionModels.contains(Build.MODEL)) {
446 Log.w(TAG, "Model: " + Build.MODEL + " has black listed H.264 en coder.");
447 return false;
448 }
449 }
450
451 for (MediaCodecProperties codecProperties : supportedHwCodecProperties) {
452 if (encoderName.startsWith(codecProperties.codecPrefix)) {
453 if (Build.VERSION.SDK_INT < codecProperties.minSdk) {
454 Log.w(TAG, "Codec " + encoderName + " is disabled due to SDK version "
455 + Build.VERSION.SDK_INT);
456 continue;
457 }
458 return true;
459 }
460 }
461
462 Log.w(TAG, "Codec " + encoderName + " is not supported.");
463 return false;
464 }
465
466 /**
467 * Check if H264 HW accelerated encoder is supported.
468 * @return true if HW encoder is found on this device.
469 */
470 @CalledByNative
471 static boolean isH264EncoderSupported() {
472 return findHwEncoder(MimeTypes.VIDEO_H264, sH264HwList);
473 }
359 } 474 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698