Skip to content

Commit

Permalink
Expose whether decoders support tunneling
Browse files Browse the repository at this point in the history
This is a first step toward supporting tunneled playback

Issue: google#1688

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=141167501
  • Loading branch information
ojw28 committed Dec 6, 2016
1 parent 99957bb commit 4db6f1e
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ protected int supportsFormat(MediaCodecSelector mediaCodecSelector, Format forma
if (allowPassthrough(mimeType) && mediaCodecSelector.getPassthroughDecoderInfo() != null) {
return ADAPTIVE_NOT_SEAMLESS | FORMAT_HANDLED;
}
MediaCodecInfo decoderInfo = mediaCodecSelector.getDecoderInfo(mimeType, false);
MediaCodecInfo decoderInfo = mediaCodecSelector.getDecoderInfo(mimeType, false, false);
if (decoderInfo == null) {
return FORMAT_UNSUPPORTED_SUBTYPE;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ public final class MediaCodecInfo {
*/
public final boolean adaptive;

/**
* Whether the decoder supports tunneling.
*
* @see CodecCapabilities#isFeatureSupported(String)
* @see CodecCapabilities#FEATURE_TunneledPlayback
*/
public final boolean tunneling;

private final String mimeType;
private final CodecCapabilities capabilities;

Expand Down Expand Up @@ -86,6 +94,7 @@ private MediaCodecInfo(String name, String mimeType, CodecCapabilities capabilit
this.mimeType = mimeType;
this.capabilities = capabilities;
adaptive = capabilities != null && isAdaptive(capabilities);
tunneling = capabilities != null && isTunneling(capabilities);
}

/**
Expand Down Expand Up @@ -270,4 +279,13 @@ private static boolean isAdaptiveV19(CodecCapabilities capabilities) {
return capabilities.isFeatureSupported(CodecCapabilities.FEATURE_AdaptivePlayback);
}

private static boolean isTunneling(CodecCapabilities capabilities) {
return Util.SDK_INT >= 21 && isTunnelingV21(capabilities);
}

@TargetApi(21)
private static boolean isTunnelingV21(CodecCapabilities capabilities) {
return capabilities.isFeatureSupported(CodecCapabilities.FEATURE_TunneledPlayback);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ protected abstract int supportsFormat(MediaCodecSelector mediaCodecSelector, For
*/
protected MediaCodecInfo getDecoderInfo(MediaCodecSelector mediaCodecSelector,
Format format, boolean requiresSecureDecoder) throws DecoderQueryException {
return mediaCodecSelector.getDecoderInfo(format.sampleMimeType, requiresSecureDecoder);
return mediaCodecSelector.getDecoderInfo(format.sampleMimeType, requiresSecureDecoder, false);
}

/**
Expand Down Expand Up @@ -1020,7 +1020,7 @@ private static boolean codecNeedsAdaptationWorkaround(String name) {
return Util.SDK_INT < 24
&& ("OMX.Nvidia.h264.decode".equals(name) || "OMX.Nvidia.h264.decode.secure".equals(name))
&& ("flounder".equals(Util.DEVICE) || "flounder_lte".equals(Util.DEVICE)
|| "grouper".equals(Util.DEVICE) || "tilapia".equals(Util.DEVICE));
|| "grouper".equals(Util.DEVICE) || "tilapia".equals(Util.DEVICE));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ public interface MediaCodecSelector {
MediaCodecSelector DEFAULT = new MediaCodecSelector() {

@Override
public MediaCodecInfo getDecoderInfo(String mimeType, boolean requiresSecureDecoder)
throws DecoderQueryException {
return MediaCodecUtil.getDecoderInfo(mimeType, requiresSecureDecoder);
public MediaCodecInfo getDecoderInfo(String mimeType, boolean requiresSecureDecoder,
boolean requiresTunneling) throws DecoderQueryException {
return MediaCodecUtil.getDecoderInfo(mimeType, requiresSecureDecoder, requiresTunneling);
}

@Override
Expand All @@ -46,12 +46,13 @@ public MediaCodecInfo getPassthroughDecoderInfo() throws DecoderQueryException {
*
* @param mimeType The mime type for which a decoder is required.
* @param requiresSecureDecoder Whether a secure decoder is required.
* @param requiresTunneling Whether a decoder that supports tunneling is required.
* @return A {@link MediaCodecInfo} describing the decoder, or null if no suitable decoder
* exists.
* @throws DecoderQueryException Thrown if there was an error querying decoders.
*/
MediaCodecInfo getDecoderInfo(String mimeType, boolean requiresSecureDecoder)
throws DecoderQueryException;
MediaCodecInfo getDecoderInfo(String mimeType, boolean requiresSecureDecoder,
boolean requiresTunneling) throws DecoderQueryException;

/**
* Selects a decoder to instantiate for audio passthrough.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,9 @@ private MediaCodecUtil() {}
/**
* Optional call to warm the codec cache for a given mime type.
* <p>
* Calling this method may speed up subsequent calls to {@link #getDecoderInfo(String, boolean)}.
* Calling this method may speed up subsequent calls to
* {@link #getDecoderInfo(String, boolean, boolean)} and
* {@link #getDecoderInfos(String, boolean)}.
*
* @param mimeType The mime type.
* @param secure Whether the decoder is required to support secure decryption. Always pass false
Expand Down Expand Up @@ -113,14 +115,26 @@ public static MediaCodecInfo getPassthroughDecoderInfo() {
* @param mimeType The mime type.
* @param secure Whether the decoder is required to support secure decryption. Always pass false
* unless secure decryption really is required.
* @param tunneling Whether the decoder is required to support tunneling. Always pass false unless
* tunneling really is required.
* @return A {@link MediaCodecInfo} describing the decoder, or null if no suitable decoder
* exists.
* @throws DecoderQueryException If there was an error querying the available decoders.
*/
public static MediaCodecInfo getDecoderInfo(String mimeType, boolean secure)
public static MediaCodecInfo getDecoderInfo(String mimeType, boolean secure, boolean tunneling)
throws DecoderQueryException {
List<MediaCodecInfo> decoderInfos = getDecoderInfos(mimeType, secure);
return decoderInfos.isEmpty() ? null : decoderInfos.get(0);
if (tunneling) {
for (int i = 0; i < decoderInfos.size(); i++) {
MediaCodecInfo decoderInfo = decoderInfos.get(i);
if (decoderInfo.tunneling) {
return decoderInfo;
}
}
return null;
} else {
return decoderInfos.isEmpty() ? null : decoderInfos.get(0);
}
}

/**
Expand Down Expand Up @@ -178,11 +192,10 @@ private static List<MediaCodecInfo> getDecoderInfosInternal(
boolean secure = mediaCodecList.isSecurePlaybackSupported(mimeType, capabilities);
if ((secureDecodersExplicit && key.secure == secure)
|| (!secureDecodersExplicit && !key.secure)) {
decoderInfos.add(
MediaCodecInfo.newInstance(codecName, mimeType, capabilities));
decoderInfos.add(MediaCodecInfo.newInstance(codecName, mimeType, capabilities));
} else if (!secureDecodersExplicit && secure) {
decoderInfos.add(MediaCodecInfo.newInstance(codecName + ".secure",
mimeType, capabilities));
decoderInfos.add(MediaCodecInfo.newInstance(codecName + ".secure", mimeType,
capabilities));
// It only makes sense to have one synthesized secure decoder, return immediately.
return decoderInfos;
}
Expand Down Expand Up @@ -292,7 +305,7 @@ private static boolean isCodecUsableDecoder(android.media.MediaCodecInfo info, S
public static int maxH264DecodableFrameSize() throws DecoderQueryException {
if (maxH264DecodableFrameSize == -1) {
int result = 0;
MediaCodecInfo decoderInfo = getDecoderInfo(MimeTypes.VIDEO_H264, false);
MediaCodecInfo decoderInfo = getDecoderInfo(MimeTypes.VIDEO_H264, false, false);
if (decoderInfo != null) {
for (CodecProfileLevel profileLevel : decoderInfo.getProfileLevels()) {
result = Math.max(avcLevelToMaxFrameSize(profileLevel.level), result);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ protected int supportsFormat(MediaCodecSelector mediaCodecSelector, Format forma
}
}
MediaCodecInfo decoderInfo = mediaCodecSelector.getDecoderInfo(mimeType,
requiresSecureDecryption);
requiresSecureDecryption, false);
if (decoderInfo == null) {
return FORMAT_UNSUPPORTED_SUBTYPE;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -633,7 +633,7 @@ private void testDashPlayback(HostActivity activity, String streamName,
}

private static boolean shouldSkipAdaptiveTest(String mimeType) throws DecoderQueryException {
MediaCodecInfo decoderInfo = MediaCodecUtil.getDecoderInfo(mimeType, false);
MediaCodecInfo decoderInfo = MediaCodecUtil.getDecoderInfo(mimeType, false, false);
assertNotNull(decoderInfo);
if (decoderInfo.adaptive) {
return false;
Expand Down Expand Up @@ -706,7 +706,8 @@ protected final StreamingDrmSessionManager<FrameworkMediaCrypto> buildDrmSession
if (isWidevineEncrypted) {
try {
// Force L3 if secure decoder is not available.
boolean forceL3Widevine = MediaCodecUtil.getDecoderInfo(videoMimeType, true) == null;
boolean forceL3Widevine =
MediaCodecUtil.getDecoderInfo(videoMimeType, true, false) == null;
MediaDrm mediaDrm = new MediaDrm(WIDEVINE_UUID);
String securityProperty = mediaDrm.getPropertyString(SECURITY_LEVEL_PROPERTY);
String widevineContentId = forceL3Widevine ? WIDEVINE_SW_CRYPTO_CONTENT_ID
Expand Down

0 comments on commit 4db6f1e

Please sign in to comment.