mirror of
https://github.com/samsonjs/media.git
synced 2026-03-30 10:15:48 +00:00
Report tunneling support via RendererCapabilities API
Also revert ability to query for a decoder that explicitly supports tunneling, since in the new design we'll just be querying the first decoder provided by the MediaCodecSelector and then reporting what it supports. This is in line with what we do when reporting support for adaptive switching. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=144315746
This commit is contained in:
parent
5752524442
commit
e125ed705e
8 changed files with 42 additions and 38 deletions
|
|
@ -79,6 +79,20 @@ public interface RendererCapabilities {
|
|||
*/
|
||||
int ADAPTIVE_NOT_SUPPORTED = 0b0000;
|
||||
|
||||
/**
|
||||
* A mask to apply to the result of {@link #supportsFormat(Format)} to obtain one of
|
||||
* {@link #TUNNELING_SUPPORTED} and {@link #TUNNELING_NOT_SUPPORTED}.
|
||||
*/
|
||||
int TUNNELING_SUPPORT_MASK = 0b10000;
|
||||
/**
|
||||
* The {@link Renderer} supports tunneled output.
|
||||
*/
|
||||
int TUNNELING_SUPPORTED = 0b10000;
|
||||
/**
|
||||
* The {@link Renderer} does not support tunneled output.
|
||||
*/
|
||||
int TUNNELING_NOT_SUPPORTED = 0b00000;
|
||||
|
||||
/**
|
||||
* Returns the track type that the {@link Renderer} handles. For example, a video renderer will
|
||||
* return {@link C#TRACK_TYPE_VIDEO}, an audio renderer will return {@link C#TRACK_TYPE_AUDIO}, a
|
||||
|
|
@ -91,7 +105,7 @@ public interface RendererCapabilities {
|
|||
|
||||
/**
|
||||
* Returns the extent to which the {@link Renderer} supports a given format. The returned value is
|
||||
* the bitwise OR of two properties:
|
||||
* the bitwise OR of three properties:
|
||||
* <ul>
|
||||
* <li>The level of support for the format itself. One of {@link #FORMAT_HANDLED},
|
||||
* {@link #FORMAT_EXCEEDS_CAPABILITIES}, {@link #FORMAT_UNSUPPORTED_SUBTYPE} and
|
||||
|
|
@ -99,9 +113,12 @@ public interface RendererCapabilities {
|
|||
* <li>The level of support for adapting from the format to another format of the same mime type.
|
||||
* One of {@link #ADAPTIVE_SEAMLESS}, {@link #ADAPTIVE_NOT_SEAMLESS} and
|
||||
* {@link #ADAPTIVE_NOT_SUPPORTED}.</li>
|
||||
* <li>The level of support for tunneling. One of {@link #TUNNELING_SUPPORTED} and
|
||||
* {@link #TUNNELING_NOT_SUPPORTED}.</li>
|
||||
* </ul>
|
||||
* The individual properties can be retrieved by performing a bitwise AND with
|
||||
* {@link #FORMAT_SUPPORT_MASK} and {@link #ADAPTIVE_SUPPORT_MASK} respectively.
|
||||
* {@link #FORMAT_SUPPORT_MASK}, {@link #ADAPTIVE_SUPPORT_MASK} and
|
||||
* {@link #TUNNELING_SUPPORT_MASK} respectively.
|
||||
*
|
||||
* @param format The format.
|
||||
* @return The extent to which the renderer is capable of supporting the given format.
|
||||
|
|
|
|||
|
|
@ -138,10 +138,11 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
|
|||
if (!MimeTypes.isAudio(mimeType)) {
|
||||
return FORMAT_UNSUPPORTED_TYPE;
|
||||
}
|
||||
int tunnelingSupport = Util.SDK_INT >= 21 ? TUNNELING_SUPPORTED : TUNNELING_NOT_SUPPORTED;
|
||||
if (allowPassthrough(mimeType) && mediaCodecSelector.getPassthroughDecoderInfo() != null) {
|
||||
return ADAPTIVE_NOT_SEAMLESS | FORMAT_HANDLED;
|
||||
return ADAPTIVE_NOT_SEAMLESS | tunnelingSupport | FORMAT_HANDLED;
|
||||
}
|
||||
MediaCodecInfo decoderInfo = mediaCodecSelector.getDecoderInfo(mimeType, false, false);
|
||||
MediaCodecInfo decoderInfo = mediaCodecSelector.getDecoderInfo(mimeType, false);
|
||||
if (decoderInfo == null) {
|
||||
return FORMAT_UNSUPPORTED_SUBTYPE;
|
||||
}
|
||||
|
|
@ -152,7 +153,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
|
|||
&& (format.channelCount == Format.NO_VALUE
|
||||
|| decoderInfo.isAudioChannelCountSupportedV21(format.channelCount)));
|
||||
int formatSupport = decoderCapable ? FORMAT_HANDLED : FORMAT_EXCEEDS_CAPABILITIES;
|
||||
return ADAPTIVE_NOT_SEAMLESS | formatSupport;
|
||||
return ADAPTIVE_NOT_SEAMLESS | tunnelingSupport | formatSupport;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -158,7 +158,8 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements
|
|||
if (formatSupport == FORMAT_UNSUPPORTED_TYPE || formatSupport == FORMAT_UNSUPPORTED_SUBTYPE) {
|
||||
return formatSupport;
|
||||
}
|
||||
return ADAPTIVE_NOT_SEAMLESS | formatSupport;
|
||||
int tunnelingSupport = Util.SDK_INT >= 21 ? TUNNELING_SUPPORTED : TUNNELING_NOT_SUPPORTED;
|
||||
return ADAPTIVE_NOT_SEAMLESS | tunnelingSupport | formatSupport;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -270,7 +270,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
|||
*/
|
||||
protected MediaCodecInfo getDecoderInfo(MediaCodecSelector mediaCodecSelector,
|
||||
Format format, boolean requiresSecureDecoder) throws DecoderQueryException {
|
||||
return mediaCodecSelector.getDecoderInfo(format.sampleMimeType, requiresSecureDecoder, false);
|
||||
return mediaCodecSelector.getDecoderInfo(format.sampleMimeType, requiresSecureDecoder);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -29,9 +29,9 @@ public interface MediaCodecSelector {
|
|||
MediaCodecSelector DEFAULT = new MediaCodecSelector() {
|
||||
|
||||
@Override
|
||||
public MediaCodecInfo getDecoderInfo(String mimeType, boolean requiresSecureDecoder,
|
||||
boolean requiresTunneling) throws DecoderQueryException {
|
||||
return MediaCodecUtil.getDecoderInfo(mimeType, requiresSecureDecoder, requiresTunneling);
|
||||
public MediaCodecInfo getDecoderInfo(String mimeType, boolean requiresSecureDecoder)
|
||||
throws DecoderQueryException {
|
||||
return MediaCodecUtil.getDecoderInfo(mimeType, requiresSecureDecoder);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -46,13 +46,11 @@ public interface MediaCodecSelector {
|
|||
*
|
||||
* @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.
|
||||
* @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,
|
||||
boolean requiresTunneling) throws DecoderQueryException;
|
||||
MediaCodecInfo getDecoderInfo(String mimeType, boolean requiresSecureDecoder)
|
||||
throws DecoderQueryException;
|
||||
|
||||
/**
|
||||
* Selects a decoder to instantiate for audio passthrough.
|
||||
|
|
|
|||
|
|
@ -81,9 +81,8 @@ public final class 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, boolean)} and
|
||||
* {@link #getDecoderInfos(String, boolean)}.
|
||||
* Calling this method may speed up subsequent calls to {@link #getDecoderInfo(String, 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
|
||||
|
|
@ -115,26 +114,14 @@ public final class MediaCodecUtil {
|
|||
* @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, boolean tunneling)
|
||||
public static MediaCodecInfo getDecoderInfo(String mimeType, boolean secure)
|
||||
throws DecoderQueryException {
|
||||
List<MediaCodecInfo> decoderInfos = getDecoderInfos(mimeType, secure);
|
||||
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);
|
||||
}
|
||||
return decoderInfos.isEmpty() ? null : decoderInfos.get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -305,7 +292,7 @@ public final class MediaCodecUtil {
|
|||
public static int maxH264DecodableFrameSize() throws DecoderQueryException {
|
||||
if (maxH264DecodableFrameSize == -1) {
|
||||
int result = 0;
|
||||
MediaCodecInfo decoderInfo = getDecoderInfo(MimeTypes.VIDEO_H264, false, false);
|
||||
MediaCodecInfo decoderInfo = getDecoderInfo(MimeTypes.VIDEO_H264, false);
|
||||
if (decoderInfo != null) {
|
||||
for (CodecProfileLevel profileLevel : decoderInfo.getProfileLevels()) {
|
||||
result = Math.max(avcLevelToMaxFrameSize(profileLevel.level), result);
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
|
|||
}
|
||||
}
|
||||
MediaCodecInfo decoderInfo = mediaCodecSelector.getDecoderInfo(mimeType,
|
||||
requiresSecureDecryption, false);
|
||||
requiresSecureDecryption);
|
||||
if (decoderInfo == null) {
|
||||
return FORMAT_UNSUPPORTED_SUBTYPE;
|
||||
}
|
||||
|
|
@ -196,8 +196,9 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
|
|||
}
|
||||
|
||||
int adaptiveSupport = decoderInfo.adaptive ? ADAPTIVE_SEAMLESS : ADAPTIVE_NOT_SEAMLESS;
|
||||
int tunnelingSupport = decoderInfo.tunneling ? TUNNELING_SUPPORTED : TUNNELING_NOT_SUPPORTED;
|
||||
int formatSupport = decoderCapable ? FORMAT_HANDLED : FORMAT_EXCEEDS_CAPABILITIES;
|
||||
return adaptiveSupport | formatSupport;
|
||||
return adaptiveSupport | tunnelingSupport | formatSupport;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -634,7 +634,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||
}
|
||||
|
||||
private static boolean shouldSkipAdaptiveTest(String mimeType) throws DecoderQueryException {
|
||||
MediaCodecInfo decoderInfo = MediaCodecUtil.getDecoderInfo(mimeType, false, false);
|
||||
MediaCodecInfo decoderInfo = MediaCodecUtil.getDecoderInfo(mimeType, false);
|
||||
assertNotNull(decoderInfo);
|
||||
if (decoderInfo.adaptive) {
|
||||
return false;
|
||||
|
|
@ -707,8 +707,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||
if (isWidevineEncrypted) {
|
||||
try {
|
||||
// Force L3 if secure decoder is not available.
|
||||
boolean forceL3Widevine =
|
||||
MediaCodecUtil.getDecoderInfo(videoMimeType, true, false) == null;
|
||||
boolean forceL3Widevine = MediaCodecUtil.getDecoderInfo(videoMimeType, true) == null;
|
||||
MediaDrm mediaDrm = new MediaDrm(WIDEVINE_UUID);
|
||||
String securityProperty = mediaDrm.getPropertyString(SECURITY_LEVEL_PROPERTY);
|
||||
String widevineContentId = forceL3Widevine ? WIDEVINE_SW_CRYPTO_CONTENT_ID
|
||||
|
|
|
|||
Loading…
Reference in a new issue