Fix track selection nullability issues.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=199266768
This commit is contained in:
tonihei 2018-06-05 02:30:25 -07:00 committed by Oliver Woodman
parent 6a82f99ca1
commit 3c6ca19c85
12 changed files with 130 additions and 96 deletions

View File

@ -54,6 +54,7 @@ android {
dependencies { dependencies {
implementation 'com.android.support:support-annotations:' + supportLibraryVersion implementation 'com.android.support:support-annotations:' + supportLibraryVersion
compileOnly 'org.checkerframework:checker-qual:' + checkerframeworkVersion compileOnly 'org.checkerframework:checker-qual:' + checkerframeworkVersion
compileOnly 'org.checkerframework:checker-compat-qual:' + checkerframeworkVersion
androidTestImplementation 'com.google.dexmaker:dexmaker:' + dexmakerVersion androidTestImplementation 'com.google.dexmaker:dexmaker:' + dexmakerVersion
androidTestImplementation 'com.google.dexmaker:dexmaker-mockito:' + dexmakerVersion androidTestImplementation 'com.google.dexmaker:dexmaker-mockito:' + dexmakerVersion
androidTestImplementation 'com.google.truth:truth:' + truthVersion androidTestImplementation 'com.google.truth:truth:' + truthVersion

View File

@ -15,6 +15,7 @@
*/ */
package com.google.android.exoplayer2.trackselection; package com.google.android.exoplayer2.trackselection;
import android.support.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.source.TrackGroup; import com.google.android.exoplayer2.source.TrackGroup;
@ -242,9 +243,11 @@ public class AdaptiveTrackSelection extends BaseTrackSelection {
this.minTimeBetweenBufferReevaluationMs = minTimeBetweenBufferReevaluationMs; this.minTimeBetweenBufferReevaluationMs = minTimeBetweenBufferReevaluationMs;
this.clock = clock; this.clock = clock;
playbackSpeed = 1f; playbackSpeed = 1f;
selectedIndex = determineIdealSelectedIndex(Long.MIN_VALUE);
reason = C.SELECTION_REASON_INITIAL; reason = C.SELECTION_REASON_INITIAL;
lastBufferEvaluationMs = C.TIME_UNSET; lastBufferEvaluationMs = C.TIME_UNSET;
@SuppressWarnings("nullness:method.invocation.invalid")
int selectedIndex = determineIdealSelectedIndex(Long.MIN_VALUE);
this.selectedIndex = selectedIndex;
} }
@Override @Override
@ -301,7 +304,7 @@ public class AdaptiveTrackSelection extends BaseTrackSelection {
} }
@Override @Override
public Object getSelectionData() { public @Nullable Object getSelectionData() {
return null; return null;
} }

View File

@ -19,7 +19,6 @@ import android.content.Context;
import android.graphics.Point; import android.graphics.Point;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Pair; import android.util.Pair;
@ -44,6 +43,7 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import org.checkerframework.checker.nullness.compatqual.NullableType;
/** /**
* A default {@link TrackSelector} suitable for most use cases. Track selections are made according * A default {@link TrackSelector} suitable for most use cases. Track selections are made according
@ -161,8 +161,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
private final SparseArray<Map<TrackGroupArray, SelectionOverride>> selectionOverrides; private final SparseArray<Map<TrackGroupArray, SelectionOverride>> selectionOverrides;
private final SparseBooleanArray rendererDisabledFlags; private final SparseBooleanArray rendererDisabledFlags;
private String preferredAudioLanguage; private @Nullable String preferredAudioLanguage;
private String preferredTextLanguage; private @Nullable String preferredTextLanguage;
private boolean selectUndeterminedTextLanguage; private boolean selectUndeterminedTextLanguage;
private int disabledTextTrackSelectionFlags; private int disabledTextTrackSelectionFlags;
private boolean forceLowestBitrate; private boolean forceLowestBitrate;
@ -572,14 +572,14 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* The preferred language for audio, as well as for forced text tracks, as an ISO 639-2/T tag. * The preferred language for audio, as well as for forced text tracks, as an ISO 639-2/T tag.
* {@code null} selects the default track, or the first track if there's no default. * {@code null} selects the default track, or the first track if there's no default.
*/ */
public final String preferredAudioLanguage; public final @Nullable String preferredAudioLanguage;
// Text // Text
/** /**
* The preferred language for text tracks as an ISO 639-2/T tag. {@code null} selects the * The preferred language for text tracks as an ISO 639-2/T tag. {@code null} selects the
* default track if there is one, or no track otherwise. * default track if there is one, or no track otherwise.
*/ */
public final String preferredTextLanguage; public final @Nullable String preferredTextLanguage;
/** /**
* Whether a text track with undetermined language should be selected if no track with * Whether a text track with undetermined language should be selected if no track with
* {@link #preferredTextLanguage} is available, or if {@link #preferredTextLanguage} is unset. * {@link #preferredTextLanguage} is available, or if {@link #preferredTextLanguage} is unset.
@ -673,8 +673,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
/* package */ Parameters( /* package */ Parameters(
SparseArray<Map<TrackGroupArray, SelectionOverride>> selectionOverrides, SparseArray<Map<TrackGroupArray, SelectionOverride>> selectionOverrides,
SparseBooleanArray rendererDisabledFlags, SparseBooleanArray rendererDisabledFlags,
String preferredAudioLanguage, @Nullable String preferredAudioLanguage,
String preferredTextLanguage, @Nullable String preferredTextLanguage,
boolean selectUndeterminedTextLanguage, boolean selectUndeterminedTextLanguage,
int disabledTextTrackSelectionFlags, int disabledTextTrackSelectionFlags,
boolean forceLowestBitrate, boolean forceLowestBitrate,
@ -759,7 +759,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* @param groups The {@link TrackGroupArray}. * @param groups The {@link TrackGroupArray}.
* @return The override, or null if no override exists. * @return The override, or null if no override exists.
*/ */
public final SelectionOverride getSelectionOverride(int rendererIndex, TrackGroupArray groups) { public final @Nullable SelectionOverride getSelectionOverride(
int rendererIndex, TrackGroupArray groups) {
Map<TrackGroupArray, SelectionOverride> overrides = selectionOverrides.get(rendererIndex); Map<TrackGroupArray, SelectionOverride> overrides = selectionOverrides.get(rendererIndex);
return overrides != null ? overrides.get(groups) : null; return overrides != null ? overrides.get(groups) : null;
} }
@ -816,8 +817,9 @@ public class DefaultTrackSelector extends MappingTrackSelector {
result = 31 * result + viewportHeight; result = 31 * result + viewportHeight;
result = 31 * result + maxVideoBitrate; result = 31 * result + maxVideoBitrate;
result = 31 * result + tunnelingAudioSessionId; result = 31 * result + tunnelingAudioSessionId;
result = 31 * result + preferredAudioLanguage.hashCode(); result =
result = 31 * result + preferredTextLanguage.hashCode(); 31 * result + (preferredAudioLanguage == null ? 0 : preferredAudioLanguage.hashCode());
result = 31 * result + (preferredTextLanguage == null ? 0 : preferredTextLanguage.hashCode());
return result; return result;
} }
@ -1042,7 +1044,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
private static final int[] NO_TRACKS = new int[0]; private static final int[] NO_TRACKS = new int[0];
private static final int WITHIN_RENDERER_CAPABILITIES_BONUS = 1000; private static final int WITHIN_RENDERER_CAPABILITIES_BONUS = 1000;
private final TrackSelection.Factory adaptiveTrackSelectionFactory; private final @Nullable TrackSelection.Factory adaptiveTrackSelectionFactory;
private final AtomicReference<Parameters> parametersReference; private final AtomicReference<Parameters> parametersReference;
/** /**
@ -1069,7 +1071,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* @param adaptiveTrackSelectionFactory A factory for adaptive {@link TrackSelection}s, or null if * @param adaptiveTrackSelectionFactory A factory for adaptive {@link TrackSelection}s, or null if
* the selector should not support adaptive tracks. * the selector should not support adaptive tracks.
*/ */
public DefaultTrackSelector(TrackSelection.Factory adaptiveTrackSelectionFactory) { public DefaultTrackSelector(@Nullable TrackSelection.Factory adaptiveTrackSelectionFactory) {
this.adaptiveTrackSelectionFactory = adaptiveTrackSelectionFactory; this.adaptiveTrackSelectionFactory = adaptiveTrackSelectionFactory;
parametersReference = new AtomicReference<>(Parameters.DEFAULT); parametersReference = new AtomicReference<>(Parameters.DEFAULT);
} }
@ -1139,7 +1141,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
/** @deprecated Use {@link Parameters#getSelectionOverride(int, TrackGroupArray)}. */ /** @deprecated Use {@link Parameters#getSelectionOverride(int, TrackGroupArray)}. */
@Deprecated @Deprecated
public final SelectionOverride getSelectionOverride(int rendererIndex, TrackGroupArray groups) { public final @Nullable SelectionOverride getSelectionOverride(
int rendererIndex, TrackGroupArray groups) {
return getParameters().getSelectionOverride(rendererIndex, groups); return getParameters().getSelectionOverride(rendererIndex, groups);
} }
@ -1170,14 +1173,15 @@ public class DefaultTrackSelector extends MappingTrackSelector {
// MappingTrackSelector implementation. // MappingTrackSelector implementation.
@Override @Override
protected final Pair<RendererConfiguration[], TrackSelection[]> selectTracks( protected final Pair<@NullableType RendererConfiguration[], @NullableType TrackSelection[]>
selectTracks(
MappedTrackInfo mappedTrackInfo, MappedTrackInfo mappedTrackInfo,
int[][][] rendererFormatSupports, int[][][] rendererFormatSupports,
int[] rendererMixedMimeTypeAdaptationSupports) int[] rendererMixedMimeTypeAdaptationSupports)
throws ExoPlaybackException { throws ExoPlaybackException {
Parameters params = parametersReference.get(); Parameters params = parametersReference.get();
int rendererCount = mappedTrackInfo.getRendererCount(); int rendererCount = mappedTrackInfo.getRendererCount();
TrackSelection[] rendererTrackSelections = @NullableType TrackSelection[] rendererTrackSelections =
selectAllTracks( selectAllTracks(
mappedTrackInfo, mappedTrackInfo,
rendererFormatSupports, rendererFormatSupports,
@ -1200,7 +1204,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
rendererTrackGroups.get(override.groupIndex), override.tracks[0]); rendererTrackGroups.get(override.groupIndex), override.tracks[0]);
} else { } else {
rendererTrackSelections[i] = rendererTrackSelections[i] =
adaptiveTrackSelectionFactory.createTrackSelection( Assertions.checkNotNull(adaptiveTrackSelectionFactory)
.createTrackSelection(
rendererTrackGroups.get(override.groupIndex), override.tracks); rendererTrackGroups.get(override.groupIndex), override.tracks);
} }
} }
@ -1209,7 +1214,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
// Initialize the renderer configurations to the default configuration for all renderers with // Initialize the renderer configurations to the default configuration for all renderers with
// selections, and null otherwise. // selections, and null otherwise.
RendererConfiguration[] rendererConfigurations = new RendererConfiguration[rendererCount]; @NullableType RendererConfiguration[] rendererConfigurations =
new RendererConfiguration[rendererCount];
for (int i = 0; i < rendererCount; i++) { for (int i = 0; i < rendererCount; i++) {
boolean forceRendererDisabled = params.getRendererDisabled(i); boolean forceRendererDisabled = params.getRendererDisabled(i);
boolean rendererEnabled = boolean rendererEnabled =
@ -1248,14 +1254,14 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* disabled, unless RendererCapabilities#getTrackType()} is {@link C#TRACK_TYPE_NONE}. * disabled, unless RendererCapabilities#getTrackType()} is {@link C#TRACK_TYPE_NONE}.
* @throws ExoPlaybackException If an error occurs while selecting the tracks. * @throws ExoPlaybackException If an error occurs while selecting the tracks.
*/ */
protected TrackSelection[] selectAllTracks( protected @NullableType TrackSelection[] selectAllTracks(
MappedTrackInfo mappedTrackInfo, MappedTrackInfo mappedTrackInfo,
int[][][] rendererFormatSupports, int[][][] rendererFormatSupports,
int[] rendererMixedMimeTypeAdaptationSupports, int[] rendererMixedMimeTypeAdaptationSupports,
Parameters params) Parameters params)
throws ExoPlaybackException { throws ExoPlaybackException {
int rendererCount = mappedTrackInfo.getRendererCount(); int rendererCount = mappedTrackInfo.getRendererCount();
TrackSelection[] rendererTrackSelections = new TrackSelection[rendererCount]; @NullableType TrackSelection[] rendererTrackSelections = new TrackSelection[rendererCount];
boolean seenVideoRendererWithMappedTracks = false; boolean seenVideoRendererWithMappedTracks = false;
boolean selectedVideoTracks = false; boolean selectedVideoTracks = false;
@ -1331,12 +1337,12 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* @return The {@link TrackSelection} for the renderer, or null if no selection was made. * @return The {@link TrackSelection} for the renderer, or null if no selection was made.
* @throws ExoPlaybackException If an error occurs while selecting the tracks. * @throws ExoPlaybackException If an error occurs while selecting the tracks.
*/ */
protected TrackSelection selectVideoTrack( protected @Nullable TrackSelection selectVideoTrack(
TrackGroupArray groups, TrackGroupArray groups,
int[][] formatSupports, int[][] formatSupports,
int mixedMimeTypeAdaptationSupports, int mixedMimeTypeAdaptationSupports,
Parameters params, Parameters params,
TrackSelection.Factory adaptiveTrackSelectionFactory) @Nullable TrackSelection.Factory adaptiveTrackSelectionFactory)
throws ExoPlaybackException { throws ExoPlaybackException {
TrackSelection selection = null; TrackSelection selection = null;
if (!params.forceLowestBitrate && adaptiveTrackSelectionFactory != null) { if (!params.forceLowestBitrate && adaptiveTrackSelectionFactory != null) {
@ -1354,7 +1360,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
return selection; return selection;
} }
private static TrackSelection selectAdaptiveVideoTrack( private static @Nullable TrackSelection selectAdaptiveVideoTrack(
TrackGroupArray groups, TrackGroupArray groups,
int[][] formatSupport, int[][] formatSupport,
int mixedMimeTypeAdaptationSupports, int mixedMimeTypeAdaptationSupports,
@ -1374,7 +1380,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
params.maxVideoBitrate, params.viewportWidth, params.viewportHeight, params.maxVideoBitrate, params.viewportWidth, params.viewportHeight,
params.viewportOrientationMayChange); params.viewportOrientationMayChange);
if (adaptiveTracks.length > 0) { if (adaptiveTracks.length > 0) {
return adaptiveTrackSelectionFactory.createTrackSelection(group, adaptiveTracks); return Assertions.checkNotNull(adaptiveTrackSelectionFactory)
.createTrackSelection(group, adaptiveTracks);
} }
} }
return null; return null;
@ -1397,7 +1404,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
String selectedMimeType = null; String selectedMimeType = null;
if (!allowMixedMimeTypes) { if (!allowMixedMimeTypes) {
// Select the mime type for which we have the most adaptive tracks. // Select the mime type for which we have the most adaptive tracks.
HashSet<String> seenMimeTypes = new HashSet<>(); HashSet<@NullableType String> seenMimeTypes = new HashSet<>();
int selectedMimeTypeTrackCount = 0; int selectedMimeTypeTrackCount = 0;
for (int i = 0; i < selectedTrackIndices.size(); i++) { for (int i = 0; i < selectedTrackIndices.size(); i++) {
int trackIndex = selectedTrackIndices.get(i); int trackIndex = selectedTrackIndices.get(i);
@ -1421,9 +1428,15 @@ public class DefaultTrackSelector extends MappingTrackSelector {
return selectedTrackIndices.size() < 2 ? NO_TRACKS : Util.toArray(selectedTrackIndices); return selectedTrackIndices.size() < 2 ? NO_TRACKS : Util.toArray(selectedTrackIndices);
} }
private static int getAdaptiveVideoTrackCountForMimeType(TrackGroup group, int[] formatSupport, private static int getAdaptiveVideoTrackCountForMimeType(
int requiredAdaptiveSupport, String mimeType, int maxVideoWidth, int maxVideoHeight, TrackGroup group,
int maxVideoBitrate, List<Integer> selectedTrackIndices) { int[] formatSupport,
int requiredAdaptiveSupport,
@Nullable String mimeType,
int maxVideoWidth,
int maxVideoHeight,
int maxVideoBitrate,
List<Integer> selectedTrackIndices) {
int adaptiveTrackCount = 0; int adaptiveTrackCount = 0;
for (int i = 0; i < selectedTrackIndices.size(); i++) { for (int i = 0; i < selectedTrackIndices.size(); i++) {
int trackIndex = selectedTrackIndices.get(i); int trackIndex = selectedTrackIndices.get(i);
@ -1436,9 +1449,15 @@ public class DefaultTrackSelector extends MappingTrackSelector {
return adaptiveTrackCount; return adaptiveTrackCount;
} }
private static void filterAdaptiveVideoTrackCountForMimeType(TrackGroup group, private static void filterAdaptiveVideoTrackCountForMimeType(
int[] formatSupport, int requiredAdaptiveSupport, String mimeType, int maxVideoWidth, TrackGroup group,
int maxVideoHeight, int maxVideoBitrate, List<Integer> selectedTrackIndices) { int[] formatSupport,
int requiredAdaptiveSupport,
@Nullable String mimeType,
int maxVideoWidth,
int maxVideoHeight,
int maxVideoBitrate,
List<Integer> selectedTrackIndices) {
for (int i = selectedTrackIndices.size() - 1; i >= 0; i--) { for (int i = selectedTrackIndices.size() - 1; i >= 0; i--) {
int trackIndex = selectedTrackIndices.get(i); int trackIndex = selectedTrackIndices.get(i);
if (!isSupportedAdaptiveVideoTrack(group.getFormat(trackIndex), mimeType, if (!isSupportedAdaptiveVideoTrack(group.getFormat(trackIndex), mimeType,
@ -1449,8 +1468,13 @@ public class DefaultTrackSelector extends MappingTrackSelector {
} }
} }
private static boolean isSupportedAdaptiveVideoTrack(Format format, String mimeType, private static boolean isSupportedAdaptiveVideoTrack(
int formatSupport, int requiredAdaptiveSupport, int maxVideoWidth, int maxVideoHeight, Format format,
@Nullable String mimeType,
int formatSupport,
int requiredAdaptiveSupport,
int maxVideoWidth,
int maxVideoHeight,
int maxVideoBitrate) { int maxVideoBitrate) {
return isSupported(formatSupport, false) && ((formatSupport & requiredAdaptiveSupport) != 0) return isSupported(formatSupport, false) && ((formatSupport & requiredAdaptiveSupport) != 0)
&& (mimeType == null || Util.areEqual(format.sampleMimeType, mimeType)) && (mimeType == null || Util.areEqual(format.sampleMimeType, mimeType))
@ -1459,7 +1483,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
&& (format.bitrate == Format.NO_VALUE || format.bitrate <= maxVideoBitrate); && (format.bitrate == Format.NO_VALUE || format.bitrate <= maxVideoBitrate);
} }
private static TrackSelection selectFixedVideoTrack( private static @Nullable TrackSelection selectFixedVideoTrack(
TrackGroupArray groups, int[][] formatSupports, Parameters params) { TrackGroupArray groups, int[][] formatSupports, Parameters params) {
TrackGroup selectedGroup = null; TrackGroup selectedGroup = null;
int selectedTrackIndex = 0; int selectedTrackIndex = 0;
@ -1537,12 +1561,12 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* @return The {@link TrackSelection} for the renderer, or null if no selection was made. * @return The {@link TrackSelection} for the renderer, or null if no selection was made.
* @throws ExoPlaybackException If an error occurs while selecting the tracks. * @throws ExoPlaybackException If an error occurs while selecting the tracks.
*/ */
protected TrackSelection selectAudioTrack( protected @Nullable TrackSelection selectAudioTrack(
TrackGroupArray groups, TrackGroupArray groups,
int[][] formatSupports, int[][] formatSupports,
int mixedMimeTypeAdaptationSupports, int mixedMimeTypeAdaptationSupports,
Parameters params, Parameters params,
TrackSelection.Factory adaptiveTrackSelectionFactory) @Nullable TrackSelection.Factory adaptiveTrackSelectionFactory)
throws ExoPlaybackException { throws ExoPlaybackException {
int selectedTrackIndex = C.INDEX_UNSET; int selectedTrackIndex = C.INDEX_UNSET;
int selectedGroupIndex = C.INDEX_UNSET; int selectedGroupIndex = C.INDEX_UNSET;
@ -1606,8 +1630,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
int[] adaptiveIndices = new int[selectedConfigurationTrackCount]; int[] adaptiveIndices = new int[selectedConfigurationTrackCount];
int index = 0; int index = 0;
for (int i = 0; i < group.length; i++) { for (int i = 0; i < group.length; i++) {
if (isSupportedAdaptiveAudioTrack(group.getFormat(i), formatSupport[i], if (isSupportedAdaptiveAudioTrack(
selectedConfiguration)) { group.getFormat(i), formatSupport[i], Assertions.checkNotNull(selectedConfiguration))) {
adaptiveIndices[index++] = i; adaptiveIndices[index++] = i;
} }
} }
@ -1648,7 +1672,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* @return The {@link TrackSelection} for the renderer, or null if no selection was made. * @return The {@link TrackSelection} for the renderer, or null if no selection was made.
* @throws ExoPlaybackException If an error occurs while selecting the tracks. * @throws ExoPlaybackException If an error occurs while selecting the tracks.
*/ */
protected TrackSelection selectTextTrack( protected @Nullable TrackSelection selectTextTrack(
TrackGroupArray groups, int[][] formatSupport, Parameters params) TrackGroupArray groups, int[][] formatSupport, Parameters params)
throws ExoPlaybackException { throws ExoPlaybackException {
TrackGroup selectedGroup = null; TrackGroup selectedGroup = null;
@ -1721,7 +1745,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* @return The {@link TrackSelection} for the renderer, or null if no selection was made. * @return The {@link TrackSelection} for the renderer, or null if no selection was made.
* @throws ExoPlaybackException If an error occurs while selecting the tracks. * @throws ExoPlaybackException If an error occurs while selecting the tracks.
*/ */
protected TrackSelection selectOtherTrack( protected @Nullable TrackSelection selectOtherTrack(
int trackType, TrackGroupArray groups, int[][] formatSupport, Parameters params) int trackType, TrackGroupArray groups, int[][] formatSupport, Parameters params)
throws ExoPlaybackException { throws ExoPlaybackException {
TrackGroup selectedGroup = null; TrackGroup selectedGroup = null;
@ -1768,8 +1792,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
private static void maybeConfigureRenderersForTunneling( private static void maybeConfigureRenderersForTunneling(
MappedTrackInfo mappedTrackInfo, MappedTrackInfo mappedTrackInfo,
int[][][] renderererFormatSupports, int[][][] renderererFormatSupports,
RendererConfiguration[] rendererConfigurations, @NullableType RendererConfiguration[] rendererConfigurations,
TrackSelection[] trackSelections, @NullableType TrackSelection[] trackSelections,
int tunnelingAudioSessionId) { int tunnelingAudioSessionId) {
if (tunnelingAudioSessionId == C.AUDIO_SESSION_ID_UNSET) { if (tunnelingAudioSessionId == C.AUDIO_SESSION_ID_UNSET) {
return; return;
@ -1883,15 +1907,15 @@ public class DefaultTrackSelector extends MappingTrackSelector {
} }
/** /**
* Returns whether a {@link Format} specifies a particular language, or {@code false} if * Returns whether a {@link Format} specifies a particular language, or {@code false} if {@code
* {@code language} is null. * language} is null.
* *
* @param format The {@link Format}. * @param format The {@link Format}.
* @param language The language. * @param language The language.
* @return Whether the format specifies the language, or {@code false} if {@code language} is * @return Whether the format specifies the language, or {@code false} if {@code language} is
* null. * null.
*/ */
protected static boolean formatHasLanguage(Format format, String language) { protected static boolean formatHasLanguage(Format format, @Nullable String language) {
return language != null return language != null
&& TextUtils.equals(language, Util.normalizeLanguageCode(format.language)); && TextUtils.equals(language, Util.normalizeLanguageCode(format.language));
} }
@ -1997,7 +2021,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* negative integer if this score is worse than the other. * negative integer if this score is worse than the other.
*/ */
@Override @Override
public int compareTo(@NonNull AudioTrackScore other) { public int compareTo(AudioTrackScore other) {
if (this.withinRendererCapabilitiesScore != other.withinRendererCapabilitiesScore) { if (this.withinRendererCapabilitiesScore != other.withinRendererCapabilitiesScore) {
return compareInts(this.withinRendererCapabilitiesScore, return compareInts(this.withinRendererCapabilitiesScore,
other.withinRendererCapabilitiesScore); other.withinRendererCapabilitiesScore);
@ -2066,9 +2090,9 @@ public class DefaultTrackSelector extends MappingTrackSelector {
public final int channelCount; public final int channelCount;
public final int sampleRate; public final int sampleRate;
public final String mimeType; public final @Nullable String mimeType;
public AudioConfigurationTuple(int channelCount, int sampleRate, String mimeType) { public AudioConfigurationTuple(int channelCount, int sampleRate, @Nullable String mimeType) {
this.channelCount = channelCount; this.channelCount = channelCount;
this.sampleRate = sampleRate; this.sampleRate = sampleRate;
this.mimeType = mimeType; this.mimeType = mimeType;

View File

@ -15,6 +15,7 @@
*/ */
package com.google.android.exoplayer2.trackselection; package com.google.android.exoplayer2.trackselection;
import android.support.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.source.TrackGroup; import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
@ -30,7 +31,7 @@ public final class FixedTrackSelection extends BaseTrackSelection {
public static final class Factory implements TrackSelection.Factory { public static final class Factory implements TrackSelection.Factory {
private final int reason; private final int reason;
private final Object data; private final @Nullable Object data;
public Factory() { public Factory() {
this.reason = C.SELECTION_REASON_UNKNOWN; this.reason = C.SELECTION_REASON_UNKNOWN;
@ -41,7 +42,7 @@ public final class FixedTrackSelection extends BaseTrackSelection {
* @param reason A reason for the track selection. * @param reason A reason for the track selection.
* @param data Optional data associated with the track selection. * @param data Optional data associated with the track selection.
*/ */
public Factory(int reason, Object data) { public Factory(int reason, @Nullable Object data) {
this.reason = reason; this.reason = reason;
this.data = data; this.data = data;
} }
@ -51,11 +52,10 @@ public final class FixedTrackSelection extends BaseTrackSelection {
Assertions.checkArgument(tracks.length == 1); Assertions.checkArgument(tracks.length == 1);
return new FixedTrackSelection(group, tracks[0], reason, data); return new FixedTrackSelection(group, tracks[0], reason, data);
} }
} }
private final int reason; private final int reason;
private final Object data; private final @Nullable Object data;
/** /**
* @param group The {@link TrackGroup}. Must not be null. * @param group The {@link TrackGroup}. Must not be null.
@ -71,7 +71,7 @@ public final class FixedTrackSelection extends BaseTrackSelection {
* @param reason A reason for the track selection. * @param reason A reason for the track selection.
* @param data Optional data associated with the track selection. * @param data Optional data associated with the track selection.
*/ */
public FixedTrackSelection(TrackGroup group, int track, int reason, Object data) { public FixedTrackSelection(TrackGroup group, int track, int reason, @Nullable Object data) {
super(group, track); super(group, track);
this.reason = reason; this.reason = reason;
this.data = data; this.data = data;
@ -94,7 +94,7 @@ public final class FixedTrackSelection extends BaseTrackSelection {
} }
@Override @Override
public Object getSelectionData() { public @Nullable Object getSelectionData() {
return data; return data;
} }

View File

@ -16,6 +16,7 @@
package com.google.android.exoplayer2.trackselection; package com.google.android.exoplayer2.trackselection;
import android.support.annotation.IntDef; import android.support.annotation.IntDef;
import android.support.annotation.Nullable;
import android.util.Pair; import android.util.Pair;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlaybackException;
@ -28,6 +29,7 @@ import com.google.android.exoplayer2.util.Util;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.util.Arrays; import java.util.Arrays;
import org.checkerframework.checker.nullness.compatqual.NullableType;
/** /**
* Base class for {@link TrackSelector}s that first establish a mapping between {@link TrackGroup}s * Base class for {@link TrackSelector}s that first establish a mapping between {@link TrackGroup}s
@ -301,13 +303,13 @@ public abstract class MappingTrackSelector extends TrackSelector {
} }
private MappedTrackInfo currentMappedTrackInfo; private @Nullable MappedTrackInfo currentMappedTrackInfo;
/** /**
* Returns the mapping information for the currently active track selection, or null if no * Returns the mapping information for the currently active track selection, or null if no
* selection is currently active. * selection is currently active.
*/ */
public final MappedTrackInfo getCurrentMappedTrackInfo() { public final @Nullable MappedTrackInfo getCurrentMappedTrackInfo() {
return currentMappedTrackInfo; return currentMappedTrackInfo;
} }
@ -357,9 +359,11 @@ public abstract class MappingTrackSelector extends TrackSelector {
int[] rendererTrackTypes = new int[rendererCapabilities.length]; int[] rendererTrackTypes = new int[rendererCapabilities.length];
for (int i = 0; i < rendererCapabilities.length; i++) { for (int i = 0; i < rendererCapabilities.length; i++) {
int rendererTrackGroupCount = rendererTrackGroupCounts[i]; int rendererTrackGroupCount = rendererTrackGroupCounts[i];
rendererTrackGroupArrays[i] = new TrackGroupArray( rendererTrackGroupArrays[i] =
Arrays.copyOf(rendererTrackGroups[i], rendererTrackGroupCount)); new TrackGroupArray(
rendererFormatSupports[i] = Arrays.copyOf(rendererFormatSupports[i], rendererTrackGroupCount); Util.nullSafeArrayCopy(rendererTrackGroups[i], rendererTrackGroupCount));
rendererFormatSupports[i] =
Util.nullSafeArrayCopy(rendererFormatSupports[i], rendererTrackGroupCount);
rendererTrackTypes[i] = rendererCapabilities[i].getTrackType(); rendererTrackTypes[i] = rendererCapabilities[i].getTrackType();
} }
@ -367,7 +371,7 @@ public abstract class MappingTrackSelector extends TrackSelector {
int unmappedTrackGroupCount = rendererTrackGroupCounts[rendererCapabilities.length]; int unmappedTrackGroupCount = rendererTrackGroupCounts[rendererCapabilities.length];
TrackGroupArray unmappedTrackGroupArray = TrackGroupArray unmappedTrackGroupArray =
new TrackGroupArray( new TrackGroupArray(
Arrays.copyOf( Util.nullSafeArrayCopy(
rendererTrackGroups[rendererCapabilities.length], unmappedTrackGroupCount)); rendererTrackGroups[rendererCapabilities.length], unmappedTrackGroupCount));
// Package up the track information and selections. // Package up the track information and selections.
@ -379,7 +383,7 @@ public abstract class MappingTrackSelector extends TrackSelector {
rendererFormatSupports, rendererFormatSupports,
unmappedTrackGroupArray); unmappedTrackGroupArray);
Pair<RendererConfiguration[], TrackSelection[]> result = Pair<@NullableType RendererConfiguration[], @NullableType TrackSelection[]> result =
selectTracks( selectTracks(
mappedTrackInfo, rendererFormatSupports, rendererMixedMimeTypeAdaptationSupports); mappedTrackInfo, rendererFormatSupports, rendererMixedMimeTypeAdaptationSupports);
return new TrackSelectorResult(result.first, result.second, mappedTrackInfo); return new TrackSelectorResult(result.first, result.second, mappedTrackInfo);
@ -399,7 +403,8 @@ public abstract class MappingTrackSelector extends TrackSelector {
* RendererCapabilities#getTrackType()} is {@link C#TRACK_TYPE_NONE}. * RendererCapabilities#getTrackType()} is {@link C#TRACK_TYPE_NONE}.
* @throws ExoPlaybackException If an error occurs while selecting the tracks. * @throws ExoPlaybackException If an error occurs while selecting the tracks.
*/ */
protected abstract Pair<RendererConfiguration[], TrackSelection[]> selectTracks( protected abstract Pair<@NullableType RendererConfiguration[], @NullableType TrackSelection[]>
selectTracks(
MappedTrackInfo mappedTrackInfo, MappedTrackInfo mappedTrackInfo,
int[][][] rendererFormatSupports, int[][][] rendererFormatSupports,
int[] rendererMixedMimeTypeAdaptationSupport) int[] rendererMixedMimeTypeAdaptationSupport)

View File

@ -16,6 +16,7 @@
package com.google.android.exoplayer2.trackselection; package com.google.android.exoplayer2.trackselection;
import android.os.SystemClock; import android.os.SystemClock;
import android.support.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.source.TrackGroup; import com.google.android.exoplayer2.source.TrackGroup;
import java.util.Random; import java.util.Random;
@ -47,7 +48,6 @@ public final class RandomTrackSelection extends BaseTrackSelection {
public RandomTrackSelection createTrackSelection(TrackGroup group, int... tracks) { public RandomTrackSelection createTrackSelection(TrackGroup group, int... tracks) {
return new RandomTrackSelection(group, tracks, random); return new RandomTrackSelection(group, tracks, random);
} }
} }
private final Random random; private final Random random;
@ -123,7 +123,7 @@ public final class RandomTrackSelection extends BaseTrackSelection {
} }
@Override @Override
public Object getSelectionData() { public @Nullable Object getSelectionData() {
return null; return null;
} }

View File

@ -15,6 +15,7 @@
*/ */
package com.google.android.exoplayer2.trackselection; package com.google.android.exoplayer2.trackselection;
import android.support.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.source.TrackGroup; import com.google.android.exoplayer2.source.TrackGroup;
@ -129,10 +130,8 @@ public interface TrackSelection {
*/ */
int getSelectionReason(); int getSelectionReason();
/** /** Returns optional data associated with the current track selection. */
* Returns optional data associated with the current track selection. @Nullable Object getSelectionData();
*/
Object getSelectionData();
// Adaptation. // Adaptation.

View File

@ -17,6 +17,7 @@ package com.google.android.exoplayer2.trackselection;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import java.util.Arrays; import java.util.Arrays;
import org.checkerframework.checker.nullness.compatqual.NullableType;
/** An array of {@link TrackSelection}s. */ /** An array of {@link TrackSelection}s. */
public final class TrackSelectionArray { public final class TrackSelectionArray {
@ -24,15 +25,13 @@ public final class TrackSelectionArray {
/** The length of this array. */ /** The length of this array. */
public final int length; public final int length;
private final TrackSelection[] trackSelections; private final @NullableType TrackSelection[] trackSelections;
// Lazily initialized hashcode. // Lazily initialized hashcode.
private int hashCode; private int hashCode;
/** /** @param trackSelections The selections. Must not be null, but may contain null elements. */
* @param trackSelections The selections. Must not be null, but may contain null elements. public TrackSelectionArray(@NullableType TrackSelection... trackSelections) {
*/
public TrackSelectionArray(TrackSelection... trackSelections) {
this.trackSelections = trackSelections; this.trackSelections = trackSelections;
this.length = trackSelections.length; this.length = trackSelections.length;
} }
@ -43,14 +42,12 @@ public final class TrackSelectionArray {
* @param index The index of the selection. * @param index The index of the selection.
* @return The selection. * @return The selection.
*/ */
public TrackSelection get(int index) { public @Nullable TrackSelection get(int index) {
return trackSelections[index]; return trackSelections[index];
} }
/** /** Returns the selections in a newly allocated array. */
* Returns the selections in a newly allocated array. public @NullableType TrackSelection[] getAll() {
*/
public TrackSelection[] getAll() {
return trackSelections.clone(); return trackSelections.clone();
} }

View File

@ -15,6 +15,7 @@
*/ */
package com.google.android.exoplayer2.trackselection; package com.google.android.exoplayer2.trackselection;
import android.support.annotation.Nullable;
import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.Renderer; import com.google.android.exoplayer2.Renderer;
@ -89,7 +90,7 @@ public abstract class TrackSelector {
} }
private InvalidationListener listener; private @Nullable InvalidationListener listener;
/** /**
* Called by the player to initialize the selector. * Called by the player to initialize the selector.

View File

@ -17,6 +17,7 @@ package com.google.android.exoplayer2.trackselection;
import com.google.android.exoplayer2.RendererConfiguration; import com.google.android.exoplayer2.RendererConfiguration;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import org.checkerframework.checker.nullness.compatqual.NullableType;
/** /**
* The result of a {@link TrackSelector} operation. * The result of a {@link TrackSelector} operation.
@ -29,7 +30,7 @@ public final class TrackSelectorResult {
* A {@link RendererConfiguration} for each renderer. A null entry indicates the corresponding * A {@link RendererConfiguration} for each renderer. A null entry indicates the corresponding
* renderer should be disabled. * renderer should be disabled.
*/ */
public final RendererConfiguration[] rendererConfigurations; public final @NullableType RendererConfiguration[] rendererConfigurations;
/** /**
* A {@link TrackSelectionArray} containing the track selection for each renderer. * A {@link TrackSelectionArray} containing the track selection for each renderer.
*/ */
@ -48,7 +49,9 @@ public final class TrackSelectorResult {
* TrackSelector#onSelectionActivated(Object)} should the selection be activated. * TrackSelector#onSelectionActivated(Object)} should the selection be activated.
*/ */
public TrackSelectorResult( public TrackSelectorResult(
RendererConfiguration[] rendererConfigurations, TrackSelection[] selections, Object info) { @NullableType RendererConfiguration[] rendererConfigurations,
@NullableType TrackSelection[] selections,
Object info) {
this.rendererConfigurations = rendererConfigurations; this.rendererConfigurations = rendererConfigurations;
this.selections = new TrackSelectionArray(selections); this.selections = new TrackSelectionArray(selections);
this.info = info; this.info = info;

View File

@ -311,10 +311,10 @@ public final class Util {
* Returns a normalized RFC 639-2/T code for {@code language}. * Returns a normalized RFC 639-2/T code for {@code language}.
* *
* @param language A case-insensitive ISO 639 alpha-2 or alpha-3 language code. * @param language A case-insensitive ISO 639 alpha-2 or alpha-3 language code.
* @return The all-lowercase normalized code, or null if the input was null, or * @return The all-lowercase normalized code, or null if the input was null, or {@code
* {@code language.toLowerCase()} if the language could not be normalized. * language.toLowerCase()} if the language could not be normalized.
*/ */
public static String normalizeLanguageCode(String language) { public static @Nullable String normalizeLanguageCode(@Nullable String language) {
try { try {
return language == null ? null : new Locale(language).getISO3Language(); return language == null ? null : new Locale(language).getISO3Language();
} catch (MissingResourceException e) { } catch (MissingResourceException e) {

View File

@ -203,7 +203,9 @@ public class TrackSelectionView extends LinearLayout {
removeViewAt(i); removeViewAt(i);
} }
if (trackSelector == null) { MappingTrackSelector.MappedTrackInfo trackInfo =
trackSelector == null ? null : trackSelector.getCurrentMappedTrackInfo();
if (trackSelector == null || trackInfo == null) {
// The view is not initialized. // The view is not initialized.
disableView.setEnabled(false); disableView.setEnabled(false);
defaultView.setEnabled(false); defaultView.setEnabled(false);
@ -212,7 +214,6 @@ public class TrackSelectionView extends LinearLayout {
disableView.setEnabled(true); disableView.setEnabled(true);
defaultView.setEnabled(true); defaultView.setEnabled(true);
MappingTrackSelector.MappedTrackInfo trackInfo = trackSelector.getCurrentMappedTrackInfo();
trackGroups = trackInfo.getTrackGroups(rendererIndex); trackGroups = trackInfo.getTrackGroups(rendererIndex);
DefaultTrackSelector.Parameters parameters = trackSelector.getParameters(); DefaultTrackSelector.Parameters parameters = trackSelector.getParameters();