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