Commit 7c551081 by olly Committed by Oliver Woodman

Only pass RendererCapabilities to TrackSelectors

We should only give a TrackSelector access to what it
needs, not the whole Renderer. This is particular true
if [] happens, since more Renderer methods
will become publicly visible.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=127526473
parent 97d9c94c
......@@ -20,7 +20,6 @@ import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
import com.google.android.exoplayer2.source.SampleStream;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.MediaClock;
import com.google.android.exoplayer2.util.MimeTypes;
import java.io.IOException;
......@@ -35,64 +34,7 @@ import java.io.IOException;
* alt="Renderer state transitions"
* border="0"/></p>
*/
public abstract class Renderer implements ExoPlayerComponent {
/**
* 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_SUBTYPE} and {@link #FORMAT_UNSUPPORTED_TYPE}.
*/
public static final int FORMAT_SUPPORT_MASK = 0b11;
/**
* The {@link Renderer} is capable of rendering the format.
*/
public static final int FORMAT_HANDLED = 0b11;
/**
* The {@link Renderer} is capable of rendering formats with the same mimeType, but the
* properties of the format exceed the renderer's capability.
* <p>
* Example: The {@link Renderer} is capable of rendering H264 and the format's mimeType is
* {@link MimeTypes#VIDEO_H264}, but the format's resolution exceeds the maximum limit supported
* by the underlying H264 decoder.
*/
public static final int FORMAT_EXCEEDS_CAPABILITIES = 0b10;
/**
* The {@link Renderer} is a general purpose renderer for formats of the same top-level type,
* but is not capable of rendering the format or any other format with the same mimeType because
* the sub-type is not supported.
* <p>
* Example: The {@link Renderer} is a general purpose audio renderer and the format's
* mimeType matches audio/[subtype], but there does not exist a suitable decoder for [subtype].
*/
public static final int FORMAT_UNSUPPORTED_SUBTYPE = 0b01;
/**
* The {@link Renderer} is not capable of rendering the format, either because it does not
* support the format's top-level type, or because it's a specialized renderer for a different
* mimeType.
* <p>
* Example: The {@link Renderer} is a general purpose video renderer, but the format has an
* audio mimeType.
*/
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 Renderer} can seamlessly adapt between formats.
*/
public static final int ADAPTIVE_SEAMLESS = 0b1000;
/**
* The {@link Renderer} 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 Renderer} does not support adaptation between formats.
*/
public static final int ADAPTIVE_NOT_SUPPORTED = 0b0000;
public abstract class Renderer implements ExoPlayerComponent, RendererCapabilities {
/**
* The renderer is disabled.
......@@ -159,19 +101,6 @@ public abstract class Renderer implements ExoPlayerComponent {
}
/**
* Returns the extent to which the renderer supports adapting between supported formats that have
* different mimeTypes.
*
* @return The extent to which the renderer supports adapting between supported formats that have
* different mimeTypes. One of {@link #ADAPTIVE_SEAMLESS}, {@link #ADAPTIVE_NOT_SEAMLESS} and
* {@link #ADAPTIVE_NOT_SUPPORTED}.
* @throws ExoPlaybackException If an error occurs.
*/
public int supportsMixedMimeTypeAdaptation() throws ExoPlaybackException {
return ADAPTIVE_NOT_SUPPORTED;
}
/**
* Enable the renderer to consume from the specified {@link SampleStream}.
*
* @param formats The enabled formats.
......@@ -383,36 +312,6 @@ public abstract class Renderer implements ExoPlayerComponent {
// Abstract methods.
/**
* Returns the track type that the 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 text
* renderer will return {@link C#TRACK_TYPE_TEXT}, and so on.
*
* @return One of the {@code TRACK_TYPE_*} constants defined in {@link C}.
*/
public abstract int getTrackType();
/**
* 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}, {@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 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.
* @return The extent to which the renderer is capable of supporting the given format.
* @throws ExoPlaybackException If an error occurs.
*/
public abstract int supportsFormat(Format format) throws ExoPlaybackException;
/**
* Incrementally renders the {@link SampleStream}.
* <p>
* This method should return quickly, and should not block if the renderer is unable to make
......@@ -459,6 +358,13 @@ public abstract class Renderer implements ExoPlayerComponent {
*/
protected abstract boolean isEnded();
// RendererCapabilities implementation
@Override
public int supportsMixedMimeTypeAdaptation() throws ExoPlaybackException {
return ADAPTIVE_NOT_SUPPORTED;
}
// ExoPlayerComponent implementation.
@Override
......
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2;
import com.google.android.exoplayer2.util.MimeTypes;
/**
* Defines the capabilities of a {@link Renderer}.
*/
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_SUBTYPE} and {@link #FORMAT_UNSUPPORTED_TYPE}.
*/
int FORMAT_SUPPORT_MASK = 0b11;
/**
* The {@link Renderer} is capable of rendering the format.
*/
int FORMAT_HANDLED = 0b11;
/**
* The {@link Renderer} is capable of rendering formats with the same mimeType, but the
* properties of the format exceed the renderer's capability.
* <p>
* Example: The {@link Renderer} is capable of rendering H264 and the format's mimeType is
* {@link MimeTypes#VIDEO_H264}, but the format's resolution exceeds the maximum limit supported
* by the underlying H264 decoder.
*/
int FORMAT_EXCEEDS_CAPABILITIES = 0b10;
/**
* The {@link Renderer} is a general purpose renderer for formats of the same top-level type,
* but is not capable of rendering the format or any other format with the same mimeType because
* the sub-type is not supported.
* <p>
* Example: The {@link Renderer} is a general purpose audio renderer and the format's
* mimeType matches audio/[subtype], but there does not exist a suitable decoder for [subtype].
*/
int FORMAT_UNSUPPORTED_SUBTYPE = 0b01;
/**
* The {@link Renderer} is not capable of rendering the format, either because it does not
* support the format's top-level type, or because it's a specialized renderer for a different
* mimeType.
* <p>
* Example: The {@link Renderer} is a general purpose video renderer, but the format has an
* audio mimeType.
*/
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}.
*/
int ADAPTIVE_SUPPORT_MASK = 0b1100;
/**
* The {@link Renderer} can seamlessly adapt between formats.
*/
int ADAPTIVE_SEAMLESS = 0b1000;
/**
* The {@link Renderer} can adapt between formats, but may suffer a brief discontinuity
* (~50-100ms) when adaptation occurs.
*/
int ADAPTIVE_NOT_SEAMLESS = 0b0100;
/**
* The {@link Renderer} does not support adaptation between formats.
*/
int ADAPTIVE_NOT_SUPPORTED = 0b0000;
/**
* 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
* text renderer will return {@link C#TRACK_TYPE_TEXT}, and so on.
*
* @return One of the {@code TRACK_TYPE_*} constants defined in {@link C}.
*/
int getTrackType();
/**
* Returns the extent to which the {@link 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}, {@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 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.
* @return The extent to which the renderer is capable of supporting the given format.
* @throws ExoPlaybackException If an error occurs.
*/
int supportsFormat(Format format) throws ExoPlaybackException;
/**
* Returns the extent to which the {@link Renderer} supports adapting between supported formats
* that have different mimeTypes.
*
* @return The extent to which the renderer supports adapting between supported formats that have
* different mimeTypes. One of {@link #ADAPTIVE_SEAMLESS}, {@link #ADAPTIVE_NOT_SEAMLESS} and
* {@link #ADAPTIVE_NOT_SUPPORTED}.
* @throws ExoPlaybackException If an error occurs.
*/
int supportsMixedMimeTypeAdaptation() throws ExoPlaybackException;
}
......@@ -18,7 +18,7 @@ package com.google.android.exoplayer2.trackselection;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.RendererCapabilities;
import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.util.Util;
......@@ -131,15 +131,15 @@ public class DefaultTrackSelector extends MappingTrackSelector {
// TrackSelectionPolicy implementation.
@Override
protected TrackSelection[] selectTracks(Renderer[] renderers,
protected TrackSelection[] selectTracks(RendererCapabilities[] rendererCapabilities,
TrackGroupArray[] rendererTrackGroupArrays, int[][][] rendererFormatSupports)
throws ExoPlaybackException {
// Make a track selection for each renderer.
TrackSelection[] rendererTrackSelections = new TrackSelection[renderers.length];
for (int i = 0; i < renderers.length; i++) {
switch (renderers[i].getTrackType()) {
TrackSelection[] rendererTrackSelections = new TrackSelection[rendererCapabilities.length];
for (int i = 0; i < rendererCapabilities.length; i++) {
switch (rendererCapabilities[i].getTrackType()) {
case C.TRACK_TYPE_VIDEO:
rendererTrackSelections[i] = selectTrackForVideoRenderer(renderers[i],
rendererTrackSelections[i] = selectTrackForVideoRenderer(rendererCapabilities[i],
rendererTrackGroupArrays[i], rendererFormatSupports[i], maxVideoWidth, maxVideoHeight,
allowNonSeamlessAdaptiveness, allowMixedMimeAdaptiveness);
if (rendererTrackSelections[i] == null && exceedVideoConstraintsIfNecessary) {
......@@ -166,15 +166,16 @@ public class DefaultTrackSelector extends MappingTrackSelector {
// Video track selection implementation.
private static TrackSelection selectTrackForVideoRenderer(Renderer renderer,
TrackGroupArray trackGroups, int[][] formatSupport, int maxVideoWidth, int maxVideoHeight,
private static TrackSelection selectTrackForVideoRenderer(
RendererCapabilities rendererCapabilities, TrackGroupArray trackGroups,
int[][] formatSupport, int maxVideoWidth, int maxVideoHeight,
boolean allowNonSeamlessAdaptiveness, boolean allowMixedMimeAdaptiveness)
throws ExoPlaybackException {
int requiredAdaptiveSupport = allowNonSeamlessAdaptiveness
? (Renderer.ADAPTIVE_NOT_SEAMLESS | Renderer.ADAPTIVE_SEAMLESS)
: Renderer.ADAPTIVE_SEAMLESS;
? (RendererCapabilities.ADAPTIVE_NOT_SEAMLESS | RendererCapabilities.ADAPTIVE_SEAMLESS)
: RendererCapabilities.ADAPTIVE_SEAMLESS;
boolean allowMixedMimeTypes = allowMixedMimeAdaptiveness
&& (renderer.supportsMixedMimeTypeAdaptation() & requiredAdaptiveSupport) != 0;
&& (rendererCapabilities.supportsMixedMimeTypeAdaptation() & requiredAdaptiveSupport) != 0;
int largestAdaptiveGroup = -1;
int[] largestAdaptiveGroupTracks = NO_TRACKS;
for (int i = 0; i < trackGroups.length; i++) {
......@@ -356,7 +357,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
}
private static boolean isSupported(int formatSupport) {
return (formatSupport & Renderer.FORMAT_SUPPORT_MASK) == Renderer.FORMAT_HANDLED;
return (formatSupport & RendererCapabilities.FORMAT_SUPPORT_MASK)
== RendererCapabilities.FORMAT_HANDLED;
}
private static boolean formatHasLanguage(Format format, String language) {
......
......@@ -16,13 +16,13 @@
package com.google.android.exoplayer2.trackselection;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.RendererCapabilities;
import com.google.android.exoplayer2.source.TrackGroupArray;
import android.util.Pair;
/**
* Selects tracks to be consumed by available {@link Renderer}s.
* Selects tracks to be consumed by available renderers.
*/
public abstract class TrackSelector {
......@@ -56,19 +56,21 @@ public abstract class TrackSelector {
* that the selector wishes to receive in an invocation of {@link #onSelectionActivated(Object)}
* should the selection be activated.
*
* @param renderers The renderers.
* @param rendererCapabilities The {@link RendererCapabilities} of the renderers for which
* {@link TrackSelection}s are to be generated.
* @param trackGroups The available track groups.
* @return A {@link TrackSelectionArray} containing a {@link TrackSelection} for each renderer,
* together with an opaque object that will be passed to {@link #onSelectionActivated(Object)}
* if the selection is activated.
* @throws ExoPlaybackException If an error occurs selecting tracks.
*/
public abstract Pair<TrackSelectionArray, Object> selectTracks(Renderer[] renderers,
TrackGroupArray trackGroups) throws ExoPlaybackException;
public abstract Pair<TrackSelectionArray, Object> selectTracks(
RendererCapabilities[] rendererCapabilities, TrackGroupArray trackGroups)
throws ExoPlaybackException;
/**
* Invoked when a selection previously generated by
* {@link #selectTracks(Renderer[], TrackGroupArray)} is activated.
* {@link #selectTracks(RendererCapabilities[], TrackGroupArray)} is activated.
*
* @param selectionInfo The opaque object associated with the selection.
*/
......
......@@ -19,6 +19,7 @@ import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.RendererCapabilities;
import com.google.android.exoplayer2.decoder.DecoderCounters;
import com.google.android.exoplayer2.mediacodec.MediaCodecInfo;
import com.google.android.exoplayer2.mediacodec.MediaCodecUtil;
......@@ -44,7 +45,6 @@ import android.annotation.TargetApi;
import android.net.Uri;
import android.test.ActivityInstrumentationTestCase2;
import android.util.Log;
import junit.framework.AssertionFailedError;
import java.util.ArrayList;
......@@ -492,14 +492,16 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
}
@Override
protected TrackSelection[] selectTracks(Renderer[] renderers,
protected TrackSelection[] selectTracks(RendererCapabilities[] rendererCapabilities,
TrackGroupArray[] rendererTrackGroupArrays, int[][][] rendererFormatSupports)
throws ExoPlaybackException {
Assertions.checkState(renderers[VIDEO_RENDERER_INDEX].getTrackType() == C.TRACK_TYPE_VIDEO);
Assertions.checkState(renderers[AUDIO_RENDERER_INDEX].getTrackType() == C.TRACK_TYPE_AUDIO);
Assertions.checkState(rendererCapabilities[VIDEO_RENDERER_INDEX].getTrackType()
== C.TRACK_TYPE_VIDEO);
Assertions.checkState(rendererCapabilities[AUDIO_RENDERER_INDEX].getTrackType()
== C.TRACK_TYPE_AUDIO);
Assertions.checkState(rendererTrackGroupArrays[VIDEO_RENDERER_INDEX].length == 1);
Assertions.checkState(rendererTrackGroupArrays[AUDIO_RENDERER_INDEX].length == 1);
TrackSelection[] selections = new TrackSelection[renderers.length];
TrackSelection[] selections = new TrackSelection[rendererCapabilities.length];
selections[VIDEO_RENDERER_INDEX] = new TrackSelection(0,
getTrackIndices(rendererTrackGroupArrays[VIDEO_RENDERER_INDEX].get(0),
rendererFormatSupports[VIDEO_RENDERER_INDEX][0], videoFormatIds,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment