Commit e97b8347 by tonihei Committed by Oliver Woodman

Add IntDefs for renderer capabilities.

This simplifies documentation and adds compiler checks that the correct values
are used.

PiperOrigin-RevId: 283754163
parent 7d7c37b3
Showing with 397 additions and 209 deletions
...@@ -25,6 +25,7 @@ import com.google.android.exoplayer2.ExoPlaybackException; ...@@ -25,6 +25,7 @@ import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.PlayerMessage.Target; import com.google.android.exoplayer2.PlayerMessage.Target;
import com.google.android.exoplayer2.RendererCapabilities;
import com.google.android.exoplayer2.decoder.SimpleDecoder; import com.google.android.exoplayer2.decoder.SimpleDecoder;
import com.google.android.exoplayer2.drm.DrmSessionManager; import com.google.android.exoplayer2.drm.DrmSessionManager;
import com.google.android.exoplayer2.drm.ExoMediaCrypto; import com.google.android.exoplayer2.drm.ExoMediaCrypto;
...@@ -133,16 +134,17 @@ public class Libgav1VideoRenderer extends SimpleDecoderVideoRenderer { ...@@ -133,16 +134,17 @@ public class Libgav1VideoRenderer extends SimpleDecoderVideoRenderer {
} }
@Override @Override
@Capabilities
protected int supportsFormatInternal( protected int supportsFormatInternal(
@Nullable DrmSessionManager<ExoMediaCrypto> drmSessionManager, Format format) { @Nullable DrmSessionManager<ExoMediaCrypto> drmSessionManager, Format format) {
if (!MimeTypes.VIDEO_AV1.equalsIgnoreCase(format.sampleMimeType) if (!MimeTypes.VIDEO_AV1.equalsIgnoreCase(format.sampleMimeType)
|| !Gav1Library.isAvailable()) { || !Gav1Library.isAvailable()) {
return FORMAT_UNSUPPORTED_TYPE; return RendererCapabilities.create(FORMAT_UNSUPPORTED_TYPE);
} }
if (!supportsFormatDrm(drmSessionManager, format.drmInitData)) { if (!supportsFormatDrm(drmSessionManager, format.drmInitData)) {
return FORMAT_UNSUPPORTED_DRM; return RendererCapabilities.create(FORMAT_UNSUPPORTED_DRM);
} }
return FORMAT_HANDLED | ADAPTIVE_SEAMLESS; return RendererCapabilities.create(FORMAT_HANDLED, ADAPTIVE_SEAMLESS, TUNNELING_NOT_SUPPORTED);
} }
@Override @Override
......
...@@ -92,6 +92,7 @@ public final class FfmpegAudioRenderer extends SimpleDecoderAudioRenderer { ...@@ -92,6 +92,7 @@ public final class FfmpegAudioRenderer extends SimpleDecoderAudioRenderer {
} }
@Override @Override
@FormatSupport
protected int supportsFormatInternal( protected int supportsFormatInternal(
@Nullable DrmSessionManager<ExoMediaCrypto> drmSessionManager, Format format) { @Nullable DrmSessionManager<ExoMediaCrypto> drmSessionManager, Format format) {
Assertions.checkNotNull(format.sampleMimeType); Assertions.checkNotNull(format.sampleMimeType);
...@@ -108,6 +109,7 @@ public final class FfmpegAudioRenderer extends SimpleDecoderAudioRenderer { ...@@ -108,6 +109,7 @@ public final class FfmpegAudioRenderer extends SimpleDecoderAudioRenderer {
} }
@Override @Override
@AdaptiveSupport
public final int supportsMixedMimeTypeAdaptation() throws ExoPlaybackException { public final int supportsMixedMimeTypeAdaptation() throws ExoPlaybackException {
return ADAPTIVE_NOT_SEAMLESS; return ADAPTIVE_NOT_SEAMLESS;
} }
......
...@@ -51,6 +51,7 @@ public class LibflacAudioRenderer extends SimpleDecoderAudioRenderer { ...@@ -51,6 +51,7 @@ public class LibflacAudioRenderer extends SimpleDecoderAudioRenderer {
} }
@Override @Override
@FormatSupport
protected int supportsFormatInternal( protected int supportsFormatInternal(
@Nullable DrmSessionManager<ExoMediaCrypto> drmSessionManager, Format format) { @Nullable DrmSessionManager<ExoMediaCrypto> drmSessionManager, Format format) {
if (!FlacLibrary.isAvailable() if (!FlacLibrary.isAvailable()
......
...@@ -83,6 +83,7 @@ public class LibopusAudioRenderer extends SimpleDecoderAudioRenderer { ...@@ -83,6 +83,7 @@ public class LibopusAudioRenderer extends SimpleDecoderAudioRenderer {
} }
@Override @Override
@FormatSupport
protected int supportsFormatInternal( protected int supportsFormatInternal(
@Nullable DrmSessionManager<ExoMediaCrypto> drmSessionManager, Format format) { @Nullable DrmSessionManager<ExoMediaCrypto> drmSessionManager, Format format) {
boolean drmIsSupported = boolean drmIsSupported =
......
...@@ -25,6 +25,7 @@ import com.google.android.exoplayer2.ExoPlaybackException; ...@@ -25,6 +25,7 @@ import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.PlayerMessage.Target; import com.google.android.exoplayer2.PlayerMessage.Target;
import com.google.android.exoplayer2.RendererCapabilities;
import com.google.android.exoplayer2.decoder.SimpleDecoder; import com.google.android.exoplayer2.decoder.SimpleDecoder;
import com.google.android.exoplayer2.drm.DrmSessionManager; import com.google.android.exoplayer2.drm.DrmSessionManager;
import com.google.android.exoplayer2.drm.ExoMediaCrypto; import com.google.android.exoplayer2.drm.ExoMediaCrypto;
...@@ -223,10 +224,11 @@ public class LibvpxVideoRenderer extends SimpleDecoderVideoRenderer { ...@@ -223,10 +224,11 @@ public class LibvpxVideoRenderer extends SimpleDecoderVideoRenderer {
} }
@Override @Override
@Capabilities
protected int supportsFormatInternal( protected int supportsFormatInternal(
@Nullable DrmSessionManager<ExoMediaCrypto> drmSessionManager, Format format) { @Nullable DrmSessionManager<ExoMediaCrypto> drmSessionManager, Format format) {
if (!VpxLibrary.isAvailable() || !MimeTypes.VIDEO_VP9.equalsIgnoreCase(format.sampleMimeType)) { if (!VpxLibrary.isAvailable() || !MimeTypes.VIDEO_VP9.equalsIgnoreCase(format.sampleMimeType)) {
return FORMAT_UNSUPPORTED_TYPE; return RendererCapabilities.create(FORMAT_UNSUPPORTED_TYPE);
} }
boolean drmIsSupported = boolean drmIsSupported =
format.drmInitData == null format.drmInitData == null
...@@ -234,9 +236,9 @@ public class LibvpxVideoRenderer extends SimpleDecoderVideoRenderer { ...@@ -234,9 +236,9 @@ public class LibvpxVideoRenderer extends SimpleDecoderVideoRenderer {
|| (format.exoMediaCryptoType == null || (format.exoMediaCryptoType == null
&& supportsFormatDrm(drmSessionManager, format.drmInitData)); && supportsFormatDrm(drmSessionManager, format.drmInitData));
if (!drmIsSupported) { if (!drmIsSupported) {
return FORMAT_UNSUPPORTED_DRM; return RendererCapabilities.create(FORMAT_UNSUPPORTED_DRM);
} }
return FORMAT_HANDLED | ADAPTIVE_SEAMLESS; return RendererCapabilities.create(FORMAT_HANDLED, ADAPTIVE_SEAMLESS, TUNNELING_NOT_SUPPORTED);
} }
@Override @Override
......
...@@ -16,7 +16,7 @@ apply from: '../../constants.gradle' ...@@ -16,7 +16,7 @@ apply from: '../../constants.gradle'
android { android {
compileSdkVersion project.ext.compileSdkVersion compileSdkVersion project.ext.compileSdkVersion
compileOptions { compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8
......
...@@ -177,6 +177,7 @@ public abstract class BaseRenderer implements Renderer, RendererCapabilities { ...@@ -177,6 +177,7 @@ public abstract class BaseRenderer implements Renderer, RendererCapabilities {
// RendererCapabilities implementation. // RendererCapabilities implementation.
@Override @Override
@AdaptiveSupport
public int supportsMixedMimeTypeAdaptation() throws ExoPlaybackException { public int supportsMixedMimeTypeAdaptation() throws ExoPlaybackException {
return ADAPTIVE_NOT_SUPPORTED; return ADAPTIVE_NOT_SUPPORTED;
} }
......
...@@ -185,11 +185,13 @@ public abstract class NoSampleRenderer implements Renderer, RendererCapabilities ...@@ -185,11 +185,13 @@ public abstract class NoSampleRenderer implements Renderer, RendererCapabilities
// RendererCapabilities implementation. // RendererCapabilities implementation.
@Override @Override
@Capabilities
public int supportsFormat(Format format) throws ExoPlaybackException { public int supportsFormat(Format format) throws ExoPlaybackException {
return FORMAT_UNSUPPORTED_TYPE; return RendererCapabilities.create(FORMAT_UNSUPPORTED_TYPE);
} }
@Override @Override
@AdaptiveSupport
public int supportsMixedMimeTypeAdaptation() throws ExoPlaybackException { public int supportsMixedMimeTypeAdaptation() throws ExoPlaybackException {
return ADAPTIVE_NOT_SUPPORTED; return ADAPTIVE_NOT_SUPPORTED;
} }
......
...@@ -15,7 +15,12 @@ ...@@ -15,7 +15,12 @@
*/ */
package com.google.android.exoplayer2; package com.google.android.exoplayer2;
import android.annotation.SuppressLint;
import androidx.annotation.IntDef;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/** /**
* Defines the capabilities of a {@link Renderer}. * Defines the capabilities of a {@link Renderer}.
...@@ -23,10 +28,22 @@ import com.google.android.exoplayer2.util.MimeTypes; ...@@ -23,10 +28,22 @@ import com.google.android.exoplayer2.util.MimeTypes;
public interface RendererCapabilities { public interface RendererCapabilities {
/** /**
* A mask to apply to the result of {@link #supportsFormat(Format)} to obtain one of * Level of renderer support for a format. One of {@link #FORMAT_HANDLED}, {@link
* {@link #FORMAT_HANDLED}, {@link #FORMAT_EXCEEDS_CAPABILITIES}, {@link #FORMAT_UNSUPPORTED_DRM}, * #FORMAT_EXCEEDS_CAPABILITIES}, {@link #FORMAT_UNSUPPORTED_DRM}, {@link
* {@link #FORMAT_UNSUPPORTED_SUBTYPE} and {@link #FORMAT_UNSUPPORTED_TYPE}. * #FORMAT_UNSUPPORTED_SUBTYPE} or {@link #FORMAT_UNSUPPORTED_TYPE}.
*/ */
@Documented
@Retention(RetentionPolicy.SOURCE)
@IntDef({
FORMAT_HANDLED,
FORMAT_EXCEEDS_CAPABILITIES,
FORMAT_UNSUPPORTED_DRM,
FORMAT_UNSUPPORTED_SUBTYPE,
FORMAT_UNSUPPORTED_TYPE
})
@interface FormatSupport {}
/** A mask to apply to {@link Capabilities} to obtain the {@link FormatSupport} only. */
int FORMAT_SUPPORT_MASK = 0b111; int FORMAT_SUPPORT_MASK = 0b111;
/** /**
* The {@link Renderer} is capable of rendering the format. * The {@link Renderer} is capable of rendering the format.
...@@ -72,9 +89,15 @@ public interface RendererCapabilities { ...@@ -72,9 +89,15 @@ public interface RendererCapabilities {
int FORMAT_UNSUPPORTED_TYPE = 0b000; int FORMAT_UNSUPPORTED_TYPE = 0b000;
/** /**
* A mask to apply to the result of {@link #supportsFormat(Format)} to obtain one of * Level of renderer support for adaptive format switches. One of {@link #ADAPTIVE_SEAMLESS},
* {@link #ADAPTIVE_SEAMLESS}, {@link #ADAPTIVE_NOT_SEAMLESS} and {@link #ADAPTIVE_NOT_SUPPORTED}. * {@link #ADAPTIVE_NOT_SEAMLESS} or {@link #ADAPTIVE_NOT_SUPPORTED}.
*/ */
@Documented
@Retention(RetentionPolicy.SOURCE)
@IntDef({ADAPTIVE_SEAMLESS, ADAPTIVE_NOT_SEAMLESS, ADAPTIVE_NOT_SUPPORTED})
@interface AdaptiveSupport {}
/** A mask to apply to {@link Capabilities} to obtain the {@link AdaptiveSupport} only. */
int ADAPTIVE_SUPPORT_MASK = 0b11000; int ADAPTIVE_SUPPORT_MASK = 0b11000;
/** /**
* The {@link Renderer} can seamlessly adapt between formats. * The {@link Renderer} can seamlessly adapt between formats.
...@@ -91,9 +114,15 @@ public interface RendererCapabilities { ...@@ -91,9 +114,15 @@ public interface RendererCapabilities {
int ADAPTIVE_NOT_SUPPORTED = 0b00000; int ADAPTIVE_NOT_SUPPORTED = 0b00000;
/** /**
* A mask to apply to the result of {@link #supportsFormat(Format)} to obtain one of * Level of renderer support for tunneling. One of {@link #TUNNELING_SUPPORTED} or {@link
* {@link #TUNNELING_SUPPORTED} and {@link #TUNNELING_NOT_SUPPORTED}. * #TUNNELING_NOT_SUPPORTED}.
*/ */
@Documented
@Retention(RetentionPolicy.SOURCE)
@IntDef({TUNNELING_SUPPORTED, TUNNELING_NOT_SUPPORTED})
@interface TunnelingSupport {}
/** A mask to apply to {@link Capabilities} to obtain the {@link TunnelingSupport} only. */
int TUNNELING_SUPPORT_MASK = 0b100000; int TUNNELING_SUPPORT_MASK = 0b100000;
/** /**
* The {@link Renderer} supports tunneled output. * The {@link Renderer} supports tunneled output.
...@@ -105,6 +134,110 @@ public interface RendererCapabilities { ...@@ -105,6 +134,110 @@ public interface RendererCapabilities {
int TUNNELING_NOT_SUPPORTED = 0b000000; int TUNNELING_NOT_SUPPORTED = 0b000000;
/** /**
* Combined renderer capabilities.
*
* <p>This is a bitwise OR of {@link FormatSupport}, {@link AdaptiveSupport} and {@link
* TunnelingSupport}. Use {@link #getFormatSupport(int)}, {@link #getAdaptiveSupport(int)} or
* {@link #getTunnelingSupport(int)} to obtain the individual flags. And use {@link #create(int)}
* or {@link #create(int, int, int)} to create the combined capabilities.
*
* <p>Possible values:
*
* <ul>
* <li>{@link FormatSupport}: The level of support for the format itself. One of {@link
* #FORMAT_HANDLED}, {@link #FORMAT_EXCEEDS_CAPABILITIES}, {@link #FORMAT_UNSUPPORTED_DRM},
* {@link #FORMAT_UNSUPPORTED_SUBTYPE} and {@link #FORMAT_UNSUPPORTED_TYPE}.
* <li>{@link AdaptiveSupport}: 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}. Only set if the level of
* support for the format itself is {@link #FORMAT_HANDLED} or {@link
* #FORMAT_EXCEEDS_CAPABILITIES}.
* <li>{@link TunnelingSupport}: The level of support for tunneling. One of {@link
* #TUNNELING_SUPPORTED} and {@link #TUNNELING_NOT_SUPPORTED}. Only set if the level of
* support for the format itself is {@link #FORMAT_HANDLED} or {@link
* #FORMAT_EXCEEDS_CAPABILITIES}.
* </ul>
*/
@Documented
@Retention(RetentionPolicy.SOURCE)
// Intentionally empty to prevent assignment or comparison with individual flags without masking.
@IntDef({})
@interface Capabilities {}
/**
* Returns {@link Capabilities} for the given {@link FormatSupport}.
*
* <p>The {@link AdaptiveSupport} is set to {@link #ADAPTIVE_NOT_SUPPORTED} and {{@link
* TunnelingSupport} is set to {@link #TUNNELING_NOT_SUPPORTED}.
*
* @param formatSupport The {@link FormatSupport}.
* @return The combined {@link Capabilities} of the given {@link FormatSupport}, {@link
* #ADAPTIVE_NOT_SUPPORTED} and {@link #TUNNELING_NOT_SUPPORTED}.
*/
@Capabilities
static int create(@FormatSupport int formatSupport) {
return create(formatSupport, ADAPTIVE_NOT_SUPPORTED, TUNNELING_NOT_SUPPORTED);
}
/**
* Returns {@link Capabilities} combining the given {@link FormatSupport}, {@link AdaptiveSupport}
* and {@link TunnelingSupport}.
*
* @param formatSupport The {@link FormatSupport}.
* @param adaptiveSupport The {@link AdaptiveSupport}.
* @param tunnelingSupport The {@link TunnelingSupport}.
* @return The combined {@link Capabilities}.
*/
// Suppression needed for IntDef casting.
@SuppressLint("WrongConstant")
@Capabilities
static int create(
@FormatSupport int formatSupport,
@AdaptiveSupport int adaptiveSupport,
@TunnelingSupport int tunnelingSupport) {
return formatSupport | adaptiveSupport | tunnelingSupport;
}
/**
* Returns the {@link FormatSupport} from the combined {@link Capabilities}.
*
* @param supportFlags The combined {@link Capabilities}.
* @return The {@link FormatSupport} only.
*/
// Suppression needed for IntDef casting.
@SuppressLint("WrongConstant")
@FormatSupport
static int getFormatSupport(@Capabilities int supportFlags) {
return supportFlags & FORMAT_SUPPORT_MASK;
}
/**
* Returns the {@link AdaptiveSupport} from the combined {@link Capabilities}.
*
* @param supportFlags The combined {@link Capabilities}.
* @return The {@link AdaptiveSupport} only.
*/
// Suppression needed for IntDef casting.
@SuppressLint("WrongConstant")
@AdaptiveSupport
static int getAdaptiveSupport(@Capabilities int supportFlags) {
return supportFlags & ADAPTIVE_SUPPORT_MASK;
}
/**
* Returns the {@link TunnelingSupport} from the combined {@link Capabilities}.
*
* @param supportFlags The combined {@link Capabilities}.
* @return The {@link TunnelingSupport} only.
*/
// Suppression needed for IntDef casting.
@SuppressLint("WrongConstant")
@TunnelingSupport
static int getTunnelingSupport(@Capabilities int supportFlags) {
return supportFlags & TUNNELING_SUPPORT_MASK;
}
/**
* Returns the track type that the {@link Renderer} handles. For example, a video renderer will * 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 * return {@link C#TRACK_TYPE_VIDEO}, an audio renderer will return {@link C#TRACK_TYPE_AUDIO}, a
* text renderer will return {@link C#TRACK_TYPE_TEXT}, and so on. * text renderer will return {@link C#TRACK_TYPE_TEXT}, and so on.
...@@ -115,39 +248,23 @@ public interface RendererCapabilities { ...@@ -115,39 +248,23 @@ public interface RendererCapabilities {
int getTrackType(); int getTrackType();
/** /**
* Returns the extent to which the {@link Renderer} supports a given format. The returned value is * Returns the extent to which the {@link Renderer} supports a given format.
* 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_DRM},
* {@link #FORMAT_UNSUPPORTED_SUBTYPE} and {@link #FORMAT_UNSUPPORTED_TYPE}.</li>
* <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}. Only set if the level of support for the format itself is
* {@link #FORMAT_HANDLED} or {@link #FORMAT_EXCEEDS_CAPABILITIES}.</li>
* <li>The level of support for tunneling. One of {@link #TUNNELING_SUPPORTED} and
* {@link #TUNNELING_NOT_SUPPORTED}. Only set if the level of support for the format itself is
* {@link #FORMAT_HANDLED} or {@link #FORMAT_EXCEEDS_CAPABILITIES}.</li>
* </ul>
* The individual properties can be retrieved by performing a bitwise AND with
* {@link #FORMAT_SUPPORT_MASK}, {@link #ADAPTIVE_SUPPORT_MASK} and
* {@link #TUNNELING_SUPPORT_MASK} respectively.
* *
* @param format The format. * @param format The format.
* @return The extent to which the renderer is capable of supporting the given format. * @return The {@link Capabilities} for this format.
* @throws ExoPlaybackException If an error occurs. * @throws ExoPlaybackException If an error occurs.
*/ */
@Capabilities
int supportsFormat(Format format) throws ExoPlaybackException; int supportsFormat(Format format) throws ExoPlaybackException;
/** /**
* Returns the extent to which the {@link Renderer} supports adapting between supported formats * Returns the extent to which the {@link Renderer} supports adapting between supported formats
* that have different mime types. * that have different MIME types.
* *
* @return The extent to which the renderer supports adapting between supported formats that have * @return The {@link AdaptiveSupport} for adapting between supported formats that have different
* different mime types. One of {@link #ADAPTIVE_SEAMLESS}, {@link #ADAPTIVE_NOT_SEAMLESS} and * MIME types.
* {@link #ADAPTIVE_NOT_SUPPORTED}.
* @throws ExoPlaybackException If an error occurs. * @throws ExoPlaybackException If an error occurs.
*/ */
@AdaptiveSupport
int supportsMixedMimeTypeAdaptation() throws ExoPlaybackException; int supportsMixedMimeTypeAdaptation() throws ExoPlaybackException;
} }
...@@ -31,6 +31,7 @@ import com.google.android.exoplayer2.Format; ...@@ -31,6 +31,7 @@ import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.FormatHolder; import com.google.android.exoplayer2.FormatHolder;
import com.google.android.exoplayer2.PlaybackParameters; import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.PlayerMessage.Target; import com.google.android.exoplayer2.PlayerMessage.Target;
import com.google.android.exoplayer2.RendererCapabilities;
import com.google.android.exoplayer2.audio.AudioRendererEventListener.EventDispatcher; import com.google.android.exoplayer2.audio.AudioRendererEventListener.EventDispatcher;
import com.google.android.exoplayer2.decoder.DecoderInputBuffer; import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
import com.google.android.exoplayer2.drm.DrmSessionManager; import com.google.android.exoplayer2.drm.DrmSessionManager;
...@@ -358,6 +359,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media ...@@ -358,6 +359,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
} }
@Override @Override
@Capabilities
protected int supportsFormat( protected int supportsFormat(
MediaCodecSelector mediaCodecSelector, MediaCodecSelector mediaCodecSelector,
@Nullable DrmSessionManager<FrameworkMediaCrypto> drmSessionManager, @Nullable DrmSessionManager<FrameworkMediaCrypto> drmSessionManager,
...@@ -365,8 +367,9 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media ...@@ -365,8 +367,9 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
throws DecoderQueryException { throws DecoderQueryException {
String mimeType = format.sampleMimeType; String mimeType = format.sampleMimeType;
if (!MimeTypes.isAudio(mimeType)) { if (!MimeTypes.isAudio(mimeType)) {
return FORMAT_UNSUPPORTED_TYPE; return RendererCapabilities.create(FORMAT_UNSUPPORTED_TYPE);
} }
@TunnelingSupport
int tunnelingSupport = Util.SDK_INT >= 21 ? TUNNELING_SUPPORTED : TUNNELING_NOT_SUPPORTED; int tunnelingSupport = Util.SDK_INT >= 21 ? TUNNELING_SUPPORTED : TUNNELING_NOT_SUPPORTED;
boolean supportsFormatDrm = boolean supportsFormatDrm =
format.drmInitData == null format.drmInitData == null
...@@ -376,31 +379,33 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media ...@@ -376,31 +379,33 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
if (supportsFormatDrm if (supportsFormatDrm
&& allowPassthrough(format.channelCount, mimeType) && allowPassthrough(format.channelCount, mimeType)
&& mediaCodecSelector.getPassthroughDecoderInfo() != null) { && mediaCodecSelector.getPassthroughDecoderInfo() != null) {
return ADAPTIVE_NOT_SEAMLESS | tunnelingSupport | FORMAT_HANDLED; return RendererCapabilities.create(FORMAT_HANDLED, ADAPTIVE_NOT_SEAMLESS, tunnelingSupport);
} }
if ((MimeTypes.AUDIO_RAW.equals(mimeType) if ((MimeTypes.AUDIO_RAW.equals(mimeType)
&& !audioSink.supportsOutput(format.channelCount, format.pcmEncoding)) && !audioSink.supportsOutput(format.channelCount, format.pcmEncoding))
|| !audioSink.supportsOutput(format.channelCount, C.ENCODING_PCM_16BIT)) { || !audioSink.supportsOutput(format.channelCount, C.ENCODING_PCM_16BIT)) {
// Assume the decoder outputs 16-bit PCM, unless the input is raw. // Assume the decoder outputs 16-bit PCM, unless the input is raw.
return FORMAT_UNSUPPORTED_SUBTYPE; return RendererCapabilities.create(FORMAT_UNSUPPORTED_SUBTYPE);
} }
List<MediaCodecInfo> decoderInfos = List<MediaCodecInfo> decoderInfos =
getDecoderInfos(mediaCodecSelector, format, /* requiresSecureDecoder= */ false); getDecoderInfos(mediaCodecSelector, format, /* requiresSecureDecoder= */ false);
if (decoderInfos.isEmpty()) { if (decoderInfos.isEmpty()) {
return FORMAT_UNSUPPORTED_SUBTYPE; return RendererCapabilities.create(FORMAT_UNSUPPORTED_SUBTYPE);
} }
if (!supportsFormatDrm) { if (!supportsFormatDrm) {
return FORMAT_UNSUPPORTED_DRM; return RendererCapabilities.create(FORMAT_UNSUPPORTED_DRM);
} }
// Check capabilities for the first decoder in the list, which takes priority. // Check capabilities for the first decoder in the list, which takes priority.
MediaCodecInfo decoderInfo = decoderInfos.get(0); MediaCodecInfo decoderInfo = decoderInfos.get(0);
boolean isFormatSupported = decoderInfo.isFormatSupported(format); boolean isFormatSupported = decoderInfo.isFormatSupported(format);
@AdaptiveSupport
int adaptiveSupport = int adaptiveSupport =
isFormatSupported && decoderInfo.isSeamlessAdaptationSupported(format) isFormatSupported && decoderInfo.isSeamlessAdaptationSupported(format)
? ADAPTIVE_SEAMLESS ? ADAPTIVE_SEAMLESS
: ADAPTIVE_NOT_SEAMLESS; : ADAPTIVE_NOT_SEAMLESS;
@FormatSupport
int formatSupport = isFormatSupported ? FORMAT_HANDLED : FORMAT_EXCEEDS_CAPABILITIES; int formatSupport = isFormatSupported ? FORMAT_HANDLED : FORMAT_EXCEEDS_CAPABILITIES;
return adaptiveSupport | tunnelingSupport | formatSupport; return RendererCapabilities.create(formatSupport, adaptiveSupport, tunnelingSupport);
} }
@Override @Override
......
...@@ -28,6 +28,7 @@ import com.google.android.exoplayer2.Format; ...@@ -28,6 +28,7 @@ import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.FormatHolder; import com.google.android.exoplayer2.FormatHolder;
import com.google.android.exoplayer2.PlaybackParameters; import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.PlayerMessage.Target; import com.google.android.exoplayer2.PlayerMessage.Target;
import com.google.android.exoplayer2.RendererCapabilities;
import com.google.android.exoplayer2.audio.AudioRendererEventListener.EventDispatcher; import com.google.android.exoplayer2.audio.AudioRendererEventListener.EventDispatcher;
import com.google.android.exoplayer2.decoder.DecoderCounters; import com.google.android.exoplayer2.decoder.DecoderCounters;
import com.google.android.exoplayer2.decoder.DecoderInputBuffer; import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
...@@ -222,26 +223,28 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements ...@@ -222,26 +223,28 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements
} }
@Override @Override
@Capabilities
public final int supportsFormat(Format format) { public final int supportsFormat(Format format) {
if (!MimeTypes.isAudio(format.sampleMimeType)) { if (!MimeTypes.isAudio(format.sampleMimeType)) {
return FORMAT_UNSUPPORTED_TYPE; return RendererCapabilities.create(FORMAT_UNSUPPORTED_TYPE);
} }
int formatSupport = supportsFormatInternal(drmSessionManager, format); @FormatSupport int formatSupport = supportsFormatInternal(drmSessionManager, format);
if (formatSupport <= FORMAT_UNSUPPORTED_DRM) { if (formatSupport <= FORMAT_UNSUPPORTED_DRM) {
return formatSupport; return RendererCapabilities.create(formatSupport);
} }
@TunnelingSupport
int tunnelingSupport = Util.SDK_INT >= 21 ? TUNNELING_SUPPORTED : TUNNELING_NOT_SUPPORTED; int tunnelingSupport = Util.SDK_INT >= 21 ? TUNNELING_SUPPORTED : TUNNELING_NOT_SUPPORTED;
return ADAPTIVE_NOT_SEAMLESS | tunnelingSupport | formatSupport; return RendererCapabilities.create(formatSupport, ADAPTIVE_NOT_SEAMLESS, tunnelingSupport);
} }
/** /**
* Returns the {@link #FORMAT_SUPPORT_MASK} component of the return value for {@link * Returns the {@link FormatSupport} for the given {@link Format}.
* #supportsFormat(Format)}.
* *
* @param drmSessionManager The renderer's {@link DrmSessionManager}. * @param drmSessionManager The renderer's {@link DrmSessionManager}.
* @param format The format, which has an audio {@link Format#sampleMimeType}. * @param format The format, which has an audio {@link Format#sampleMimeType}.
* @return The extent to which the renderer supports the format itself. * @return The {@link FormatSupport} for this {@link Format}.
*/ */
@FormatSupport
protected abstract int supportsFormatInternal( protected abstract int supportsFormatInternal(
@Nullable DrmSessionManager<ExoMediaCrypto> drmSessionManager, Format format); @Nullable DrmSessionManager<ExoMediaCrypto> drmSessionManager, Format format);
......
...@@ -452,11 +452,13 @@ public abstract class MediaCodecRenderer extends BaseRenderer { ...@@ -452,11 +452,13 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
} }
@Override @Override
@AdaptiveSupport
public final int supportsMixedMimeTypeAdaptation() { public final int supportsMixedMimeTypeAdaptation() {
return ADAPTIVE_NOT_SEAMLESS; return ADAPTIVE_NOT_SEAMLESS;
} }
@Override @Override
@Capabilities
public final int supportsFormat(Format format) throws ExoPlaybackException { public final int supportsFormat(Format format) throws ExoPlaybackException {
try { try {
return supportsFormat(mediaCodecSelector, drmSessionManager, format); return supportsFormat(mediaCodecSelector, drmSessionManager, format);
...@@ -466,15 +468,15 @@ public abstract class MediaCodecRenderer extends BaseRenderer { ...@@ -466,15 +468,15 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
} }
/** /**
* Returns the extent to which the renderer is capable of supporting a given {@link Format}. * Returns the {@link Capabilities} for the given {@link Format}.
* *
* @param mediaCodecSelector The decoder selector. * @param mediaCodecSelector The decoder selector.
* @param drmSessionManager The renderer's {@link DrmSessionManager}. * @param drmSessionManager The renderer's {@link DrmSessionManager}.
* @param format The {@link Format}. * @param format The {@link Format}.
* @return The extent to which the renderer is capable of supporting the given format. See {@link * @return The {@link Capabilities} for this {@link Format}.
* #supportsFormat(Format)} for more detail.
* @throws DecoderQueryException If there was an error querying decoders. * @throws DecoderQueryException If there was an error querying decoders.
*/ */
@Capabilities
protected abstract int supportsFormat( protected abstract int supportsFormat(
MediaCodecSelector mediaCodecSelector, MediaCodecSelector mediaCodecSelector,
@Nullable DrmSessionManager<FrameworkMediaCrypto> drmSessionManager, @Nullable DrmSessionManager<FrameworkMediaCrypto> drmSessionManager,
......
...@@ -26,6 +26,7 @@ import com.google.android.exoplayer2.BaseRenderer; ...@@ -26,6 +26,7 @@ import com.google.android.exoplayer2.BaseRenderer;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.FormatHolder; import com.google.android.exoplayer2.FormatHolder;
import com.google.android.exoplayer2.RendererCapabilities;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import java.util.ArrayList; import java.util.ArrayList;
...@@ -91,11 +92,13 @@ public final class MetadataRenderer extends BaseRenderer implements Callback { ...@@ -91,11 +92,13 @@ public final class MetadataRenderer extends BaseRenderer implements Callback {
} }
@Override @Override
@Capabilities
public int supportsFormat(Format format) { public int supportsFormat(Format format) {
if (decoderFactory.supportsFormat(format)) { if (decoderFactory.supportsFormat(format)) {
return supportsFormatDrm(null, format.drmInitData) ? FORMAT_HANDLED : FORMAT_UNSUPPORTED_DRM; return RendererCapabilities.create(
supportsFormatDrm(null, format.drmInitData) ? FORMAT_HANDLED : FORMAT_UNSUPPORTED_DRM);
} else { } else {
return FORMAT_UNSUPPORTED_TYPE; return RendererCapabilities.create(FORMAT_UNSUPPORTED_TYPE);
} }
} }
......
...@@ -26,6 +26,7 @@ import com.google.android.exoplayer2.C; ...@@ -26,6 +26,7 @@ import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.FormatHolder; import com.google.android.exoplayer2.FormatHolder;
import com.google.android.exoplayer2.RendererCapabilities;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
...@@ -118,13 +119,15 @@ public final class TextRenderer extends BaseRenderer implements Callback { ...@@ -118,13 +119,15 @@ public final class TextRenderer extends BaseRenderer implements Callback {
} }
@Override @Override
@Capabilities
public int supportsFormat(Format format) { public int supportsFormat(Format format) {
if (decoderFactory.supportsFormat(format)) { if (decoderFactory.supportsFormat(format)) {
return supportsFormatDrm(null, format.drmInitData) ? FORMAT_HANDLED : FORMAT_UNSUPPORTED_DRM; return RendererCapabilities.create(
supportsFormatDrm(null, format.drmInitData) ? FORMAT_HANDLED : FORMAT_UNSUPPORTED_DRM);
} else if (MimeTypes.isText(format.sampleMimeType)) { } else if (MimeTypes.isText(format.sampleMimeType)) {
return FORMAT_UNSUPPORTED_SUBTYPE; return RendererCapabilities.create(FORMAT_UNSUPPORTED_SUBTYPE);
} else { } else {
return FORMAT_UNSUPPORTED_TYPE; return RendererCapabilities.create(FORMAT_UNSUPPORTED_TYPE);
} }
} }
......
...@@ -30,6 +30,9 @@ import com.google.android.exoplayer2.Format; ...@@ -30,6 +30,9 @@ import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.Player; import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.Renderer; import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.RendererCapabilities; import com.google.android.exoplayer2.RendererCapabilities;
import com.google.android.exoplayer2.RendererCapabilities.AdaptiveSupport;
import com.google.android.exoplayer2.RendererCapabilities.Capabilities;
import com.google.android.exoplayer2.RendererCapabilities.FormatSupport;
import com.google.android.exoplayer2.RendererConfiguration; import com.google.android.exoplayer2.RendererConfiguration;
import com.google.android.exoplayer2.source.TrackGroup; import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray; import com.google.android.exoplayer2.source.TrackGroupArray;
...@@ -1608,8 +1611,8 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1608,8 +1611,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
protected final Pair<@NullableType RendererConfiguration[], @NullableType TrackSelection[]> protected final Pair<@NullableType RendererConfiguration[], @NullableType TrackSelection[]>
selectTracks( selectTracks(
MappedTrackInfo mappedTrackInfo, MappedTrackInfo mappedTrackInfo,
int[][][] rendererFormatSupports, @Capabilities int[][][] rendererFormatSupports,
int[] rendererMixedMimeTypeAdaptationSupports) @AdaptiveSupport int[] rendererMixedMimeTypeAdaptationSupports)
throws ExoPlaybackException { throws ExoPlaybackException {
Parameters params = parametersReference.get(); Parameters params = parametersReference.get();
int rendererCount = mappedTrackInfo.getRendererCount(); int rendererCount = mappedTrackInfo.getRendererCount();
...@@ -1678,18 +1681,18 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1678,18 +1681,18 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* generated by this method will be overridden to account for these properties. * generated by this method will be overridden to account for these properties.
* *
* @param mappedTrackInfo Mapped track information. * @param mappedTrackInfo Mapped track information.
* @param rendererFormatSupports The result of {@link RendererCapabilities#supportsFormat} for * @param rendererFormatSupports The {@link Capabilities} for each mapped track, indexed by
* each mapped track, indexed by renderer, track group and track (in that order). * renderer, track group and track (in that order).
* @param rendererMixedMimeTypeAdaptationSupports The result of {@link * @param rendererMixedMimeTypeAdaptationSupports The {@link AdaptiveSupport} for mixed MIME type
* RendererCapabilities#supportsMixedMimeTypeAdaptation()} for each renderer. * adaptation for the renderer.
* @return The {@link TrackSelection.Definition}s for the renderers. A null entry indicates no * @return The {@link TrackSelection.Definition}s for the renderers. A null entry indicates no
* selection was made. * selection was made.
* @throws ExoPlaybackException If an error occurs while selecting the tracks. * @throws ExoPlaybackException If an error occurs while selecting the tracks.
*/ */
protected TrackSelection.@NullableType Definition[] selectAllTracks( protected TrackSelection.@NullableType Definition[] selectAllTracks(
MappedTrackInfo mappedTrackInfo, MappedTrackInfo mappedTrackInfo,
int[][][] rendererFormatSupports, @Capabilities int[][][] rendererFormatSupports,
int[] rendererMixedMimeTypeAdaptationSupports, @AdaptiveSupport int[] rendererMixedMimeTypeAdaptationSupports,
Parameters params) Parameters params)
throws ExoPlaybackException { throws ExoPlaybackException {
int rendererCount = mappedTrackInfo.getRendererCount(); int rendererCount = mappedTrackInfo.getRendererCount();
...@@ -1793,10 +1796,10 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1793,10 +1796,10 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* {@link TrackSelection} for a video renderer. * {@link TrackSelection} for a video renderer.
* *
* @param groups The {@link TrackGroupArray} mapped to the renderer. * @param groups The {@link TrackGroupArray} mapped to the renderer.
* @param formatSupports The result of {@link RendererCapabilities#supportsFormat} for each mapped * @param formatSupports The {@link Capabilities} for each mapped track, indexed by renderer,
* track, indexed by track group index and track index (in that order). * track group and track (in that order).
* @param mixedMimeTypeAdaptationSupports The result of {@link * @param mixedMimeTypeAdaptationSupports The {@link AdaptiveSupport} for mixed MIME type
* RendererCapabilities#supportsMixedMimeTypeAdaptation()} for the renderer. * adaptation for the renderer.
* @param params The selector's current constraint parameters. * @param params The selector's current constraint parameters.
* @param enableAdaptiveTrackSelection Whether adaptive track selection is allowed. * @param enableAdaptiveTrackSelection Whether adaptive track selection is allowed.
* @return The {@link TrackSelection.Definition} for the renderer, or null if no selection was * @return The {@link TrackSelection.Definition} for the renderer, or null if no selection was
...@@ -1806,8 +1809,8 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1806,8 +1809,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
@Nullable @Nullable
protected TrackSelection.Definition selectVideoTrack( protected TrackSelection.Definition selectVideoTrack(
TrackGroupArray groups, TrackGroupArray groups,
int[][] formatSupports, @Capabilities int[][] formatSupports,
int mixedMimeTypeAdaptationSupports, @AdaptiveSupport int mixedMimeTypeAdaptationSupports,
Parameters params, Parameters params,
boolean enableAdaptiveTrackSelection) boolean enableAdaptiveTrackSelection)
throws ExoPlaybackException { throws ExoPlaybackException {
...@@ -1827,8 +1830,8 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1827,8 +1830,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
@Nullable @Nullable
private static TrackSelection.Definition selectAdaptiveVideoTrack( private static TrackSelection.Definition selectAdaptiveVideoTrack(
TrackGroupArray groups, TrackGroupArray groups,
int[][] formatSupport, @Capabilities int[][] formatSupport,
int mixedMimeTypeAdaptationSupports, @AdaptiveSupport int mixedMimeTypeAdaptationSupports,
Parameters params) { Parameters params) {
int requiredAdaptiveSupport = int requiredAdaptiveSupport =
params.allowVideoNonSeamlessAdaptiveness params.allowVideoNonSeamlessAdaptiveness
...@@ -1861,7 +1864,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1861,7 +1864,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
private static int[] getAdaptiveVideoTracksForGroup( private static int[] getAdaptiveVideoTracksForGroup(
TrackGroup group, TrackGroup group,
int[] formatSupport, @Capabilities int[] formatSupport,
boolean allowMixedMimeTypes, boolean allowMixedMimeTypes,
int requiredAdaptiveSupport, int requiredAdaptiveSupport,
int maxVideoWidth, int maxVideoWidth,
...@@ -1926,7 +1929,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1926,7 +1929,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
private static int getAdaptiveVideoTrackCountForMimeType( private static int getAdaptiveVideoTrackCountForMimeType(
TrackGroup group, TrackGroup group,
int[] formatSupport, @Capabilities int[] formatSupport,
int requiredAdaptiveSupport, int requiredAdaptiveSupport,
@Nullable String mimeType, @Nullable String mimeType,
int maxVideoWidth, int maxVideoWidth,
...@@ -1954,7 +1957,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1954,7 +1957,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
private static void filterAdaptiveVideoTrackCountForMimeType( private static void filterAdaptiveVideoTrackCountForMimeType(
TrackGroup group, TrackGroup group,
int[] formatSupport, @Capabilities int[] formatSupport,
int requiredAdaptiveSupport, int requiredAdaptiveSupport,
@Nullable String mimeType, @Nullable String mimeType,
int maxVideoWidth, int maxVideoWidth,
...@@ -1981,7 +1984,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1981,7 +1984,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
private static boolean isSupportedAdaptiveVideoTrack( private static boolean isSupportedAdaptiveVideoTrack(
Format format, Format format,
@Nullable String mimeType, @Nullable String mimeType,
int formatSupport, @Capabilities int formatSupport,
int requiredAdaptiveSupport, int requiredAdaptiveSupport,
int maxVideoWidth, int maxVideoWidth,
int maxVideoHeight, int maxVideoHeight,
...@@ -1998,7 +2001,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1998,7 +2001,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
@Nullable @Nullable
private static TrackSelection.Definition selectFixedVideoTrack( private static TrackSelection.Definition selectFixedVideoTrack(
TrackGroupArray groups, int[][] formatSupports, Parameters params) { TrackGroupArray groups, @Capabilities int[][] formatSupports, Parameters params) {
TrackGroup selectedGroup = null; TrackGroup selectedGroup = null;
int selectedTrackIndex = 0; int selectedTrackIndex = 0;
int selectedTrackScore = 0; int selectedTrackScore = 0;
...@@ -2008,7 +2011,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2008,7 +2011,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
TrackGroup trackGroup = groups.get(groupIndex); TrackGroup trackGroup = groups.get(groupIndex);
List<Integer> selectedTrackIndices = getViewportFilteredTrackIndices(trackGroup, List<Integer> selectedTrackIndices = getViewportFilteredTrackIndices(trackGroup,
params.viewportWidth, params.viewportHeight, params.viewportOrientationMayChange); params.viewportWidth, params.viewportHeight, params.viewportOrientationMayChange);
int[] trackFormatSupport = formatSupports[groupIndex]; @Capabilities int[] trackFormatSupport = formatSupports[groupIndex];
for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) { for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
if (isSupported(trackFormatSupport[trackIndex], if (isSupported(trackFormatSupport[trackIndex],
params.exceedRendererCapabilitiesIfNecessary)) { params.exceedRendererCapabilitiesIfNecessary)) {
...@@ -2071,10 +2074,10 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2071,10 +2074,10 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* {@link TrackSelection} for an audio renderer. * {@link TrackSelection} for an audio renderer.
* *
* @param groups The {@link TrackGroupArray} mapped to the renderer. * @param groups The {@link TrackGroupArray} mapped to the renderer.
* @param formatSupports The result of {@link RendererCapabilities#supportsFormat} for each mapped * @param formatSupports The {@link Capabilities} for each mapped track, indexed by renderer,
* track, indexed by track group index and track index (in that order). * track group and track (in that order).
* @param mixedMimeTypeAdaptationSupports The result of {@link * @param mixedMimeTypeAdaptationSupports The {@link AdaptiveSupport} for mixed MIME type
* RendererCapabilities#supportsMixedMimeTypeAdaptation()} for the renderer. * adaptation for the renderer.
* @param params The selector's current constraint parameters. * @param params The selector's current constraint parameters.
* @param enableAdaptiveTrackSelection Whether adaptive track selection is allowed. * @param enableAdaptiveTrackSelection Whether adaptive track selection is allowed.
* @return The {@link TrackSelection.Definition} and corresponding {@link AudioTrackScore}, or * @return The {@link TrackSelection.Definition} and corresponding {@link AudioTrackScore}, or
...@@ -2085,8 +2088,8 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2085,8 +2088,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
@Nullable @Nullable
protected Pair<TrackSelection.Definition, AudioTrackScore> selectAudioTrack( protected Pair<TrackSelection.Definition, AudioTrackScore> selectAudioTrack(
TrackGroupArray groups, TrackGroupArray groups,
int[][] formatSupports, @Capabilities int[][] formatSupports,
int mixedMimeTypeAdaptationSupports, @AdaptiveSupport int mixedMimeTypeAdaptationSupports,
Parameters params, Parameters params,
boolean enableAdaptiveTrackSelection) boolean enableAdaptiveTrackSelection)
throws ExoPlaybackException { throws ExoPlaybackException {
...@@ -2095,7 +2098,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2095,7 +2098,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
AudioTrackScore selectedTrackScore = null; AudioTrackScore selectedTrackScore = null;
for (int groupIndex = 0; groupIndex < groups.length; groupIndex++) { for (int groupIndex = 0; groupIndex < groups.length; groupIndex++) {
TrackGroup trackGroup = groups.get(groupIndex); TrackGroup trackGroup = groups.get(groupIndex);
int[] trackFormatSupport = formatSupports[groupIndex]; @Capabilities int[] trackFormatSupport = formatSupports[groupIndex];
for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) { for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
if (isSupported(trackFormatSupport[trackIndex], if (isSupported(trackFormatSupport[trackIndex],
params.exceedRendererCapabilitiesIfNecessary)) { params.exceedRendererCapabilitiesIfNecessary)) {
...@@ -2148,7 +2151,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2148,7 +2151,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
private static int[] getAdaptiveAudioTracks( private static int[] getAdaptiveAudioTracks(
TrackGroup group, TrackGroup group,
int[] formatSupport, @Capabilities int[] formatSupport,
int maxAudioBitrate, int maxAudioBitrate,
boolean allowMixedMimeTypeAdaptiveness, boolean allowMixedMimeTypeAdaptiveness,
boolean allowMixedSampleRateAdaptiveness, boolean allowMixedSampleRateAdaptiveness,
...@@ -2202,7 +2205,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2202,7 +2205,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
private static int getAdaptiveAudioTrackCount( private static int getAdaptiveAudioTrackCount(
TrackGroup group, TrackGroup group,
int[] formatSupport, @Capabilities int[] formatSupport,
AudioConfigurationTuple configuration, AudioConfigurationTuple configuration,
int maxAudioBitrate, int maxAudioBitrate,
boolean allowMixedMimeTypeAdaptiveness, boolean allowMixedMimeTypeAdaptiveness,
...@@ -2226,7 +2229,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2226,7 +2229,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
private static boolean isSupportedAdaptiveAudioTrack( private static boolean isSupportedAdaptiveAudioTrack(
Format format, Format format,
int formatSupport, @Capabilities int formatSupport,
AudioConfigurationTuple configuration, AudioConfigurationTuple configuration,
int maxAudioBitrate, int maxAudioBitrate,
boolean allowMixedMimeTypeAdaptiveness, boolean allowMixedMimeTypeAdaptiveness,
...@@ -2252,8 +2255,8 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2252,8 +2255,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* {@link TrackSelection} for a text renderer. * {@link TrackSelection} for a text renderer.
* *
* @param groups The {@link TrackGroupArray} mapped to the renderer. * @param groups The {@link TrackGroupArray} mapped to the renderer.
* @param formatSupport The result of {@link RendererCapabilities#supportsFormat} for each mapped * @param formatSupport The {@link Capabilities} for each mapped track, indexed by renderer, track
* track, indexed by track group index and track index (in that order). * group and track (in that order).
* @param params The selector's current constraint parameters. * @param params The selector's current constraint parameters.
* @param selectedAudioLanguage The language of the selected audio track. May be null if the * @param selectedAudioLanguage The language of the selected audio track. May be null if the
* selected text track declares no language or no text track was selected. * selected text track declares no language or no text track was selected.
...@@ -2264,7 +2267,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2264,7 +2267,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
@Nullable @Nullable
protected Pair<TrackSelection.Definition, TextTrackScore> selectTextTrack( protected Pair<TrackSelection.Definition, TextTrackScore> selectTextTrack(
TrackGroupArray groups, TrackGroupArray groups,
int[][] formatSupport, @Capabilities int[][] formatSupport,
Parameters params, Parameters params,
@Nullable String selectedAudioLanguage) @Nullable String selectedAudioLanguage)
throws ExoPlaybackException { throws ExoPlaybackException {
...@@ -2273,7 +2276,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2273,7 +2276,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
TextTrackScore selectedTrackScore = null; TextTrackScore selectedTrackScore = null;
for (int groupIndex = 0; groupIndex < groups.length; groupIndex++) { for (int groupIndex = 0; groupIndex < groups.length; groupIndex++) {
TrackGroup trackGroup = groups.get(groupIndex); TrackGroup trackGroup = groups.get(groupIndex);
int[] trackFormatSupport = formatSupport[groupIndex]; @Capabilities int[] trackFormatSupport = formatSupport[groupIndex];
for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) { for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
if (isSupported(trackFormatSupport[trackIndex], if (isSupported(trackFormatSupport[trackIndex],
params.exceedRendererCapabilitiesIfNecessary)) { params.exceedRendererCapabilitiesIfNecessary)) {
...@@ -2305,22 +2308,22 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2305,22 +2308,22 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* *
* @param trackType The type of the renderer. * @param trackType The type of the renderer.
* @param groups The {@link TrackGroupArray} mapped to the renderer. * @param groups The {@link TrackGroupArray} mapped to the renderer.
* @param formatSupport The result of {@link RendererCapabilities#supportsFormat} for each mapped * @param formatSupport The {@link Capabilities} for each mapped track, indexed by renderer, track
* track, indexed by track group index and track index (in that order). * group and track (in that order).
* @param params The selector's current constraint parameters. * @param params The selector's current constraint parameters.
* @return The {@link TrackSelection} for the renderer, or null if no selection was made. * @return The {@link TrackSelection} for the renderer, or null if no selection was made.
* @throws ExoPlaybackException If an error occurs while selecting the tracks. * @throws ExoPlaybackException If an error occurs while selecting the tracks.
*/ */
@Nullable @Nullable
protected TrackSelection.Definition selectOtherTrack( protected TrackSelection.Definition selectOtherTrack(
int trackType, TrackGroupArray groups, int[][] formatSupport, Parameters params) int trackType, TrackGroupArray groups, @Capabilities int[][] formatSupport, Parameters params)
throws ExoPlaybackException { throws ExoPlaybackException {
TrackGroup selectedGroup = null; TrackGroup selectedGroup = null;
int selectedTrackIndex = 0; int selectedTrackIndex = 0;
int selectedTrackScore = 0; int selectedTrackScore = 0;
for (int groupIndex = 0; groupIndex < groups.length; groupIndex++) { for (int groupIndex = 0; groupIndex < groups.length; groupIndex++) {
TrackGroup trackGroup = groups.get(groupIndex); TrackGroup trackGroup = groups.get(groupIndex);
int[] trackFormatSupport = formatSupport[groupIndex]; @Capabilities int[] trackFormatSupport = formatSupport[groupIndex];
for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) { for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
if (isSupported(trackFormatSupport[trackIndex], if (isSupported(trackFormatSupport[trackIndex],
params.exceedRendererCapabilitiesIfNecessary)) { params.exceedRendererCapabilitiesIfNecessary)) {
...@@ -2351,6 +2354,8 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2351,6 +2354,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* renderers if so. * renderers if so.
* *
* @param mappedTrackInfo Mapped track information. * @param mappedTrackInfo Mapped track information.
* @param renderererFormatSupports The {@link Capabilities} for each mapped track, indexed by
* renderer, track group and track (in that order).
* @param rendererConfigurations The renderer configurations. Configurations may be replaced with * @param rendererConfigurations The renderer configurations. Configurations may be replaced with
* ones that enable tunneling as a result of this call. * ones that enable tunneling as a result of this call.
* @param trackSelections The renderer track selections. * @param trackSelections The renderer track selections.
...@@ -2359,7 +2364,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2359,7 +2364,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
*/ */
private static void maybeConfigureRenderersForTunneling( private static void maybeConfigureRenderersForTunneling(
MappedTrackInfo mappedTrackInfo, MappedTrackInfo mappedTrackInfo,
int[][][] renderererFormatSupports, @Capabilities int[][][] renderererFormatSupports,
@NullableType RendererConfiguration[] rendererConfigurations, @NullableType RendererConfiguration[] rendererConfigurations,
@NullableType TrackSelection[] trackSelections, @NullableType TrackSelection[] trackSelections,
int tunnelingAudioSessionId) { int tunnelingAudioSessionId) {
...@@ -2408,21 +2413,22 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2408,21 +2413,22 @@ public class DefaultTrackSelector extends MappingTrackSelector {
/** /**
* Returns whether a renderer supports tunneling for a {@link TrackSelection}. * Returns whether a renderer supports tunneling for a {@link TrackSelection}.
* *
* @param formatSupports The result of {@link RendererCapabilities#supportsFormat} for each track, * @param formatSupports The {@link Capabilities} for each track, indexed by group index and track
* indexed by group index and track index (in that order). * index (in that order).
* @param trackGroups The {@link TrackGroupArray}s for the renderer. * @param trackGroups The {@link TrackGroupArray}s for the renderer.
* @param selection The track selection. * @param selection The track selection.
* @return Whether the renderer supports tunneling for the {@link TrackSelection}. * @return Whether the renderer supports tunneling for the {@link TrackSelection}.
*/ */
private static boolean rendererSupportsTunneling( private static boolean rendererSupportsTunneling(
int[][] formatSupports, TrackGroupArray trackGroups, TrackSelection selection) { @Capabilities int[][] formatSupports, TrackGroupArray trackGroups, TrackSelection selection) {
if (selection == null) { if (selection == null) {
return false; return false;
} }
int trackGroupIndex = trackGroups.indexOf(selection.getTrackGroup()); int trackGroupIndex = trackGroups.indexOf(selection.getTrackGroup());
for (int i = 0; i < selection.length(); i++) { for (int i = 0; i < selection.length(); i++) {
@Capabilities
int trackFormatSupport = formatSupports[trackGroupIndex][selection.getIndexInTrackGroup(i)]; int trackFormatSupport = formatSupports[trackGroupIndex][selection.getIndexInTrackGroup(i)];
if ((trackFormatSupport & RendererCapabilities.TUNNELING_SUPPORT_MASK) if (RendererCapabilities.getTunnelingSupport(trackFormatSupport)
!= RendererCapabilities.TUNNELING_SUPPORTED) { != RendererCapabilities.TUNNELING_SUPPORTED) {
return false; return false;
} }
...@@ -2446,20 +2452,20 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2446,20 +2452,20 @@ public class DefaultTrackSelector extends MappingTrackSelector {
} }
/** /**
* Applies the {@link RendererCapabilities#FORMAT_SUPPORT_MASK} to a value obtained from * Returns true if the {@link FormatSupport} in the given {@link Capabilities} is {@link
* {@link RendererCapabilities#supportsFormat(Format)}, returning true if the result is * RendererCapabilities#FORMAT_HANDLED} or if {@code allowExceedsCapabilities} is set and the
* {@link RendererCapabilities#FORMAT_HANDLED} or if {@code allowExceedsCapabilities} is set * format support is {@link RendererCapabilities#FORMAT_EXCEEDS_CAPABILITIES}.
* and the result is {@link RendererCapabilities#FORMAT_EXCEEDS_CAPABILITIES}.
* *
* @param formatSupport A value obtained from {@link RendererCapabilities#supportsFormat(Format)}. * @param formatSupport {@link Capabilities}.
* @param allowExceedsCapabilities Whether to return true if the format support component of the * @param allowExceedsCapabilities Whether to return true if {@link FormatSupport} is {@link
* value is {@link RendererCapabilities#FORMAT_EXCEEDS_CAPABILITIES}. * RendererCapabilities#FORMAT_EXCEEDS_CAPABILITIES}.
* @return True if the format support component is {@link RendererCapabilities#FORMAT_HANDLED}, or * @return True if {@link FormatSupport} is {@link RendererCapabilities#FORMAT_HANDLED}, or if
* if {@code allowExceedsCapabilities} is set and the format support component is * {@code allowExceedsCapabilities} is set and the format support is {@link
* {@link RendererCapabilities#FORMAT_EXCEEDS_CAPABILITIES}. * RendererCapabilities#FORMAT_EXCEEDS_CAPABILITIES}.
*/ */
protected static boolean isSupported(int formatSupport, boolean allowExceedsCapabilities) { protected static boolean isSupported(
int maskedSupport = formatSupport & RendererCapabilities.FORMAT_SUPPORT_MASK; @Capabilities int formatSupport, boolean allowExceedsCapabilities) {
@FormatSupport int maskedSupport = RendererCapabilities.getFormatSupport(formatSupport);
return maskedSupport == RendererCapabilities.FORMAT_HANDLED || (allowExceedsCapabilities return maskedSupport == RendererCapabilities.FORMAT_HANDLED || (allowExceedsCapabilities
&& maskedSupport == RendererCapabilities.FORMAT_EXCEEDS_CAPABILITIES); && maskedSupport == RendererCapabilities.FORMAT_EXCEEDS_CAPABILITIES);
} }
...@@ -2615,7 +2621,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2615,7 +2621,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
private final int sampleRate; private final int sampleRate;
private final int bitrate; private final int bitrate;
public AudioTrackScore(Format format, Parameters parameters, int formatSupport) { public AudioTrackScore(Format format, Parameters parameters, @Capabilities int formatSupport) {
this.parameters = parameters; this.parameters = parameters;
this.language = normalizeUndeterminedLanguageToNull(format.language); this.language = normalizeUndeterminedLanguageToNull(format.language);
isWithinRendererCapabilities = isSupported(formatSupport, false); isWithinRendererCapabilities = isSupported(formatSupport, false);
...@@ -2754,7 +2760,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2754,7 +2760,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
public TextTrackScore( public TextTrackScore(
Format format, Format format,
Parameters parameters, Parameters parameters,
int trackFormatSupport, @Capabilities int trackFormatSupport,
@Nullable String selectedAudioLanguage) { @Nullable String selectedAudioLanguage) {
isWithinRendererCapabilities = isWithinRendererCapabilities =
isSupported(trackFormatSupport, /* allowExceedsCapabilities= */ false); isSupported(trackFormatSupport, /* allowExceedsCapabilities= */ false);
......
...@@ -22,6 +22,9 @@ import com.google.android.exoplayer2.C; ...@@ -22,6 +22,9 @@ import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.Renderer; import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.RendererCapabilities; import com.google.android.exoplayer2.RendererCapabilities;
import com.google.android.exoplayer2.RendererCapabilities.AdaptiveSupport;
import com.google.android.exoplayer2.RendererCapabilities.Capabilities;
import com.google.android.exoplayer2.RendererCapabilities.FormatSupport;
import com.google.android.exoplayer2.RendererConfiguration; import com.google.android.exoplayer2.RendererConfiguration;
import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId; import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
...@@ -90,25 +93,25 @@ public abstract class MappingTrackSelector extends TrackSelector { ...@@ -90,25 +93,25 @@ public abstract class MappingTrackSelector extends TrackSelector {
private final int rendererCount; private final int rendererCount;
private final int[] rendererTrackTypes; private final int[] rendererTrackTypes;
private final TrackGroupArray[] rendererTrackGroups; private final TrackGroupArray[] rendererTrackGroups;
private final int[] rendererMixedMimeTypeAdaptiveSupports; @AdaptiveSupport private final int[] rendererMixedMimeTypeAdaptiveSupports;
private final int[][][] rendererFormatSupports; @Capabilities private final int[][][] rendererFormatSupports;
private final TrackGroupArray unmappedTrackGroups; private final TrackGroupArray unmappedTrackGroups;
/** /**
* @param rendererTrackTypes The track type handled by each renderer. * @param rendererTrackTypes The track type handled by each renderer.
* @param rendererTrackGroups The {@link TrackGroup}s mapped to each renderer. * @param rendererTrackGroups The {@link TrackGroup}s mapped to each renderer.
* @param rendererMixedMimeTypeAdaptiveSupports The result of {@link * @param rendererMixedMimeTypeAdaptiveSupports The {@link AdaptiveSupport} for mixed MIME type
* RendererCapabilities#supportsMixedMimeTypeAdaptation()} for each renderer. * adaptation for the renderer.
* @param rendererFormatSupports The result of {@link RendererCapabilities#supportsFormat} for * @param rendererFormatSupports The {@link Capabilities} for each mapped track, indexed by
* each mapped track, indexed by renderer, track group and track (in that order). * renderer, track group and track (in that order).
* @param unmappedTrackGroups {@link TrackGroup}s not mapped to any renderer. * @param unmappedTrackGroups {@link TrackGroup}s not mapped to any renderer.
*/ */
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
/* package */ MappedTrackInfo( /* package */ MappedTrackInfo(
int[] rendererTrackTypes, int[] rendererTrackTypes,
TrackGroupArray[] rendererTrackGroups, TrackGroupArray[] rendererTrackGroups,
int[] rendererMixedMimeTypeAdaptiveSupports, @AdaptiveSupport int[] rendererMixedMimeTypeAdaptiveSupports,
int[][][] rendererFormatSupports, @Capabilities int[][][] rendererFormatSupports,
TrackGroupArray unmappedTrackGroups) { TrackGroupArray unmappedTrackGroups) {
this.rendererTrackTypes = rendererTrackTypes; this.rendererTrackTypes = rendererTrackTypes;
this.rendererTrackGroups = rendererTrackGroups; this.rendererTrackGroups = rendererTrackGroups;
...@@ -149,25 +152,28 @@ public abstract class MappingTrackSelector extends TrackSelector { ...@@ -149,25 +152,28 @@ public abstract class MappingTrackSelector extends TrackSelector {
* Returns the extent to which a renderer can play the tracks that are mapped to it. * Returns the extent to which a renderer can play the tracks that are mapped to it.
* *
* @param rendererIndex The renderer index. * @param rendererIndex The renderer index.
* @return One of {@link #RENDERER_SUPPORT_PLAYABLE_TRACKS}, {@link * @return The {@link RendererSupport}.
* #RENDERER_SUPPORT_EXCEEDS_CAPABILITIES_TRACKS}, {@link
* #RENDERER_SUPPORT_UNSUPPORTED_TRACKS} and {@link #RENDERER_SUPPORT_NO_TRACKS}.
*/ */
public @RendererSupport int getRendererSupport(int rendererIndex) { @RendererSupport
int bestRendererSupport = RENDERER_SUPPORT_NO_TRACKS; public int getRendererSupport(int rendererIndex) {
int[][] rendererFormatSupport = rendererFormatSupports[rendererIndex]; @RendererSupport int bestRendererSupport = RENDERER_SUPPORT_NO_TRACKS;
for (int[] trackGroupFormatSupport : rendererFormatSupport) { @Capabilities int[][] rendererFormatSupport = rendererFormatSupports[rendererIndex];
for (int trackFormatSupport : trackGroupFormatSupport) { for (@Capabilities int[] trackGroupFormatSupport : rendererFormatSupport) {
for (@Capabilities int trackFormatSupport : trackGroupFormatSupport) {
int trackRendererSupport; int trackRendererSupport;
switch (trackFormatSupport & RendererCapabilities.FORMAT_SUPPORT_MASK) { switch (RendererCapabilities.getFormatSupport(trackFormatSupport)) {
case RendererCapabilities.FORMAT_HANDLED: case RendererCapabilities.FORMAT_HANDLED:
return RENDERER_SUPPORT_PLAYABLE_TRACKS; return RENDERER_SUPPORT_PLAYABLE_TRACKS;
case RendererCapabilities.FORMAT_EXCEEDS_CAPABILITIES: case RendererCapabilities.FORMAT_EXCEEDS_CAPABILITIES:
trackRendererSupport = RENDERER_SUPPORT_EXCEEDS_CAPABILITIES_TRACKS; trackRendererSupport = RENDERER_SUPPORT_EXCEEDS_CAPABILITIES_TRACKS;
break; break;
default: case RendererCapabilities.FORMAT_UNSUPPORTED_TYPE:
case RendererCapabilities.FORMAT_UNSUPPORTED_SUBTYPE:
case RendererCapabilities.FORMAT_UNSUPPORTED_DRM:
trackRendererSupport = RENDERER_SUPPORT_UNSUPPORTED_TRACKS; trackRendererSupport = RENDERER_SUPPORT_UNSUPPORTED_TRACKS;
break; break;
default:
throw new IllegalStateException();
} }
bestRendererSupport = Math.max(bestRendererSupport, trackRendererSupport); bestRendererSupport = Math.max(bestRendererSupport, trackRendererSupport);
} }
...@@ -177,7 +183,8 @@ public abstract class MappingTrackSelector extends TrackSelector { ...@@ -177,7 +183,8 @@ public abstract class MappingTrackSelector extends TrackSelector {
/** @deprecated Use {@link #getTypeSupport(int)}. */ /** @deprecated Use {@link #getTypeSupport(int)}. */
@Deprecated @Deprecated
public @RendererSupport int getTrackTypeRendererSupport(int trackType) { @RendererSupport
public int getTrackTypeRendererSupport(int trackType) {
return getTypeSupport(trackType); return getTypeSupport(trackType);
} }
...@@ -188,12 +195,11 @@ public abstract class MappingTrackSelector extends TrackSelector { ...@@ -188,12 +195,11 @@ public abstract class MappingTrackSelector extends TrackSelector {
* returned. * returned.
* *
* @param trackType The track type. One of the {@link C} {@code TRACK_TYPE_*} constants. * @param trackType The track type. One of the {@link C} {@code TRACK_TYPE_*} constants.
* @return One of {@link #RENDERER_SUPPORT_PLAYABLE_TRACKS}, {@link * @return The {@link RendererSupport}.
* #RENDERER_SUPPORT_EXCEEDS_CAPABILITIES_TRACKS}, {@link
* #RENDERER_SUPPORT_UNSUPPORTED_TRACKS} and {@link #RENDERER_SUPPORT_NO_TRACKS}.
*/ */
public @RendererSupport int getTypeSupport(int trackType) { @RendererSupport
int bestRendererSupport = RENDERER_SUPPORT_NO_TRACKS; public int getTypeSupport(int trackType) {
@RendererSupport int bestRendererSupport = RENDERER_SUPPORT_NO_TRACKS;
for (int i = 0; i < rendererCount; i++) { for (int i = 0; i < rendererCount; i++) {
if (rendererTrackTypes[i] == trackType) { if (rendererTrackTypes[i] == trackType) {
bestRendererSupport = Math.max(bestRendererSupport, getRendererSupport(i)); bestRendererSupport = Math.max(bestRendererSupport, getRendererSupport(i));
...@@ -204,6 +210,7 @@ public abstract class MappingTrackSelector extends TrackSelector { ...@@ -204,6 +210,7 @@ public abstract class MappingTrackSelector extends TrackSelector {
/** @deprecated Use {@link #getTrackSupport(int, int, int)}. */ /** @deprecated Use {@link #getTrackSupport(int, int, int)}. */
@Deprecated @Deprecated
@FormatSupport
public int getTrackFormatSupport(int rendererIndex, int groupIndex, int trackIndex) { public int getTrackFormatSupport(int rendererIndex, int groupIndex, int trackIndex) {
return getTrackSupport(rendererIndex, groupIndex, trackIndex); return getTrackSupport(rendererIndex, groupIndex, trackIndex);
} }
...@@ -214,15 +221,12 @@ public abstract class MappingTrackSelector extends TrackSelector { ...@@ -214,15 +221,12 @@ public abstract class MappingTrackSelector extends TrackSelector {
* @param rendererIndex The renderer index. * @param rendererIndex The renderer index.
* @param groupIndex The index of the track group to which the track belongs. * @param groupIndex The index of the track group to which the track belongs.
* @param trackIndex The index of the track within the track group. * @param trackIndex The index of the track within the track group.
* @return One of {@link RendererCapabilities#FORMAT_HANDLED}, {@link * @return The {@link FormatSupport}.
* RendererCapabilities#FORMAT_EXCEEDS_CAPABILITIES}, {@link
* RendererCapabilities#FORMAT_UNSUPPORTED_DRM}, {@link
* RendererCapabilities#FORMAT_UNSUPPORTED_SUBTYPE} and {@link
* RendererCapabilities#FORMAT_UNSUPPORTED_TYPE}.
*/ */
@FormatSupport
public int getTrackSupport(int rendererIndex, int groupIndex, int trackIndex) { public int getTrackSupport(int rendererIndex, int groupIndex, int trackIndex) {
return rendererFormatSupports[rendererIndex][groupIndex][trackIndex] return RendererCapabilities.getFormatSupport(
& RendererCapabilities.FORMAT_SUPPORT_MASK; rendererFormatSupports[rendererIndex][groupIndex][trackIndex]);
} }
/** /**
...@@ -242,10 +246,9 @@ public abstract class MappingTrackSelector extends TrackSelector { ...@@ -242,10 +246,9 @@ public abstract class MappingTrackSelector extends TrackSelector {
* @param groupIndex The index of the track group. * @param groupIndex The index of the track group.
* @param includeCapabilitiesExceededTracks Whether tracks that exceed the capabilities of the * @param includeCapabilitiesExceededTracks Whether tracks that exceed the capabilities of the
* renderer are included when determining support. * renderer are included when determining support.
* @return One of {@link RendererCapabilities#ADAPTIVE_SEAMLESS}, {@link * @return The {@link AdaptiveSupport}.
* RendererCapabilities#ADAPTIVE_NOT_SEAMLESS} and {@link
* RendererCapabilities#ADAPTIVE_NOT_SUPPORTED}.
*/ */
@AdaptiveSupport
public int getAdaptiveSupport( public int getAdaptiveSupport(
int rendererIndex, int groupIndex, boolean includeCapabilitiesExceededTracks) { int rendererIndex, int groupIndex, boolean includeCapabilitiesExceededTracks) {
int trackCount = rendererTrackGroups[rendererIndex].get(groupIndex).length; int trackCount = rendererTrackGroups[rendererIndex].get(groupIndex).length;
...@@ -253,7 +256,7 @@ public abstract class MappingTrackSelector extends TrackSelector { ...@@ -253,7 +256,7 @@ public abstract class MappingTrackSelector extends TrackSelector {
int[] trackIndices = new int[trackCount]; int[] trackIndices = new int[trackCount];
int trackIndexCount = 0; int trackIndexCount = 0;
for (int i = 0; i < trackCount; i++) { for (int i = 0; i < trackCount; i++) {
int fixedSupport = getTrackSupport(rendererIndex, groupIndex, i); @FormatSupport int fixedSupport = getTrackSupport(rendererIndex, groupIndex, i);
if (fixedSupport == RendererCapabilities.FORMAT_HANDLED if (fixedSupport == RendererCapabilities.FORMAT_HANDLED
|| (includeCapabilitiesExceededTracks || (includeCapabilitiesExceededTracks
&& fixedSupport == RendererCapabilities.FORMAT_EXCEEDS_CAPABILITIES)) { && fixedSupport == RendererCapabilities.FORMAT_EXCEEDS_CAPABILITIES)) {
...@@ -270,13 +273,12 @@ public abstract class MappingTrackSelector extends TrackSelector { ...@@ -270,13 +273,12 @@ public abstract class MappingTrackSelector extends TrackSelector {
* *
* @param rendererIndex The renderer index. * @param rendererIndex The renderer index.
* @param groupIndex The index of the track group. * @param groupIndex The index of the track group.
* @return One of {@link RendererCapabilities#ADAPTIVE_SEAMLESS}, {@link * @return The {@link AdaptiveSupport}.
* RendererCapabilities#ADAPTIVE_NOT_SEAMLESS} and {@link
* RendererCapabilities#ADAPTIVE_NOT_SUPPORTED}.
*/ */
@AdaptiveSupport
public int getAdaptiveSupport(int rendererIndex, int groupIndex, int[] trackIndices) { public int getAdaptiveSupport(int rendererIndex, int groupIndex, int[] trackIndices) {
int handledTrackCount = 0; int handledTrackCount = 0;
int adaptiveSupport = RendererCapabilities.ADAPTIVE_SEAMLESS; @AdaptiveSupport int adaptiveSupport = RendererCapabilities.ADAPTIVE_SEAMLESS;
boolean multipleMimeTypes = false; boolean multipleMimeTypes = false;
String firstSampleMimeType = null; String firstSampleMimeType = null;
for (int i = 0; i < trackIndices.length; i++) { for (int i = 0; i < trackIndices.length; i++) {
...@@ -291,8 +293,8 @@ public abstract class MappingTrackSelector extends TrackSelector { ...@@ -291,8 +293,8 @@ public abstract class MappingTrackSelector extends TrackSelector {
adaptiveSupport = adaptiveSupport =
Math.min( Math.min(
adaptiveSupport, adaptiveSupport,
rendererFormatSupports[rendererIndex][groupIndex][i] RendererCapabilities.getAdaptiveSupport(
& RendererCapabilities.ADAPTIVE_SUPPORT_MASK); rendererFormatSupports[rendererIndex][groupIndex][i]));
} }
return multipleMimeTypes return multipleMimeTypes
? Math.min(adaptiveSupport, rendererMixedMimeTypeAdaptiveSupports[rendererIndex]) ? Math.min(adaptiveSupport, rendererMixedMimeTypeAdaptiveSupports[rendererIndex])
...@@ -341,13 +343,14 @@ public abstract class MappingTrackSelector extends TrackSelector { ...@@ -341,13 +343,14 @@ public abstract class MappingTrackSelector extends TrackSelector {
// any renderer. // any renderer.
int[] rendererTrackGroupCounts = new int[rendererCapabilities.length + 1]; int[] rendererTrackGroupCounts = new int[rendererCapabilities.length + 1];
TrackGroup[][] rendererTrackGroups = new TrackGroup[rendererCapabilities.length + 1][]; TrackGroup[][] rendererTrackGroups = new TrackGroup[rendererCapabilities.length + 1][];
int[][][] rendererFormatSupports = new int[rendererCapabilities.length + 1][][]; @Capabilities int[][][] rendererFormatSupports = new int[rendererCapabilities.length + 1][][];
for (int i = 0; i < rendererTrackGroups.length; i++) { for (int i = 0; i < rendererTrackGroups.length; i++) {
rendererTrackGroups[i] = new TrackGroup[trackGroups.length]; rendererTrackGroups[i] = new TrackGroup[trackGroups.length];
rendererFormatSupports[i] = new int[trackGroups.length][]; rendererFormatSupports[i] = new int[trackGroups.length][];
} }
// Determine the extent to which each renderer supports mixed mimeType adaptation. // Determine the extent to which each renderer supports mixed mimeType adaptation.
@AdaptiveSupport
int[] rendererMixedMimeTypeAdaptationSupports = int[] rendererMixedMimeTypeAdaptationSupports =
getMixedMimeTypeAdaptationSupports(rendererCapabilities); getMixedMimeTypeAdaptationSupports(rendererCapabilities);
...@@ -358,8 +361,11 @@ public abstract class MappingTrackSelector extends TrackSelector { ...@@ -358,8 +361,11 @@ public abstract class MappingTrackSelector extends TrackSelector {
// Associate the group to a preferred renderer. // Associate the group to a preferred renderer.
int rendererIndex = findRenderer(rendererCapabilities, group); int rendererIndex = findRenderer(rendererCapabilities, group);
// Evaluate the support that the renderer provides for each track in the group. // Evaluate the support that the renderer provides for each track in the group.
int[] rendererFormatSupport = rendererIndex == rendererCapabilities.length @Capabilities
? new int[group.length] : getFormatSupport(rendererCapabilities[rendererIndex], group); int[] rendererFormatSupport =
rendererIndex == rendererCapabilities.length
? new int[group.length]
: getFormatSupport(rendererCapabilities[rendererIndex], group);
// Stash the results. // Stash the results.
int rendererTrackGroupCount = rendererTrackGroupCounts[rendererIndex]; int rendererTrackGroupCount = rendererTrackGroupCounts[rendererIndex];
rendererTrackGroups[rendererIndex][rendererTrackGroupCount] = group; rendererTrackGroups[rendererIndex][rendererTrackGroupCount] = group;
...@@ -406,10 +412,10 @@ public abstract class MappingTrackSelector extends TrackSelector { ...@@ -406,10 +412,10 @@ public abstract class MappingTrackSelector extends TrackSelector {
* Given mapped track information, returns a track selection and configuration for each renderer. * Given mapped track information, returns a track selection and configuration for each renderer.
* *
* @param mappedTrackInfo Mapped track information. * @param mappedTrackInfo Mapped track information.
* @param rendererFormatSupports The result of {@link RendererCapabilities#supportsFormat} for * @param rendererFormatSupports The {@link Capabilities} for ach mapped track, indexed by
* each mapped track, indexed by renderer, track group and track (in that order). * renderer, track group and track (in that order).
* @param rendererMixedMimeTypeAdaptationSupport The result of {@link * @param rendererMixedMimeTypeAdaptationSupport The {@link AdaptiveSupport} for mixed MIME type
* RendererCapabilities#supportsMixedMimeTypeAdaptation()} for each renderer. * adaptation for the renderer.
* @return A pair consisting of the track selections and configurations for each renderer. A null * @return A pair consisting of the track selections and configurations for each renderer. A null
* configuration indicates the renderer should be disabled, in which case the track selection * configuration indicates the renderer should be disabled, in which case the track selection
* will also be null. A track selection may also be null for a non-disabled renderer if {@link * will also be null. A track selection may also be null for a non-disabled renderer if {@link
...@@ -419,8 +425,8 @@ public abstract class MappingTrackSelector extends TrackSelector { ...@@ -419,8 +425,8 @@ public abstract class MappingTrackSelector extends TrackSelector {
protected abstract Pair<@NullableType RendererConfiguration[], @NullableType TrackSelection[]> protected abstract Pair<@NullableType RendererConfiguration[], @NullableType TrackSelection[]>
selectTracks( selectTracks(
MappedTrackInfo mappedTrackInfo, MappedTrackInfo mappedTrackInfo,
int[][][] rendererFormatSupports, @Capabilities int[][][] rendererFormatSupports,
int[] rendererMixedMimeTypeAdaptationSupport) @AdaptiveSupport int[] rendererMixedMimeTypeAdaptationSupport)
throws ExoPlaybackException; throws ExoPlaybackException;
/** /**
...@@ -446,12 +452,14 @@ public abstract class MappingTrackSelector extends TrackSelector { ...@@ -446,12 +452,14 @@ public abstract class MappingTrackSelector extends TrackSelector {
private static int findRenderer(RendererCapabilities[] rendererCapabilities, TrackGroup group) private static int findRenderer(RendererCapabilities[] rendererCapabilities, TrackGroup group)
throws ExoPlaybackException { throws ExoPlaybackException {
int bestRendererIndex = rendererCapabilities.length; int bestRendererIndex = rendererCapabilities.length;
int bestFormatSupportLevel = RendererCapabilities.FORMAT_UNSUPPORTED_TYPE; @FormatSupport int bestFormatSupportLevel = RendererCapabilities.FORMAT_UNSUPPORTED_TYPE;
for (int rendererIndex = 0; rendererIndex < rendererCapabilities.length; rendererIndex++) { for (int rendererIndex = 0; rendererIndex < rendererCapabilities.length; rendererIndex++) {
RendererCapabilities rendererCapability = rendererCapabilities[rendererIndex]; RendererCapabilities rendererCapability = rendererCapabilities[rendererIndex];
for (int trackIndex = 0; trackIndex < group.length; trackIndex++) { for (int trackIndex = 0; trackIndex < group.length; trackIndex++) {
int formatSupportLevel = rendererCapability.supportsFormat(group.getFormat(trackIndex)) @FormatSupport
& RendererCapabilities.FORMAT_SUPPORT_MASK; int formatSupportLevel =
RendererCapabilities.getFormatSupport(
rendererCapability.supportsFormat(group.getFormat(trackIndex)));
if (formatSupportLevel > bestFormatSupportLevel) { if (formatSupportLevel > bestFormatSupportLevel) {
bestRendererIndex = rendererIndex; bestRendererIndex = rendererIndex;
bestFormatSupportLevel = formatSupportLevel; bestFormatSupportLevel = formatSupportLevel;
...@@ -466,18 +474,18 @@ public abstract class MappingTrackSelector extends TrackSelector { ...@@ -466,18 +474,18 @@ public abstract class MappingTrackSelector extends TrackSelector {
} }
/** /**
* Calls {@link RendererCapabilities#supportsFormat} for each track in the specified * Calls {@link RendererCapabilities#supportsFormat} for each track in the specified {@link
* {@link TrackGroup}, returning the results in an array. * TrackGroup}, returning the results in an array.
* *
* @param rendererCapabilities The {@link RendererCapabilities} of the renderer. * @param rendererCapabilities The {@link RendererCapabilities} of the renderer.
* @param group The track group to evaluate. * @param group The track group to evaluate.
* @return An array containing the result of calling * @return An array containing {@link Capabilities} for each track in the group.
* {@link RendererCapabilities#supportsFormat} for each track in the group.
* @throws ExoPlaybackException If an error occurs determining the format support. * @throws ExoPlaybackException If an error occurs determining the format support.
*/ */
@Capabilities
private static int[] getFormatSupport(RendererCapabilities rendererCapabilities, TrackGroup group) private static int[] getFormatSupport(RendererCapabilities rendererCapabilities, TrackGroup group)
throws ExoPlaybackException { throws ExoPlaybackException {
int[] formatSupport = new int[group.length]; @Capabilities int[] formatSupport = new int[group.length];
for (int i = 0; i < group.length; i++) { for (int i = 0; i < group.length; i++) {
formatSupport[i] = rendererCapabilities.supportsFormat(group.getFormat(i)); formatSupport[i] = rendererCapabilities.supportsFormat(group.getFormat(i));
} }
...@@ -489,13 +497,14 @@ public abstract class MappingTrackSelector extends TrackSelector { ...@@ -489,13 +497,14 @@ public abstract class MappingTrackSelector extends TrackSelector {
* returning the results in an array. * returning the results in an array.
* *
* @param rendererCapabilities The {@link RendererCapabilities} of the renderers. * @param rendererCapabilities The {@link RendererCapabilities} of the renderers.
* @return An array containing the result of calling {@link * @return An array containing the {@link AdaptiveSupport} for mixed MIME type adaptation for the
* RendererCapabilities#supportsMixedMimeTypeAdaptation()} for each renderer. * renderer.
* @throws ExoPlaybackException If an error occurs determining the adaptation support. * @throws ExoPlaybackException If an error occurs determining the adaptation support.
*/ */
@AdaptiveSupport
private static int[] getMixedMimeTypeAdaptationSupports( private static int[] getMixedMimeTypeAdaptationSupports(
RendererCapabilities[] rendererCapabilities) throws ExoPlaybackException { RendererCapabilities[] rendererCapabilities) throws ExoPlaybackException {
int[] mixedMimeTypeAdaptationSupport = new int[rendererCapabilities.length]; @AdaptiveSupport int[] mixedMimeTypeAdaptationSupport = new int[rendererCapabilities.length];
for (int i = 0; i < mixedMimeTypeAdaptationSupport.length; i++) { for (int i = 0; i < mixedMimeTypeAdaptationSupport.length; i++) {
mixedMimeTypeAdaptationSupport[i] = rendererCapabilities[i].supportsMixedMimeTypeAdaptation(); mixedMimeTypeAdaptationSupport[i] = rendererCapabilities[i].supportsMixedMimeTypeAdaptation();
} }
......
...@@ -25,6 +25,8 @@ import com.google.android.exoplayer2.PlaybackParameters; ...@@ -25,6 +25,8 @@ import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.Player; import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.Player.PlaybackSuppressionReason; import com.google.android.exoplayer2.Player.PlaybackSuppressionReason;
import com.google.android.exoplayer2.RendererCapabilities; import com.google.android.exoplayer2.RendererCapabilities;
import com.google.android.exoplayer2.RendererCapabilities.AdaptiveSupport;
import com.google.android.exoplayer2.RendererCapabilities.FormatSupport;
import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.analytics.AnalyticsListener; import com.google.android.exoplayer2.analytics.AnalyticsListener;
import com.google.android.exoplayer2.audio.AudioAttributes; import com.google.android.exoplayer2.audio.AudioAttributes;
...@@ -210,7 +212,8 @@ public class EventLogger implements AnalyticsListener { ...@@ -210,7 +212,8 @@ public class EventLogger implements AnalyticsListener {
String adaptiveSupport = String adaptiveSupport =
getAdaptiveSupportString( getAdaptiveSupportString(
trackGroup.length, trackGroup.length,
mappedTrackInfo.getAdaptiveSupport(rendererIndex, groupIndex, false)); mappedTrackInfo.getAdaptiveSupport(
rendererIndex, groupIndex, /* includeCapabilitiesExceededTracks= */ false));
logd(" Group:" + groupIndex + ", adaptive_supported=" + adaptiveSupport + " ["); logd(" Group:" + groupIndex + ", adaptive_supported=" + adaptiveSupport + " [");
for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) { for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
String status = getTrackStatusString(trackSelection, trackGroup, trackIndex); String status = getTrackStatusString(trackSelection, trackGroup, trackIndex);
...@@ -552,7 +555,7 @@ public class EventLogger implements AnalyticsListener { ...@@ -552,7 +555,7 @@ public class EventLogger implements AnalyticsListener {
} }
} }
private static String getFormatSupportString(int formatSupport) { private static String getFormatSupportString(@FormatSupport int formatSupport) {
switch (formatSupport) { switch (formatSupport) {
case RendererCapabilities.FORMAT_HANDLED: case RendererCapabilities.FORMAT_HANDLED:
return "YES"; return "YES";
...@@ -565,11 +568,12 @@ public class EventLogger implements AnalyticsListener { ...@@ -565,11 +568,12 @@ public class EventLogger implements AnalyticsListener {
case RendererCapabilities.FORMAT_UNSUPPORTED_TYPE: case RendererCapabilities.FORMAT_UNSUPPORTED_TYPE:
return "NO"; return "NO";
default: default:
return "?"; throw new IllegalStateException();
} }
} }
private static String getAdaptiveSupportString(int trackCount, int adaptiveSupport) { private static String getAdaptiveSupportString(
int trackCount, @AdaptiveSupport int adaptiveSupport) {
if (trackCount < 2) { if (trackCount < 2) {
return "N/A"; return "N/A";
} }
...@@ -581,7 +585,7 @@ public class EventLogger implements AnalyticsListener { ...@@ -581,7 +585,7 @@ public class EventLogger implements AnalyticsListener {
case RendererCapabilities.ADAPTIVE_NOT_SUPPORTED: case RendererCapabilities.ADAPTIVE_NOT_SUPPORTED:
return "NO"; return "NO";
default: default:
return "?"; throw new IllegalStateException();
} }
} }
......
...@@ -37,6 +37,7 @@ import com.google.android.exoplayer2.ExoPlayer; ...@@ -37,6 +37,7 @@ import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.FormatHolder; import com.google.android.exoplayer2.FormatHolder;
import com.google.android.exoplayer2.PlayerMessage.Target; import com.google.android.exoplayer2.PlayerMessage.Target;
import com.google.android.exoplayer2.RendererCapabilities;
import com.google.android.exoplayer2.decoder.DecoderInputBuffer; import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
import com.google.android.exoplayer2.drm.DrmInitData; import com.google.android.exoplayer2.drm.DrmInitData;
import com.google.android.exoplayer2.drm.DrmSessionManager; import com.google.android.exoplayer2.drm.DrmSessionManager;
...@@ -360,6 +361,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -360,6 +361,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
} }
@Override @Override
@Capabilities
protected int supportsFormat( protected int supportsFormat(
MediaCodecSelector mediaCodecSelector, MediaCodecSelector mediaCodecSelector,
@Nullable DrmSessionManager<FrameworkMediaCrypto> drmSessionManager, @Nullable DrmSessionManager<FrameworkMediaCrypto> drmSessionManager,
...@@ -367,7 +369,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -367,7 +369,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
throws DecoderQueryException { throws DecoderQueryException {
String mimeType = format.sampleMimeType; String mimeType = format.sampleMimeType;
if (!MimeTypes.isVideo(mimeType)) { if (!MimeTypes.isVideo(mimeType)) {
return FORMAT_UNSUPPORTED_TYPE; return RendererCapabilities.create(FORMAT_UNSUPPORTED_TYPE);
} }
@Nullable DrmInitData drmInitData = format.drmInitData; @Nullable DrmInitData drmInitData = format.drmInitData;
// Assume encrypted content requires secure decoders. // Assume encrypted content requires secure decoders.
...@@ -388,7 +390,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -388,7 +390,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
/* requiresTunnelingDecoder= */ false); /* requiresTunnelingDecoder= */ false);
} }
if (decoderInfos.isEmpty()) { if (decoderInfos.isEmpty()) {
return FORMAT_UNSUPPORTED_SUBTYPE; return RendererCapabilities.create(FORMAT_UNSUPPORTED_SUBTYPE);
} }
boolean supportsFormatDrm = boolean supportsFormatDrm =
drmInitData == null drmInitData == null
...@@ -396,16 +398,17 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -396,16 +398,17 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
|| (format.exoMediaCryptoType == null || (format.exoMediaCryptoType == null
&& supportsFormatDrm(drmSessionManager, drmInitData)); && supportsFormatDrm(drmSessionManager, drmInitData));
if (!supportsFormatDrm) { if (!supportsFormatDrm) {
return FORMAT_UNSUPPORTED_DRM; return RendererCapabilities.create(FORMAT_UNSUPPORTED_DRM);
} }
// Check capabilities for the first decoder in the list, which takes priority. // Check capabilities for the first decoder in the list, which takes priority.
MediaCodecInfo decoderInfo = decoderInfos.get(0); MediaCodecInfo decoderInfo = decoderInfos.get(0);
boolean isFormatSupported = decoderInfo.isFormatSupported(format); boolean isFormatSupported = decoderInfo.isFormatSupported(format);
@AdaptiveSupport
int adaptiveSupport = int adaptiveSupport =
decoderInfo.isSeamlessAdaptationSupported(format) decoderInfo.isSeamlessAdaptationSupported(format)
? ADAPTIVE_SEAMLESS ? ADAPTIVE_SEAMLESS
: ADAPTIVE_NOT_SEAMLESS; : ADAPTIVE_NOT_SEAMLESS;
int tunnelingSupport = TUNNELING_NOT_SUPPORTED; @TunnelingSupport int tunnelingSupport = TUNNELING_NOT_SUPPORTED;
if (isFormatSupported) { if (isFormatSupported) {
List<MediaCodecInfo> tunnelingDecoderInfos = List<MediaCodecInfo> tunnelingDecoderInfos =
getDecoderInfos( getDecoderInfos(
...@@ -421,8 +424,9 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -421,8 +424,9 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
} }
} }
} }
@FormatSupport
int formatSupport = isFormatSupported ? FORMAT_HANDLED : FORMAT_EXCEEDS_CAPABILITIES; int formatSupport = isFormatSupported ? FORMAT_HANDLED : FORMAT_EXCEEDS_CAPABILITIES;
return adaptiveSupport | tunnelingSupport | formatSupport; return RendererCapabilities.create(formatSupport, adaptiveSupport, tunnelingSupport);
} }
@Override @Override
......
...@@ -157,6 +157,7 @@ public abstract class SimpleDecoderVideoRenderer extends BaseRenderer { ...@@ -157,6 +157,7 @@ public abstract class SimpleDecoderVideoRenderer extends BaseRenderer {
// BaseRenderer implementation. // BaseRenderer implementation.
@Override @Override
@Capabilities
public final int supportsFormat(Format format) { public final int supportsFormat(Format format) {
return supportsFormatInternal(drmSessionManager, format); return supportsFormatInternal(drmSessionManager, format);
} }
...@@ -498,13 +499,14 @@ public abstract class SimpleDecoderVideoRenderer extends BaseRenderer { ...@@ -498,13 +499,14 @@ public abstract class SimpleDecoderVideoRenderer extends BaseRenderer {
} }
/** /**
* Returns the extent to which the subclass supports a given format. * Returns the {@link Capabilities} for the given {@link Format}.
* *
* @param drmSessionManager The renderer's {@link DrmSessionManager}. * @param drmSessionManager The renderer's {@link DrmSessionManager}.
* @param format The format, which has a video {@link Format#sampleMimeType}. * @param format The format, which has a video {@link Format#sampleMimeType}.
* @return The extent to which the subclass supports the format itself. * @return The {@link Capabilities} for this {@link Format}.
* @see RendererCapabilities#supportsFormat(Format) * @see RendererCapabilities#supportsFormat(Format)
*/ */
@Capabilities
protected abstract int supportsFormatInternal( protected abstract int supportsFormatInternal(
@Nullable DrmSessionManager<ExoMediaCrypto> drmSessionManager, Format format); @Nullable DrmSessionManager<ExoMediaCrypto> drmSessionManager, Format format);
......
...@@ -22,6 +22,7 @@ import com.google.android.exoplayer2.ExoPlaybackException; ...@@ -22,6 +22,7 @@ import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.FormatHolder; import com.google.android.exoplayer2.FormatHolder;
import com.google.android.exoplayer2.Renderer; import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.RendererCapabilities;
import com.google.android.exoplayer2.decoder.DecoderInputBuffer; import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.ParsableByteArray; import com.google.android.exoplayer2.util.ParsableByteArray;
...@@ -48,10 +49,11 @@ public class CameraMotionRenderer extends BaseRenderer { ...@@ -48,10 +49,11 @@ public class CameraMotionRenderer extends BaseRenderer {
} }
@Override @Override
@Capabilities
public int supportsFormat(Format format) { public int supportsFormat(Format format) {
return MimeTypes.APPLICATION_CAMERA_MOTION.equals(format.sampleMimeType) return MimeTypes.APPLICATION_CAMERA_MOTION.equals(format.sampleMimeType)
? FORMAT_HANDLED ? RendererCapabilities.create(FORMAT_HANDLED)
: FORMAT_UNSUPPORTED_TYPE; : RendererCapabilities.create(FORMAT_UNSUPPORTED_TYPE);
} }
@Override @Override
......
...@@ -58,6 +58,7 @@ public class SimpleDecoderAudioRendererTest { ...@@ -58,6 +58,7 @@ public class SimpleDecoderAudioRendererTest {
audioRenderer = audioRenderer =
new SimpleDecoderAudioRenderer(null, null, null, false, mockAudioSink) { new SimpleDecoderAudioRenderer(null, null, null, false, mockAudioSink) {
@Override @Override
@FormatSupport
protected int supportsFormatInternal( protected int supportsFormatInternal(
@Nullable DrmSessionManager<ExoMediaCrypto> drmSessionManager, Format format) { @Nullable DrmSessionManager<ExoMediaCrypto> drmSessionManager, Format format) {
return FORMAT_HANDLED; return FORMAT_HANDLED;
......
...@@ -1767,7 +1767,7 @@ public final class DefaultTrackSelectorTest { ...@@ -1767,7 +1767,7 @@ public final class DefaultTrackSelectorTest {
private static final class FakeRendererCapabilities implements RendererCapabilities { private static final class FakeRendererCapabilities implements RendererCapabilities {
private final int trackType; private final int trackType;
private final int supportValue; @Capabilities private final int supportValue;
/** /**
* Returns {@link FakeRendererCapabilities} that advertises adaptive support for all * Returns {@link FakeRendererCapabilities} that advertises adaptive support for all
...@@ -1777,19 +1777,21 @@ public final class DefaultTrackSelectorTest { ...@@ -1777,19 +1777,21 @@ public final class DefaultTrackSelectorTest {
* support for. * support for.
*/ */
FakeRendererCapabilities(int trackType) { FakeRendererCapabilities(int trackType) {
this(trackType, FORMAT_HANDLED | ADAPTIVE_SEAMLESS); this(
trackType,
RendererCapabilities.create(FORMAT_HANDLED, ADAPTIVE_SEAMLESS, TUNNELING_NOT_SUPPORTED));
} }
/** /**
* Returns {@link FakeRendererCapabilities} that advertises support level using given value * Returns {@link FakeRendererCapabilities} that advertises support level using given value for
* for all tracks of the given type. * all tracks of the given type.
* *
* @param trackType the track type of all formats that this renderer capabilities advertises * @param trackType the track type of all formats that this renderer capabilities advertises
* support for. * support for.
* @param supportValue the support level value that will be returned for formats with * @param supportValue the {@link Capabilities} that will be returned for formats with the given
* the given type. * type.
*/ */
FakeRendererCapabilities(int trackType, int supportValue) { FakeRendererCapabilities(int trackType, @Capabilities int supportValue) {
this.trackType = trackType; this.trackType = trackType;
this.supportValue = supportValue; this.supportValue = supportValue;
} }
...@@ -1800,12 +1802,15 @@ public final class DefaultTrackSelectorTest { ...@@ -1800,12 +1802,15 @@ public final class DefaultTrackSelectorTest {
} }
@Override @Override
@Capabilities
public int supportsFormat(Format format) { public int supportsFormat(Format format) {
return MimeTypes.getTrackType(format.sampleMimeType) == trackType return MimeTypes.getTrackType(format.sampleMimeType) == trackType
? (supportValue) : FORMAT_UNSUPPORTED_TYPE; ? supportValue
: RendererCapabilities.create(FORMAT_UNSUPPORTED_TYPE);
} }
@Override @Override
@AdaptiveSupport
public int supportsMixedMimeTypeAdaptation() { public int supportsMixedMimeTypeAdaptation() {
return ADAPTIVE_SEAMLESS; return ADAPTIVE_SEAMLESS;
} }
...@@ -1841,13 +1846,15 @@ public final class DefaultTrackSelectorTest { ...@@ -1841,13 +1846,15 @@ public final class DefaultTrackSelectorTest {
} }
@Override @Override
@Capabilities
public int supportsFormat(Format format) { public int supportsFormat(Format format) {
return format.id != null && formatToCapability.containsKey(format.id) return format.id != null && formatToCapability.containsKey(format.id)
? formatToCapability.get(format.id) ? formatToCapability.get(format.id)
: FORMAT_UNSUPPORTED_TYPE; : RendererCapabilities.create(FORMAT_UNSUPPORTED_TYPE);
} }
@Override @Override
@AdaptiveSupport
public int supportsMixedMimeTypeAdaptation() { public int supportsMixedMimeTypeAdaptation() {
return ADAPTIVE_SEAMLESS; return ADAPTIVE_SEAMLESS;
} }
......
...@@ -23,6 +23,8 @@ import com.google.android.exoplayer2.C; ...@@ -23,6 +23,8 @@ import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.RendererCapabilities; import com.google.android.exoplayer2.RendererCapabilities;
import com.google.android.exoplayer2.RendererCapabilities.AdaptiveSupport;
import com.google.android.exoplayer2.RendererCapabilities.Capabilities;
import com.google.android.exoplayer2.RendererConfiguration; import com.google.android.exoplayer2.RendererConfiguration;
import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId; import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
...@@ -112,8 +114,8 @@ public final class MappingTrackSelectorTest { ...@@ -112,8 +114,8 @@ public final class MappingTrackSelectorTest {
@Override @Override
protected Pair<RendererConfiguration[], TrackSelection[]> selectTracks( protected Pair<RendererConfiguration[], TrackSelection[]> selectTracks(
MappedTrackInfo mappedTrackInfo, MappedTrackInfo mappedTrackInfo,
int[][][] rendererFormatSupports, @Capabilities int[][][] rendererFormatSupports,
int[] rendererMixedMimeTypeAdaptationSupports) @AdaptiveSupport int[] rendererMixedMimeTypeAdaptationSupports)
throws ExoPlaybackException { throws ExoPlaybackException {
int rendererCount = mappedTrackInfo.getRendererCount(); int rendererCount = mappedTrackInfo.getRendererCount();
lastMappedTrackInfo = mappedTrackInfo; lastMappedTrackInfo = mappedTrackInfo;
...@@ -148,12 +150,15 @@ public final class MappingTrackSelectorTest { ...@@ -148,12 +150,15 @@ public final class MappingTrackSelectorTest {
} }
@Override @Override
@Capabilities
public int supportsFormat(Format format) throws ExoPlaybackException { public int supportsFormat(Format format) throws ExoPlaybackException {
return MimeTypes.getTrackType(format.sampleMimeType) == trackType return MimeTypes.getTrackType(format.sampleMimeType) == trackType
? (FORMAT_HANDLED | ADAPTIVE_SEAMLESS) : FORMAT_UNSUPPORTED_TYPE; ? RendererCapabilities.create(FORMAT_HANDLED, ADAPTIVE_SEAMLESS, TUNNELING_NOT_SUPPORTED)
: RendererCapabilities.create(FORMAT_UNSUPPORTED_TYPE);
} }
@Override @Override
@AdaptiveSupport
public int supportsMixedMimeTypeAdaptation() throws ExoPlaybackException { public int supportsMixedMimeTypeAdaptation() throws ExoPlaybackException {
return ADAPTIVE_SEAMLESS; return ADAPTIVE_SEAMLESS;
} }
......
...@@ -371,7 +371,8 @@ public class TrackSelectionView extends LinearLayout { ...@@ -371,7 +371,8 @@ public class TrackSelectionView extends LinearLayout {
private boolean shouldEnableAdaptiveSelection(int groupIndex) { private boolean shouldEnableAdaptiveSelection(int groupIndex) {
return allowAdaptiveSelections return allowAdaptiveSelections
&& trackGroups.get(groupIndex).length > 1 && trackGroups.get(groupIndex).length > 1
&& mappedTrackInfo.getAdaptiveSupport(rendererIndex, groupIndex, false) && mappedTrackInfo.getAdaptiveSupport(
rendererIndex, groupIndex, /* includeCapabilitiesExceededTracks= */ false)
!= RendererCapabilities.ADAPTIVE_NOT_SUPPORTED; != RendererCapabilities.ADAPTIVE_NOT_SUPPORTED;
} }
......
...@@ -451,7 +451,7 @@ import java.util.List; ...@@ -451,7 +451,7 @@ import java.util.List;
} }
private static boolean isFormatHandled(int formatSupport) { private static boolean isFormatHandled(int formatSupport) {
return (formatSupport & RendererCapabilities.FORMAT_SUPPORT_MASK) return RendererCapabilities.getFormatSupport(formatSupport)
== RendererCapabilities.FORMAT_HANDLED; == RendererCapabilities.FORMAT_HANDLED;
} }
......
...@@ -23,6 +23,7 @@ import com.google.android.exoplayer2.ExoPlaybackException; ...@@ -23,6 +23,7 @@ import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.FormatHolder; import com.google.android.exoplayer2.FormatHolder;
import com.google.android.exoplayer2.Renderer; import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.RendererCapabilities;
import com.google.android.exoplayer2.decoder.DecoderInputBuffer; import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
...@@ -110,9 +111,11 @@ public class FakeRenderer extends BaseRenderer { ...@@ -110,9 +111,11 @@ public class FakeRenderer extends BaseRenderer {
} }
@Override @Override
@Capabilities
public int supportsFormat(Format format) throws ExoPlaybackException { public int supportsFormat(Format format) throws ExoPlaybackException {
return getTrackType() == MimeTypes.getTrackType(format.sampleMimeType) return getTrackType() == MimeTypes.getTrackType(format.sampleMimeType)
? (FORMAT_HANDLED | ADAPTIVE_SEAMLESS) : FORMAT_UNSUPPORTED_TYPE; ? RendererCapabilities.create(FORMAT_HANDLED, ADAPTIVE_SEAMLESS, TUNNELING_NOT_SUPPORTED)
: RendererCapabilities.create(FORMAT_UNSUPPORTED_TYPE);
} }
/** Called when the renderer reads a new format. */ /** Called when the renderer reads a new format. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment