Return format and adaptation support from single method.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=114963314
This commit is contained in:
olly 2016-02-18 07:49:42 -08:00 committed by Oliver Woodman
parent 0e60335064
commit 39a924451a
5 changed files with 82 additions and 73 deletions

View file

@ -332,7 +332,8 @@ import java.util.concurrent.atomic.AtomicInteger;
Format[] adaptiveTrackFormats = new Format[trackGroup.length]; Format[] adaptiveTrackFormats = new Format[trackGroup.length];
for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) { for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
Format trackFormat = source.getTrackGroup(groupIndex).getFormat(trackIndex); Format trackFormat = source.getTrackGroup(groupIndex).getFormat(trackIndex);
if (renderer.supportsFormat(trackFormat) == TrackRenderer.FORMAT_HANDLED) { if ((renderer.supportsFormat(trackFormat) & TrackRenderer.FORMAT_SUPPORT_MASK)
== TrackRenderer.FORMAT_HANDLED) {
adaptiveTrackIndices[adaptiveTrackIndexCount] = trackIndex; adaptiveTrackIndices[adaptiveTrackIndexCount] = trackIndex;
adaptiveTrackFormats[adaptiveTrackIndexCount++] = trackFormat; adaptiveTrackFormats[adaptiveTrackIndexCount++] = trackFormat;
} }
@ -350,7 +351,8 @@ import java.util.concurrent.atomic.AtomicInteger;
} }
for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) { for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
Format trackFormat = source.getTrackGroup(groupIndex).getFormat(trackIndex); Format trackFormat = source.getTrackGroup(groupIndex).getFormat(trackIndex);
if (renderer.supportsFormat(trackFormat) == TrackRenderer.FORMAT_HANDLED) { if ((renderer.supportsFormat(trackFormat) & TrackRenderer.FORMAT_SUPPORT_MASK)
== TrackRenderer.FORMAT_HANDLED) {
rendererTrackGroups[rendererTrackCount] = groupIndex; rendererTrackGroups[rendererTrackCount] = groupIndex;
rendererTrackIndices[rendererTrackCount] = new int[] {trackIndex}; rendererTrackIndices[rendererTrackCount] = new int[] {trackIndex};
rendererTrackFormats[rendererTrackCount] = new Format[] {trackFormat}; rendererTrackFormats[rendererTrackCount] = new Format[] {trackFormat};

View file

@ -186,30 +186,26 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem
throws DecoderQueryException { throws DecoderQueryException {
String mimeType = format.sampleMimeType; String mimeType = format.sampleMimeType;
if (!MimeTypes.isAudio(mimeType)) { if (!MimeTypes.isAudio(mimeType)) {
return TrackRenderer.FORMAT_UNSUPPORTED_TYPE; return FORMAT_UNSUPPORTED_TYPE;
} }
if (allowPassthrough(mimeType) && mediaCodecSelector.getPassthroughDecoderName() != null) { if (allowPassthrough(mimeType) && mediaCodecSelector.getPassthroughDecoderName() != null) {
return TrackRenderer.FORMAT_HANDLED; return ADAPTIVE_NOT_SEAMLESS | FORMAT_HANDLED;
} }
// TODO[REFACTOR]: If requiresSecureDecryption then we should probably also check that the // TODO[REFACTOR]: If requiresSecureDecryption then we should probably also check that the
// drmSession is able to make use of a secure decoder. // drmSession is able to make use of a secure decoder.
DecoderInfo decoderInfo = mediaCodecSelector.getDecoderInfo(mimeType, DecoderInfo decoderInfo = mediaCodecSelector.getDecoderInfo(mimeType,
format.requiresSecureDecryption); format.requiresSecureDecryption);
if (decoderInfo == null) { if (decoderInfo == null) {
return TrackRenderer.FORMAT_UNSUPPORTED_TYPE; return FORMAT_UNSUPPORTED_TYPE;
} }
if (Util.SDK_INT >= 21) { // Note: We assume support for unknown sampleRate and channelCount.
// Note: We assume support in the case that the sampleRate or channelCount is unknown. boolean decoderCapable = Util.SDK_INT < 21
if (format.sampleRate != Format.NO_VALUE || ((format.sampleRate == Format.NO_VALUE
&& !decoderInfo.isAudioSampleRateSupportedV21(format.sampleRate)) { || decoderInfo.isAudioSampleRateSupportedV21(format.sampleRate))
return TrackRenderer.FORMAT_EXCEEDS_CAPABILITIES; && (format.channelCount == Format.NO_VALUE
} || decoderInfo.isAudioChannelCountSupportedV21(format.channelCount)));
if (format.channelCount != Format.NO_VALUE int formatSupport = decoderCapable ? FORMAT_HANDLED : FORMAT_EXCEEDS_CAPABILITIES;
&& !decoderInfo.isAudioChannelCountSupportedV21(format.channelCount)) { return ADAPTIVE_NOT_SEAMLESS | formatSupport;
return TrackRenderer.FORMAT_EXCEEDS_CAPABILITIES;
}
}
return TrackRenderer.FORMAT_HANDLED;
} }
@Override @Override

View file

@ -263,18 +263,8 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
} }
@Override @Override
protected final int supportsAdaptive(String mimeType) throws ExoPlaybackException { protected final int supportsMixedMimeTypeAdaptation() throws ExoPlaybackException {
if (mimeType == null) { return ADAPTIVE_NOT_SEAMLESS;
return TrackRenderer.ADAPTIVE_NOT_SEAMLESS;
}
try {
// TODO[REFACTOR]: Propagate requiresSecureDecoder to this point.
DecoderInfo decoderInfo = mediaCodecSelector.getDecoderInfo(mimeType, false);
return decoderInfo != null && decoderInfo.adaptive ? TrackRenderer.ADAPTIVE_SEAMLESS
: TrackRenderer.ADAPTIVE_NOT_SEAMLESS;
} catch (DecoderQueryException e) {
throw ExoPlaybackException.createForRenderer(e, getIndex());
}
} }
@Override @Override
@ -287,13 +277,12 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
} }
/** /**
* Returns the extent to which the renderer is capable of rendering a given format. * Returns the extent to which the renderer is capable of supporting a given format.
* *
* @param mediaCodecSelector The decoder selector. * @param mediaCodecSelector The decoder selector.
* @param format The format. * @param format The format.
* @return The extent to which the renderer is capable of rendering the given format. One of * @return The extent to which the renderer is capable of supporting the given format. See
* {@link #FORMAT_HANDLED}, {@link #FORMAT_EXCEEDS_CAPABILITIES} and * {@link #supportsFormat(Format)} for more detail.
* {@link #FORMAT_UNSUPPORTED_TYPE}.
* @throws DecoderQueryException If there was an error querying decoders. * @throws DecoderQueryException If there was an error querying decoders.
*/ */
protected abstract int supportsFormat(MediaCodecSelector mediaCodecSelector, Format format) protected abstract int supportsFormat(MediaCodecSelector mediaCodecSelector, Format format)

