diff --git a/demo/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java b/demo/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java
index 413157cbd0..b3cc8c0ba5 100644
--- a/demo/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java
+++ b/demo/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java
@@ -55,7 +55,6 @@ import com.google.android.exoplayer2.source.smoothstreaming.DefaultSsChunkSource
import com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource;
import com.google.android.exoplayer2.trackselection.AdaptiveVideoTrackSelection;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
-import com.google.android.exoplayer2.trackselection.MappingTrackSelector;
import com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedTrackInfo;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
@@ -109,7 +108,7 @@ public class PlayerActivity extends Activity implements OnClickListener, ExoPlay
private DataSource.Factory mediaDataSourceFactory;
private SimpleExoPlayer player;
- private MappingTrackSelector trackSelector;
+ private DefaultTrackSelector trackSelector;
private TrackSelectionHelper trackSelectionHelper;
private DebugTextViewHelper debugViewHelper;
private boolean playerNeedsSource;
diff --git a/library/src/main/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelector.java b/library/src/main/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelector.java
index 02c2defdfc..bf139c85a8 100644
--- a/library/src/main/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelector.java
+++ b/library/src/main/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelector.java
@@ -55,6 +55,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
public final int maxVideoWidth;
public final int maxVideoHeight;
public final boolean exceedVideoConstraintsIfNecessary;
+ public final boolean exceedRendererCapabilitiesIfNecessary;
public final int viewportWidth;
public final int viewportHeight;
public final boolean orientationMayChange;
@@ -67,13 +68,14 @@ public class DefaultTrackSelector extends MappingTrackSelector {
*
Adaptation between different mime types is not allowed.
* Non seamless adaptation is allowed.
* No max limit for video width/height.
- * Video constraints are ignored if no supported selection can be made otherwise.
+ * Video constraints are exceeded if no supported selection can be made otherwise.
+ * Renderer capabilities are not exceeded even if no supported selection can be made.
* No viewport width/height constraints are set.
*
*/
public Parameters() {
- this(null, null, false, true, Integer.MAX_VALUE, Integer.MAX_VALUE, true, Integer.MAX_VALUE,
- Integer.MAX_VALUE, true);
+ this(null, null, false, true, Integer.MAX_VALUE, Integer.MAX_VALUE, true, false,
+ Integer.MAX_VALUE, Integer.MAX_VALUE, true);
}
/**
@@ -86,8 +88,10 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* @param allowNonSeamlessAdaptiveness Whether non-seamless adaptation is allowed.
* @param maxVideoWidth Maximum allowed video width.
* @param maxVideoHeight Maximum allowed video height.
- * @param exceedVideoConstraintsIfNecessary True to ignore video constraints when no selections
- * can be made otherwise. False to force constraints anyway.
+ * @param exceedVideoConstraintsIfNecessary Whether to exceed video constraints when no
+ * selection can be made otherwise.
+ * @param exceedRendererCapabilitiesIfNecessary Whether to exceed renderer capabilities when no
+ * selection can be made otherwise.
* @param viewportWidth Viewport width in pixels.
* @param viewportHeight Viewport height in pixels.
* @param orientationMayChange Whether orientation may change during playback.
@@ -95,7 +99,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
public Parameters(String preferredAudioLanguage, String preferredTextLanguage,
boolean allowMixedMimeAdaptiveness, boolean allowNonSeamlessAdaptiveness,
int maxVideoWidth, int maxVideoHeight, boolean exceedVideoConstraintsIfNecessary,
- int viewportWidth, int viewportHeight, boolean orientationMayChange) {
+ boolean exceedRendererCapabilitiesIfNecessary, int viewportWidth, int viewportHeight,
+ boolean orientationMayChange) {
this.preferredAudioLanguage = preferredAudioLanguage;
this.preferredTextLanguage = preferredTextLanguage;
this.allowMixedMimeAdaptiveness = allowMixedMimeAdaptiveness;
@@ -103,6 +108,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
this.maxVideoWidth = maxVideoWidth;
this.maxVideoHeight = maxVideoHeight;
this.exceedVideoConstraintsIfNecessary = exceedVideoConstraintsIfNecessary;
+ this.exceedRendererCapabilitiesIfNecessary = exceedRendererCapabilitiesIfNecessary;
this.viewportWidth = viewportWidth;
this.viewportHeight = viewportHeight;
this.orientationMayChange = orientationMayChange;
@@ -124,7 +130,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
}
return new Parameters(preferredAudioLanguage, preferredTextLanguage,
allowMixedMimeAdaptiveness, allowNonSeamlessAdaptiveness, maxVideoWidth, maxVideoHeight,
- exceedVideoConstraintsIfNecessary, viewportWidth, viewportHeight, orientationMayChange);
+ exceedVideoConstraintsIfNecessary, exceedRendererCapabilitiesIfNecessary, viewportWidth,
+ viewportHeight, orientationMayChange);
}
/**
@@ -140,9 +147,9 @@ public class DefaultTrackSelector extends MappingTrackSelector {
return this;
}
return new Parameters(preferredAudioLanguage, preferredTextLanguage,
- allowMixedMimeAdaptiveness, allowNonSeamlessAdaptiveness, maxVideoWidth,
- maxVideoHeight, exceedVideoConstraintsIfNecessary, viewportWidth, viewportHeight,
- orientationMayChange);
+ allowMixedMimeAdaptiveness, allowNonSeamlessAdaptiveness, maxVideoWidth, maxVideoHeight,
+ exceedVideoConstraintsIfNecessary, exceedRendererCapabilitiesIfNecessary, viewportWidth,
+ viewportHeight, orientationMayChange);
}
/**
@@ -156,9 +163,9 @@ public class DefaultTrackSelector extends MappingTrackSelector {
return this;
}
return new Parameters(preferredAudioLanguage, preferredTextLanguage,
- allowMixedMimeAdaptiveness, allowNonSeamlessAdaptiveness, maxVideoWidth,
- maxVideoHeight, exceedVideoConstraintsIfNecessary, viewportWidth, viewportHeight,
- orientationMayChange);
+ allowMixedMimeAdaptiveness, allowNonSeamlessAdaptiveness, maxVideoWidth, maxVideoHeight,
+ exceedVideoConstraintsIfNecessary, exceedRendererCapabilitiesIfNecessary, viewportWidth,
+ viewportHeight, orientationMayChange);
}
/**
@@ -172,9 +179,9 @@ public class DefaultTrackSelector extends MappingTrackSelector {
return this;
}
return new Parameters(preferredAudioLanguage, preferredTextLanguage,
- allowMixedMimeAdaptiveness, allowNonSeamlessAdaptiveness, maxVideoWidth,
- maxVideoHeight, exceedVideoConstraintsIfNecessary, viewportWidth, viewportHeight,
- orientationMayChange);
+ allowMixedMimeAdaptiveness, allowNonSeamlessAdaptiveness, maxVideoWidth, maxVideoHeight,
+ exceedVideoConstraintsIfNecessary, exceedRendererCapabilitiesIfNecessary, viewportWidth,
+ viewportHeight, orientationMayChange);
}
/**
@@ -189,9 +196,9 @@ public class DefaultTrackSelector extends MappingTrackSelector {
return this;
}
return new Parameters(preferredAudioLanguage, preferredTextLanguage,
- allowMixedMimeAdaptiveness, allowNonSeamlessAdaptiveness, maxVideoWidth,
- maxVideoHeight, exceedVideoConstraintsIfNecessary, viewportWidth, viewportHeight,
- orientationMayChange);
+ allowMixedMimeAdaptiveness, allowNonSeamlessAdaptiveness, maxVideoWidth, maxVideoHeight,
+ exceedVideoConstraintsIfNecessary, exceedRendererCapabilitiesIfNecessary, viewportWidth,
+ viewportHeight, orientationMayChange);
}
/**
@@ -216,8 +223,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* Returns a {@link Parameters} instance with the provided
* {@code exceedVideoConstraintsIfNecessary} value.
*
- * @param exceedVideoConstraintsIfNecessary True to ignore video constraints when no selections
- * can be made otherwise. False to force constraints anyway.
+ * @param exceedVideoConstraintsIfNecessary Whether to exceed video constraints when no
+ * selection can be made otherwise.
* @return A {@link Parameters} instance with the provided
* {@code exceedVideoConstraintsIfNecessary} value.
*/
@@ -227,9 +234,29 @@ public class DefaultTrackSelector extends MappingTrackSelector {
return this;
}
return new Parameters(preferredAudioLanguage, preferredTextLanguage,
- allowMixedMimeAdaptiveness, allowNonSeamlessAdaptiveness, maxVideoWidth,
- maxVideoHeight, exceedVideoConstraintsIfNecessary, viewportWidth, viewportHeight,
- orientationMayChange);
+ allowMixedMimeAdaptiveness, allowNonSeamlessAdaptiveness, maxVideoWidth, maxVideoHeight,
+ exceedVideoConstraintsIfNecessary, exceedRendererCapabilitiesIfNecessary, viewportWidth,
+ viewportHeight, orientationMayChange);
+ }
+
+ /**
+ * Returns a {@link Parameters} instance with the provided
+ * {@code exceedRendererCapabilitiesIfNecessary} value.
+ *
+ * @param exceedRendererCapabilitiesIfNecessary Whether to exceed renderer capabilities when no
+ * selection can be made otherwise.
+ * @return A {@link Parameters} instance with the provided
+ * {@code exceedRendererCapabilitiesIfNecessary} value.
+ */
+ public Parameters withExceedRendererCapabilitiesIfNecessary(
+ boolean exceedRendererCapabilitiesIfNecessary) {
+ if (exceedRendererCapabilitiesIfNecessary == this.exceedRendererCapabilitiesIfNecessary) {
+ return this;
+ }
+ return new Parameters(preferredAudioLanguage, preferredTextLanguage,
+ allowMixedMimeAdaptiveness, allowNonSeamlessAdaptiveness, maxVideoWidth, maxVideoHeight,
+ exceedVideoConstraintsIfNecessary, exceedRendererCapabilitiesIfNecessary, viewportWidth,
+ viewportHeight, orientationMayChange);
}
/**
@@ -247,9 +274,9 @@ public class DefaultTrackSelector extends MappingTrackSelector {
return this;
}
return new Parameters(preferredAudioLanguage, preferredTextLanguage,
- allowMixedMimeAdaptiveness, allowNonSeamlessAdaptiveness, maxVideoWidth,
- maxVideoHeight, exceedVideoConstraintsIfNecessary, viewportWidth, viewportHeight,
- orientationMayChange);
+ allowMixedMimeAdaptiveness, allowNonSeamlessAdaptiveness, maxVideoWidth, maxVideoHeight,
+ exceedVideoConstraintsIfNecessary, exceedRendererCapabilitiesIfNecessary, viewportWidth,
+ viewportHeight, orientationMayChange);
}
/**
@@ -289,6 +316,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
&& allowNonSeamlessAdaptiveness == other.allowNonSeamlessAdaptiveness
&& maxVideoWidth == other.maxVideoWidth && maxVideoHeight == other.maxVideoHeight
&& exceedVideoConstraintsIfNecessary == other.exceedVideoConstraintsIfNecessary
+ && exceedRendererCapabilitiesIfNecessary == other.exceedRendererCapabilitiesIfNecessary
&& orientationMayChange == other.orientationMayChange
&& viewportWidth == other.viewportWidth && viewportHeight == other.viewportHeight
&& TextUtils.equals(preferredAudioLanguage, other.preferredAudioLanguage)
@@ -304,6 +332,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
result = 31 * result + maxVideoWidth;
result = 31 * result + maxVideoHeight;
result = 31 * result + (exceedVideoConstraintsIfNecessary ? 1 : 0);
+ result = 31 * result + (exceedRendererCapabilitiesIfNecessary ? 1 : 0);
result = 31 * result + (orientationMayChange ? 1 : 0);
result = 31 * result + viewportWidth;
result = 31 * result + viewportHeight;
@@ -319,9 +348,10 @@ public class DefaultTrackSelector extends MappingTrackSelector {
*/
private static final float FRACTION_TO_CONSIDER_FULLSCREEN = 0.98f;
private static final int[] NO_TRACKS = new int[0];
+ private static final int WITHIN_RENDERER_CAPABILITIES_BONUS = 1000;
private final TrackSelection.Factory adaptiveVideoTrackSelectionFactory;
- private final AtomicReference params;
+ private final AtomicReference paramsReference;
/**
* Constructs an instance that does not support adaptive video.
@@ -338,7 +368,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
*/
public DefaultTrackSelector(TrackSelection.Factory adaptiveVideoTrackSelectionFactory) {
this.adaptiveVideoTrackSelectionFactory = adaptiveVideoTrackSelectionFactory;
- params = new AtomicReference<>(new Parameters());
+ paramsReference = new AtomicReference<>(new Parameters());
}
/**
@@ -347,8 +377,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* @param params The parameters for track selection.
*/
public void setParameters(Parameters params) {
- if (!this.params.get().equals(params)) {
- this.params.set(Assertions.checkNotNull(params));
+ Assertions.checkNotNull(params);
+ if (!paramsReference.getAndSet(params).equals(params)) {
invalidate();
}
}
@@ -359,7 +389,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* @return The current selection parameters.
*/
public Parameters getParameters() {
- return params.get();
+ return paramsReference.get();
}
// MappingTrackSelector implementation.
@@ -370,7 +400,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
throws ExoPlaybackException {
// Make a track selection for each renderer.
TrackSelection[] rendererTrackSelections = new TrackSelection[rendererCapabilities.length];
- Parameters params = this.params.get();
+ Parameters params = paramsReference.get();
for (int i = 0; i < rendererCapabilities.length; i++) {
switch (rendererCapabilities[i].getTrackType()) {
case C.TRACK_TYPE_VIDEO:
@@ -379,20 +409,23 @@ public class DefaultTrackSelector extends MappingTrackSelector {
params.maxVideoHeight, params.allowNonSeamlessAdaptiveness,
params.allowMixedMimeAdaptiveness, params.viewportWidth, params.viewportHeight,
params.orientationMayChange, adaptiveVideoTrackSelectionFactory,
- params.exceedVideoConstraintsIfNecessary);
+ params.exceedVideoConstraintsIfNecessary,
+ params.exceedRendererCapabilitiesIfNecessary);
break;
case C.TRACK_TYPE_AUDIO:
rendererTrackSelections[i] = selectAudioTrack(rendererTrackGroupArrays[i],
- rendererFormatSupports[i], params.preferredAudioLanguage);
+ rendererFormatSupports[i], params.preferredAudioLanguage,
+ params.exceedRendererCapabilitiesIfNecessary);
break;
case C.TRACK_TYPE_TEXT:
rendererTrackSelections[i] = selectTextTrack(rendererTrackGroupArrays[i],
rendererFormatSupports[i], params.preferredTextLanguage,
- params.preferredAudioLanguage);
+ params.preferredAudioLanguage, params.exceedRendererCapabilitiesIfNecessary);
break;
default:
rendererTrackSelections[i] = selectOtherTrack(rendererCapabilities[i].getTrackType(),
- rendererTrackGroupArrays[i], rendererFormatSupports[i]);
+ rendererTrackGroupArrays[i], rendererFormatSupports[i],
+ params.exceedRendererCapabilitiesIfNecessary);
break;
}
}
@@ -406,7 +439,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
boolean allowNonSeamlessAdaptiveness, boolean allowMixedMimeAdaptiveness, int viewportWidth,
int viewportHeight, boolean orientationMayChange,
TrackSelection.Factory adaptiveVideoTrackSelectionFactory,
- boolean exceedConstraintsIfNecessary) throws ExoPlaybackException {
+ boolean exceedConstraintsIfNecessary, boolean exceedRendererCapabilitiesIfNecessary)
+ throws ExoPlaybackException {
TrackSelection selection = null;
if (adaptiveVideoTrackSelectionFactory != null) {
selection = selectAdaptiveVideoTrack(rendererCapabilities, groups, formatSupport,
@@ -416,7 +450,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
}
if (selection == null) {
selection = selectFixedVideoTrack(groups, formatSupport, maxVideoWidth, maxVideoHeight,
- viewportWidth, viewportHeight, orientationMayChange, exceedConstraintsIfNecessary);
+ viewportWidth, viewportHeight, orientationMayChange, exceedConstraintsIfNecessary,
+ exceedRendererCapabilitiesIfNecessary);
}
return selection;
}
@@ -512,7 +547,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
private static boolean isSupportedAdaptiveVideoTrack(Format format, String mimeType,
int formatSupport, int requiredAdaptiveSupport, int maxVideoWidth, int maxVideoHeight) {
- return isSupported(formatSupport) && ((formatSupport & requiredAdaptiveSupport) != 0)
+ return isSupported(formatSupport, false) && ((formatSupport & requiredAdaptiveSupport) != 0)
&& (mimeType == null || Util.areEqual(format.sampleMimeType, mimeType))
&& (format.width == Format.NO_VALUE || format.width <= maxVideoWidth)
&& (format.height == Format.NO_VALUE || format.height <= maxVideoHeight);
@@ -520,37 +555,44 @@ public class DefaultTrackSelector extends MappingTrackSelector {
private static TrackSelection selectFixedVideoTrack(TrackGroupArray groups,
int[][] formatSupport, int maxVideoWidth, int maxVideoHeight, int viewportWidth,
- int viewportHeight, boolean orientationMayChange, boolean exceedConstraintsIfNecessary) {
+ int viewportHeight, boolean orientationMayChange, boolean exceedConstraintsIfNecessary,
+ boolean exceedRendererCapabilitiesIfNecessary) {
TrackGroup selectedGroup = null;
int selectedTrackIndex = 0;
+ int selectedTrackScore = 0;
int selectedPixelCount = Format.NO_VALUE;
- boolean selectedIsWithinConstraints = false;
for (int groupIndex = 0; groupIndex < groups.length; groupIndex++) {
- TrackGroup group = groups.get(groupIndex);
- List selectedTrackIndices = getViewportFilteredTrackIndices(group, viewportWidth,
- viewportHeight, orientationMayChange);
+ TrackGroup trackGroup = groups.get(groupIndex);
+ List selectedTrackIndices = getViewportFilteredTrackIndices(trackGroup,
+ viewportWidth, viewportHeight, orientationMayChange);
int[] trackFormatSupport = formatSupport[groupIndex];
- for (int trackIndex = 0; trackIndex < group.length; trackIndex++) {
- if (isSupported(trackFormatSupport[trackIndex])) {
- Format format = group.getFormat(trackIndex);
+ for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
+ if (isSupported(trackFormatSupport[trackIndex], exceedRendererCapabilitiesIfNecessary)) {
+ Format format = trackGroup.getFormat(trackIndex);
boolean isWithinConstraints = selectedTrackIndices.contains(trackIndex)
&& (format.width == Format.NO_VALUE || format.width <= maxVideoWidth)
&& (format.height == Format.NO_VALUE || format.height <= maxVideoHeight);
- int pixelCount = format.getPixelCount();
- boolean selectTrack;
- if (selectedIsWithinConstraints) {
- selectTrack = isWithinConstraints
- && comparePixelCounts(pixelCount, selectedPixelCount) > 0;
- } else {
- selectTrack = isWithinConstraints || (exceedConstraintsIfNecessary
- && (selectedGroup == null
- || comparePixelCounts(pixelCount, selectedPixelCount) < 0));
+ if (!isWithinConstraints && !exceedConstraintsIfNecessary) {
+ // Track should not be selected.
+ continue;
+ }
+ int trackScore = isWithinConstraints ? 2 : 1;
+ if (isSupported(trackFormatSupport[trackIndex], false)) {
+ trackScore += WITHIN_RENDERER_CAPABILITIES_BONUS;
+ }
+ boolean selectTrack = trackScore > selectedTrackScore;
+ if (trackScore == selectedTrackScore) {
+ // Use the pixel count as a tie breaker. If we're within constraints prefer a higher
+ // pixel count, else prefer a lower count. If still tied then prefer the first track
+ // (i.e. the one that's already selected).
+ int pixelComparison = comparePixelCounts(format.getPixelCount(), selectedPixelCount);
+ selectTrack = isWithinConstraints ? pixelComparison > 0 : pixelComparison < 0;
}
if (selectTrack) {
- selectedGroup = group;
+ selectedGroup = trackGroup;
selectedTrackIndex = trackIndex;
- selectedPixelCount = pixelCount;
- selectedIsWithinConstraints = isWithinConstraints;
+ selectedTrackScore = trackScore;
+ selectedPixelCount = format.getPixelCount();
}
}
}
@@ -577,7 +619,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
// Audio track selection implementation.
protected TrackSelection selectAudioTrack(TrackGroupArray groups, int[][] formatSupport,
- String preferredAudioLanguage) {
+ String preferredAudioLanguage, boolean exceedRendererCapabilitiesIfNecessary) {
TrackGroup selectedGroup = null;
int selectedTrackIndex = 0;
int selectedTrackScore = 0;
@@ -585,7 +627,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
TrackGroup trackGroup = groups.get(groupIndex);
int[] trackFormatSupport = formatSupport[groupIndex];
for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
- if (isSupported(trackFormatSupport[trackIndex])) {
+ if (isSupported(trackFormatSupport[trackIndex], exceedRendererCapabilitiesIfNecessary)) {
Format format = trackGroup.getFormat(trackIndex);
boolean isDefault = (format.selectionFlags & C.SELECTION_FLAG_DEFAULT) != 0;
int trackScore;
@@ -600,6 +642,9 @@ public class DefaultTrackSelector extends MappingTrackSelector {
} else {
trackScore = 1;
}
+ if (isSupported(trackFormatSupport[trackIndex], false)) {
+ trackScore += WITHIN_RENDERER_CAPABILITIES_BONUS;
+ }
if (trackScore > selectedTrackScore) {
selectedGroup = trackGroup;
selectedTrackIndex = trackIndex;
@@ -615,7 +660,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
// Text track selection implementation.
protected TrackSelection selectTextTrack(TrackGroupArray groups, int[][] formatSupport,
- String preferredTextLanguage, String preferredAudioLanguage) {
+ String preferredTextLanguage, String preferredAudioLanguage,
+ boolean exceedRendererCapabilitiesIfNecessary) {
TrackGroup selectedGroup = null;
int selectedTrackIndex = 0;
int selectedTrackScore = 0;
@@ -623,7 +669,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
TrackGroup trackGroup = groups.get(groupIndex);
int[] trackFormatSupport = formatSupport[groupIndex];
for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
- if (isSupported(trackFormatSupport[trackIndex])) {
+ if (isSupported(trackFormatSupport[trackIndex], exceedRendererCapabilitiesIfNecessary)) {
Format format = trackGroup.getFormat(trackIndex);
boolean isDefault = (format.selectionFlags & C.SELECTION_FLAG_DEFAULT) != 0;
boolean isForced = (format.selectionFlags & C.SELECTION_FLAG_FORCED) != 0;
@@ -648,7 +694,11 @@ public class DefaultTrackSelector extends MappingTrackSelector {
trackScore = 1;
}
} else {
- trackScore = 0;
+ // Track should not be selected.
+ continue;
+ }
+ if (isSupported(trackFormatSupport[trackIndex], false)) {
+ trackScore += WITHIN_RENDERER_CAPABILITIES_BONUS;
}
if (trackScore > selectedTrackScore) {
selectedGroup = trackGroup;
@@ -665,7 +715,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
// General track selection methods.
protected TrackSelection selectOtherTrack(int trackType, TrackGroupArray groups,
- int[][] formatSupport) {
+ int[][] formatSupport, boolean exceedRendererCapabilitiesIfNecessary) {
TrackGroup selectedGroup = null;
int selectedTrackIndex = 0;
int selectedTrackScore = 0;
@@ -673,10 +723,13 @@ public class DefaultTrackSelector extends MappingTrackSelector {
TrackGroup trackGroup = groups.get(groupIndex);
int[] trackFormatSupport = formatSupport[groupIndex];
for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
- if (isSupported(trackFormatSupport[trackIndex])) {
+ if (isSupported(trackFormatSupport[trackIndex], exceedRendererCapabilitiesIfNecessary)) {
Format format = trackGroup.getFormat(trackIndex);
boolean isDefault = (format.selectionFlags & C.SELECTION_FLAG_DEFAULT) != 0;
int trackScore = isDefault ? 2 : 1;
+ if (isSupported(trackFormatSupport[trackIndex], false)) {
+ trackScore += WITHIN_RENDERER_CAPABILITIES_BONUS;
+ }
if (trackScore > selectedTrackScore) {
selectedGroup = trackGroup;
selectedTrackIndex = trackIndex;
@@ -689,12 +742,13 @@ public class DefaultTrackSelector extends MappingTrackSelector {
: new FixedTrackSelection(selectedGroup, selectedTrackIndex);
}
- private static boolean isSupported(int formatSupport) {
- return (formatSupport & RendererCapabilities.FORMAT_SUPPORT_MASK)
- == RendererCapabilities.FORMAT_HANDLED;
+ protected static boolean isSupported(int formatSupport, boolean allowExceedsCapabilities) {
+ int maskedSupport = formatSupport & RendererCapabilities.FORMAT_SUPPORT_MASK;
+ return maskedSupport == RendererCapabilities.FORMAT_HANDLED || (allowExceedsCapabilities
+ && maskedSupport == RendererCapabilities.FORMAT_EXCEEDS_CAPABILITIES);
}
- private static boolean formatHasLanguage(Format format, String language) {
+ protected static boolean formatHasLanguage(Format format, String language) {
return language != null && language.equals(Util.normalizeLanguageCode(format.language));
}