| OLD | NEW |
| 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.MediaCodec.CryptoInfo; | 9 import android.media.MediaCodec.CryptoInfo; |
| 10 import android.media.MediaCodecInfo; | 10 import android.media.MediaCodecInfo; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 import java.util.NoSuchElementException; | 26 import java.util.NoSuchElementException; |
| 27 | 27 |
| 28 /** | 28 /** |
| 29 * A collection of MediaCodec utility functions. | 29 * A collection of MediaCodec utility functions. |
| 30 */ | 30 */ |
| 31 @JNINamespace("media") | 31 @JNINamespace("media") |
| 32 @MainDex | 32 @MainDex |
| 33 class MediaCodecUtil { | 33 class MediaCodecUtil { |
| 34 private static final String TAG = "cr_MediaCodecUtil"; | 34 private static final String TAG = "cr_MediaCodecUtil"; |
| 35 | 35 |
| 36 // Codec direction. Keep this in sync with media_codec_direction.h. | |
| 37 static final int MEDIA_CODEC_DECODER = 0; | |
| 38 static final int MEDIA_CODEC_ENCODER = 1; | |
| 39 | |
| 40 /** | 36 /** |
| 41 * Class to pass parameters from createDecoder() | 37 * Class to pass parameters from createDecoder() |
| 42 */ | 38 */ |
| 43 public static class CodecCreationInfo { | 39 public static class CodecCreationInfo { |
| 44 public MediaCodec mediaCodec; | 40 public MediaCodec mediaCodec; |
| 45 public boolean supportsAdaptivePlayback; | 41 public boolean supportsAdaptivePlayback; |
| 46 public BitrateAdjustmentTypes bitrateAdjustmentType = BitrateAdjustmentT
ypes.NO_ADJUSTMENT; | 42 public BitrateAdjustmentTypes bitrateAdjustmentType = BitrateAdjustmentT
ypes.NO_ADJUSTMENT; |
| 47 } | 43 } |
| 48 | 44 |
| 49 public static final class MimeTypes { | 45 public static final class MimeTypes { |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 * @param mime MIME type of the media. | 137 * @param mime MIME type of the media. |
| 142 * @param direction Whether this is encoder or decoder. | 138 * @param direction Whether this is encoder or decoder. |
| 143 * @param requireSoftwareCodec Whether we require a software codec. | 139 * @param requireSoftwareCodec Whether we require a software codec. |
| 144 * @return name of the codec. | 140 * @return name of the codec. |
| 145 */ | 141 */ |
| 146 @CalledByNative | 142 @CalledByNative |
| 147 private static String getDefaultCodecName( | 143 private static String getDefaultCodecName( |
| 148 String mime, int direction, boolean requireSoftwareCodec) { | 144 String mime, int direction, boolean requireSoftwareCodec) { |
| 149 MediaCodecListHelper codecListHelper = new MediaCodecListHelper(); | 145 MediaCodecListHelper codecListHelper = new MediaCodecListHelper(); |
| 150 for (MediaCodecInfo info : codecListHelper) { | 146 for (MediaCodecInfo info : codecListHelper) { |
| 151 int codecDirection = info.isEncoder() ? MEDIA_CODEC_ENCODER : MEDIA_
CODEC_DECODER; | 147 int codecDirection = |
| 148 info.isEncoder() ? MediaCodecDirection.ENCODER : MediaCodecD
irection.DECODER; |
| 152 if (codecDirection != direction) continue; | 149 if (codecDirection != direction) continue; |
| 153 | 150 |
| 154 if (requireSoftwareCodec && !isSoftwareCodec(info.getName())) contin
ue; | 151 if (requireSoftwareCodec && !isSoftwareCodec(info.getName())) contin
ue; |
| 155 | 152 |
| 156 for (String supportedType : info.getSupportedTypes()) { | 153 for (String supportedType : info.getSupportedTypes()) { |
| 157 if (supportedType.equalsIgnoreCase(mime)) return info.getName(); | 154 if (supportedType.equalsIgnoreCase(mime)) return info.getName(); |
| 158 } | 155 } |
| 159 } | 156 } |
| 160 | 157 |
| 161 Log.e(TAG, "Decoder for type %s is not supported on this device", mime); | 158 Log.e(TAG, "Decoder for type %s is not supported on this device", mime); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 214 final int[][] bitrateMapping = { | 211 final int[][] bitrateMapping = { |
| 215 {200, 10}, {800, 11}, {1800, 20}, {3600, 21}, {7200, 30}, {12000
, 31}, {18000, 40}, | 212 {200, 10}, {800, 11}, {1800, 20}, {3600, 21}, {7200, 30}, {12000
, 31}, {18000, 40}, |
| 216 {30000, 41}, {60000, 50}, {120000, 51}, {180000, 52}, | 213 {30000, 41}, {60000, 50}, {120000, 51}, {180000, 52}, |
| 217 }; | 214 }; |
| 218 VideoCapabilities videoCapabilities = codecCapabilities.getVideoCapabili
ties(); | 215 VideoCapabilities videoCapabilities = codecCapabilities.getVideoCapabili
ties(); |
| 219 for (int[] entry : bitrateMapping) { | 216 for (int[] entry : bitrateMapping) { |
| 220 int bitrate = entry[0]; | 217 int bitrate = entry[0]; |
| 221 int level = entry[1]; | 218 int level = entry[1]; |
| 222 if (videoCapabilities.getBitrateRange().contains(bitrate)) { | 219 if (videoCapabilities.getBitrateRange().contains(bitrate)) { |
| 223 // Assume all platforms before N only support VP9 profile 0. | 220 // Assume all platforms before N only support VP9 profile 0. |
| 224 profileLevels.addCodecProfileLevel("VP9", 12 /* VP9PROFILE_PROFI
LE0 */, level); | 221 profileLevels.addCodecProfileLevel( |
| 222 VideoCodec.kCodecVP9, VideoCodecProfile.VP9PROFILE_PROFI
LE0, level); |
| 225 } | 223 } |
| 226 } | 224 } |
| 227 } | 225 } |
| 228 | 226 |
| 229 /** | 227 /** |
| 230 * Return an array of supported codecs and profiles. | 228 * Return an array of supported codecs and profiles. |
| 231 */ | 229 */ |
| 232 @CalledByNative | 230 @CalledByNative |
| 233 private static Object[] getSupportedCodecProfileLevels() { | 231 private static Object[] getSupportedCodecProfileLevels() { |
| 234 CodecProfileLevelList profileLevels = new CodecProfileLevelList(); | 232 CodecProfileLevelList profileLevels = new CodecProfileLevelList(); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 274 | 272 |
| 275 // Do not create codec for blacklisted devices. | 273 // Do not create codec for blacklisted devices. |
| 276 if (!isDecoderSupportedForDevice(mime)) { | 274 if (!isDecoderSupportedForDevice(mime)) { |
| 277 Log.e(TAG, "Decoder for type %s is not supported on this device", mi
me); | 275 Log.e(TAG, "Decoder for type %s is not supported on this device", mi
me); |
| 278 return result; | 276 return result; |
| 279 } | 277 } |
| 280 | 278 |
| 281 try { | 279 try { |
| 282 // |isSecure| only applies to video decoders. | 280 // |isSecure| only applies to video decoders. |
| 283 if (mime.startsWith("video") && isSecure) { | 281 if (mime.startsWith("video") && isSecure) { |
| 284 String decoderName = | 282 String decoderName = getDefaultCodecName( |
| 285 getDefaultCodecName(mime, MEDIA_CODEC_DECODER, requireSo
ftwareCodec); | 283 mime, MediaCodecDirection.DECODER, requireSoftwareCodec)
; |
| 286 if (decoderName.equals("")) return null; | 284 if (decoderName.equals("")) return null; |
| 287 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { | 285 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { |
| 288 // To work around an issue that we cannot get the codec info
from the secure | 286 // To work around an issue that we cannot get the codec info
from the secure |
| 289 // decoder, create an insecure decoder first so that we can
query its codec | 287 // decoder, create an insecure decoder first so that we can
query its codec |
| 290 // info. http://b/15587335. | 288 // info. http://b/15587335. |
| 291 // Futhermore, it is impossible to create an insecure decode
r if the secure | 289 // Futhermore, it is impossible to create an insecure decode
r if the secure |
| 292 // one is already created. | 290 // one is already created. |
| 293 MediaCodec insecureCodec = MediaCodec.createByCodecName(deco
derName); | 291 MediaCodec insecureCodec = MediaCodec.createByCodecName(deco
derName); |
| 294 result.supportsAdaptivePlayback = | 292 result.supportsAdaptivePlayback = |
| 295 codecSupportsAdaptivePlayback(insecureCodec, mime); | 293 codecSupportsAdaptivePlayback(insecureCodec, mime); |
| 296 insecureCodec.release(); | 294 insecureCodec.release(); |
| 297 } | 295 } |
| 298 result.mediaCodec = MediaCodec.createByCodecName(decoderName + "
.secure"); | 296 result.mediaCodec = MediaCodec.createByCodecName(decoderName + "
.secure"); |
| 299 } else { | 297 } else { |
| 300 if (requireSoftwareCodec) { | 298 if (requireSoftwareCodec) { |
| 301 String decoderName = | 299 String decoderName = getDefaultCodecName( |
| 302 getDefaultCodecName(mime, MEDIA_CODEC_DECODER, requi
reSoftwareCodec); | 300 mime, MediaCodecDirection.DECODER, requireSoftwareCo
dec); |
| 303 result.mediaCodec = MediaCodec.createByCodecName(decoderName
); | 301 result.mediaCodec = MediaCodec.createByCodecName(decoderName
); |
| 304 } else { | 302 } else { |
| 305 result.mediaCodec = MediaCodec.createDecoderByType(mime); | 303 result.mediaCodec = MediaCodec.createDecoderByType(mime); |
| 306 } | 304 } |
| 307 result.supportsAdaptivePlayback = | 305 result.supportsAdaptivePlayback = |
| 308 codecSupportsAdaptivePlayback(result.mediaCodec, mime); | 306 codecSupportsAdaptivePlayback(result.mediaCodec, mime); |
| 309 } | 307 } |
| 310 } catch (Exception e) { | 308 } catch (Exception e) { |
| 311 Log.e(TAG, "Failed to create MediaCodec: %s, isSecure: %s, requireSo
ftwareCodec: %s", | 309 Log.e(TAG, "Failed to create MediaCodec: %s, isSecure: %s, requireSo
ftwareCodec: %s", |
| 312 mime, isSecure, requireSoftwareCodec ? "yes" : "no", e); | 310 mime, isSecure, requireSoftwareCodec ? "yes" : "no", e); |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 626 * supported. | 624 * supported. |
| 627 * This method was introduced in Android N. Note that if platformSupportsCbc
sEncryption | 625 * This method was introduced in Android N. Note that if platformSupportsCbc
sEncryption |
| 628 * returns true, then this function will set the pattern. | 626 * returns true, then this function will set the pattern. |
| 629 */ | 627 */ |
| 630 static void setPatternIfSupported(CryptoInfo cryptoInfo, int encrypt, int sk
ip) { | 628 static void setPatternIfSupported(CryptoInfo cryptoInfo, int encrypt, int sk
ip) { |
| 631 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { | 629 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { |
| 632 cryptoInfo.setPattern(new CryptoInfo.Pattern(encrypt, skip)); | 630 cryptoInfo.setPattern(new CryptoInfo.Pattern(encrypt, skip)); |
| 633 } | 631 } |
| 634 } | 632 } |
| 635 } | 633 } |
| OLD | NEW |