View file

@ -224,33 +224,38 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer {
throws DecoderQueryException { throws DecoderQueryException {
String mimeType = format.sampleMimeType; String mimeType = format.sampleMimeType;
if (!MimeTypes.isVideo(mimeType)) { if (!MimeTypes.isVideo(mimeType)) {
return TrackRenderer.FORMAT_UNSUPPORTED_TYPE; return FORMAT_UNSUPPORTED_TYPE;
} }
// TODO[REFACTOR]: If requiresSecureDecryption then we should probably also check that the // TODO[REFACTOR]: If requiresSecureDecryption then we should probably also check that the
// drmSession is able to make use of a secure decoder. // drmSession is able to make use of a secure decoder.
DecoderInfo decoderInfo = mediaCodecSelector.getDecoderInfo(mimeType, DecoderInfo decoderInfo = mediaCodecSelector.getDecoderInfo(mimeType,
format.requiresSecureDecryption); format.requiresSecureDecryption);
if (decoderInfo == null) { if (decoderInfo == null) {
return TrackRenderer.FORMAT_UNSUPPORTED_TYPE; return FORMAT_UNSUPPORTED_TYPE;
} }
boolean decoderCapable;
if (format.width > 0 && format.height > 0) { if (format.width > 0 && format.height > 0) {
if (Util.SDK_INT >= 21) { if (Util.SDK_INT >= 21) {
if (format.frameRate > 0) { if (format.frameRate > 0) {
return decoderInfo.isVideoSizeAndRateSupportedV21(format.width, format.height, decoderCapable = decoderInfo.isVideoSizeAndRateSupportedV21(format.width, format.height,
format.frameRate) ? TrackRenderer.FORMAT_HANDLED format.frameRate);
: TrackRenderer.FORMAT_EXCEEDS_CAPABILITIES;
} else { } else {
return decoderInfo.isVideoSizeSupportedV21(format.width, format.height) decoderCapable = decoderInfo.isVideoSizeSupportedV21(format.width, format.height);
? TrackRenderer.FORMAT_HANDLED : TrackRenderer.FORMAT_EXCEEDS_CAPABILITIES;
} }
} else {
// TODO[REFACTOR]: We should probably assume that we can decode at least the resolution of
// the display, or the camera, as a sanity check?
decoderCapable = format.width * format.height > MediaCodecUtil.maxH264DecodableFrameSize();
} }
// TODO[REFACTOR]: We should probably assume that we can decode at least the resolution of } else {
// the display, or the camera, as a sanity check? // We don't know any better, so assume true.
if (format.width * format.height > MediaCodecUtil.maxH264DecodableFrameSize()) { decoderCapable = true;
return TrackRenderer.FORMAT_EXCEEDS_CAPABILITIES;
}
} }
return TrackRenderer.FORMAT_HANDLED;
int adaptiveSupport = decoderInfo.adaptive ? ADAPTIVE_SEAMLESS : ADAPTIVE_NOT_SEAMLESS;
int formatSupport = decoderCapable ? FORMAT_HANDLED : FORMAT_EXCEEDS_CAPABILITIES;
return adaptiveSupport | formatSupport;
} }
@Override @Override

View file

@ -36,23 +36,15 @@ import java.io.IOException;
public abstract class TrackRenderer implements ExoPlayerComponent { public abstract class TrackRenderer implements ExoPlayerComponent {
/** /**
* The {@link TrackRenderer} can seamlessly adapt between formats. * A mask to apply to the result of {@link #supportsFormat(Format)} to obtain one of
* {@link #FORMAT_HANDLED}, {@link #FORMAT_EXCEEDS_CAPABILITIES} and
* {@link #FORMAT_UNSUPPORTED_TYPE}.
*/ */
public static final int ADAPTIVE_SEAMLESS = 0; public static final int FORMAT_SUPPORT_MASK = 0b11;
/**
* The {@link TrackRenderer} can adapt between formats, but may suffer a brief discontinuity
* (~50-100ms) when adaptation occurs.
*/
public static final int ADAPTIVE_NOT_SEAMLESS = 1;
/**
* The {@link TrackRenderer} does not support adaptation between formats.
*/
public static final int ADAPTIVE_NOT_SUPPORTED = 2;
/** /**
* The {@link TrackRenderer} is capable of rendering the format. * The {@link TrackRenderer} is capable of rendering the format.
*/ */
public static final int FORMAT_HANDLED = 0; public static final int FORMAT_HANDLED = 0b10;
/** /**
* The {@link TrackRenderer} is capable of rendering formats with the same mimeType, but the * The {@link TrackRenderer} is capable of rendering formats with the same mimeType, but the
* properties of the format exceed the renderer's capability. * properties of the format exceed the renderer's capability.
@ -61,7 +53,7 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
* {@link MimeTypes#VIDEO_H264}, but the format's resolution exceeds the maximum limit supported * {@link MimeTypes#VIDEO_H264}, but the format's resolution exceeds the maximum limit supported
* by the underlying H264 decoder. * by the underlying H264 decoder.
*/ */
public static final int FORMAT_EXCEEDS_CAPABILITIES = 1; public static final int FORMAT_EXCEEDS_CAPABILITIES = 0b01;
/** /**
* The {@link TrackRenderer} is not capable of rendering the format, or any other format with the * The {@link TrackRenderer} is not capable of rendering the format, or any other format with the
* same mimeType. * same mimeType.
@ -69,7 +61,26 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
* Example: The {@link TrackRenderer} is only capable of rendering video and the track has an * Example: The {@link TrackRenderer} is only capable of rendering video and the track has an
* audio mimeType. * audio mimeType.
*/ */
public static final int FORMAT_UNSUPPORTED_TYPE = 2; public static final int FORMAT_UNSUPPORTED_TYPE = 0b00;
/**
* 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}.
*/
public static final int ADAPTIVE_SUPPORT_MASK = 0b1100;
/**
* The {@link TrackRenderer} can seamlessly adapt between formats.
*/
public static final int ADAPTIVE_SEAMLESS = 0b1000;
/**
* The {@link TrackRenderer} can adapt between formats, but may suffer a brief discontinuity
* (~50-100ms) when adaptation occurs.
*/
public static final int ADAPTIVE_NOT_SEAMLESS = 0b0100;
/**
* The {@link TrackRenderer} does not support adaptation between formats.
*/
public static final int ADAPTIVE_NOT_SUPPORTED = 0b0000;
/** /**
* The renderer is idle. * The renderer is idle.
@ -131,28 +142,34 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
} }
/** /**
* Returns the extent to which the renderer is capable of consuming from a {@link TrackStream} * Returns the extent to which the renderer supports adapting between supported formats that have
* that adapts between multiple supported formats of a given mimeType, or of differing mimeTypes * different mimeTypes.
* if {@code mimeType == null} is passed.
* *
* @param mimeType The mimeType, or null to query the extent to which the renderer is capable of * @return The extent to which the renderer supports adapting between supported formats that have
* adapting between formats with different mimeTypes. * different mimeTypes. One of {@link #ADAPTIVE_SEAMLESS}, {@link #ADAPTIVE_NOT_SEAMLESS} and
* @return The extent to which the renderer supports the adaptation. One of
* {@link #ADAPTIVE_SEAMLESS}, {@link #ADAPTIVE_NOT_SEAMLESS} and
* {@link #ADAPTIVE_NOT_SUPPORTED}. * {@link #ADAPTIVE_NOT_SUPPORTED}.
* @throws ExoPlaybackException If an error occurs. * @throws ExoPlaybackException If an error occurs.
*/ */
protected int supportsAdaptive(String mimeType) throws ExoPlaybackException { protected int supportsMixedMimeTypeAdaptation() throws ExoPlaybackException {
return ADAPTIVE_NOT_SUPPORTED; return ADAPTIVE_NOT_SUPPORTED;
} }
/** /**
* Returns the extent to which the renderer is capable of rendering a given format. * Returns the extent to which the renderer supports a given format.
* <p>
* The returned value is the bitwise OR of two properties:
* <ul>
* <li>The level of support for the format itself. One of {@code}link #FORMAT_HANDLED},
* {@link #FORMAT_EXCEEDS_CAPABILITIES} and {@link #FORMAT_UNSUPPORTED_TYPE}.</li>
* <li>The level of support for adapting from the format to another format of the same mimeType.
* One of {@link #ADAPTIVE_SEAMLESS}, {@link #ADAPTIVE_NOT_SEAMLESS} and
* {@link #ADAPTIVE_NOT_SUPPORTED}.</li>
* </ul>
* The individual properties can be retrieved by performing a bitwise AND with
* {@link #FORMAT_SUPPORT_MASK} and {@link #ADAPTIVE_SUPPORT_MASK} respectively.
* *
* @param format The format. * @param format The format.
* @return The extent to which the renderer is capable of rendering the given format. One of * @return The extent to which the renderer is capable of supporting the given format.
* {@link #FORMAT_HANDLED}, {@link #FORMAT_EXCEEDS_CAPABILITIES} and
* {@link #FORMAT_UNSUPPORTED_TYPE}.
* @throws ExoPlaybackException If an error occurs. * @throws ExoPlaybackException If an error occurs.
*/ */
protected abstract int supportsFormat(Format format) throws ExoPlaybackException; protected abstract int supportsFormat(Format format) throws ExoPlaybackException;