mirror of
https://github.com/androidx/media.git
synced 2025-05-04 14:10:40 +08:00
Enhance DefaultTrackSelector part 1
- Enforce viewport constraints for fixed video track selection. - Select best fixed video track, not the first one. - Better handling of video tracks with unknown dimensions. - Mini bug fix. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=129226593
This commit is contained in:
parent
2395f13682
commit
ee565300cb
@ -410,6 +410,14 @@ public final class Format implements Parcelable {
|
|||||||
initializationData, drmInitData);
|
initializationData, drmInitData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of pixels if this is a video format whose {@link #width} and {@link #height}
|
||||||
|
* are known, or {@link #NO_VALUE} otherwise
|
||||||
|
*/
|
||||||
|
public int getPixelCount() {
|
||||||
|
return width == NO_VALUE || height == NO_VALUE ? NO_VALUE : (width * height);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a {@link MediaFormat} representation of this format.
|
* Returns a {@link MediaFormat} representation of this format.
|
||||||
*/
|
*/
|
||||||
|
@ -32,6 +32,7 @@ import com.google.android.exoplayer2.source.TrackGroupArray;
|
|||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
@ -205,7 +206,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
/**
|
/**
|
||||||
* Equivalent to {@code setViewportSize(Integer.MAX_VALUE, Integer.MAX_VALUE, true)}.
|
* Equivalent to {@code setViewportSize(Integer.MAX_VALUE, Integer.MAX_VALUE, true)}.
|
||||||
*/
|
*/
|
||||||
public void clearViewportConstrains() {
|
public void clearViewportConstraints() {
|
||||||
setViewportSize(Integer.MAX_VALUE, Integer.MAX_VALUE, true);
|
setViewportSize(Integer.MAX_VALUE, Integer.MAX_VALUE, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,156 +247,189 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
// Video track selection implementation.
|
// Video track selection implementation.
|
||||||
|
|
||||||
private static TrackSelection selectTrackForVideoRenderer(
|
private static TrackSelection selectTrackForVideoRenderer(
|
||||||
RendererCapabilities rendererCapabilities, TrackGroupArray trackGroups,
|
RendererCapabilities rendererCapabilities, TrackGroupArray groups, int[][] formatSupport,
|
||||||
int[][] formatSupport, int maxVideoWidth, int maxVideoHeight,
|
int maxVideoWidth, int maxVideoHeight, boolean allowNonSeamlessAdaptiveness,
|
||||||
|
boolean allowMixedMimeAdaptiveness, int viewportWidth, int viewportHeight,
|
||||||
|
boolean orientationMayChange, TrackSelection.Factory adaptiveVideoTrackSelectionFactory,
|
||||||
|
boolean exceedConstraintsIfNecessary) throws ExoPlaybackException {
|
||||||
|
TrackSelection selection = null;
|
||||||
|
if (adaptiveVideoTrackSelectionFactory != null) {
|
||||||
|
selection = selectAdaptiveVideoTrack(rendererCapabilities, groups, formatSupport,
|
||||||
|
maxVideoWidth, maxVideoHeight, allowNonSeamlessAdaptiveness,
|
||||||
|
allowMixedMimeAdaptiveness, viewportWidth, viewportHeight,
|
||||||
|
orientationMayChange, adaptiveVideoTrackSelectionFactory);
|
||||||
|
}
|
||||||
|
if (selection == null) {
|
||||||
|
selection = selectFixedVideoTrack(groups, formatSupport, maxVideoWidth, maxVideoHeight,
|
||||||
|
viewportWidth, viewportHeight, orientationMayChange, exceedConstraintsIfNecessary);
|
||||||
|
}
|
||||||
|
return selection;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TrackSelection selectAdaptiveVideoTrack(RendererCapabilities rendererCapabilities,
|
||||||
|
TrackGroupArray groups, int[][] formatSupport, int maxVideoWidth, int maxVideoHeight,
|
||||||
boolean allowNonSeamlessAdaptiveness, boolean allowMixedMimeAdaptiveness, int viewportWidth,
|
boolean allowNonSeamlessAdaptiveness, boolean allowMixedMimeAdaptiveness, int viewportWidth,
|
||||||
int viewportHeight, boolean orientationMayChange,
|
int viewportHeight, boolean orientationMayChange,
|
||||||
TrackSelection.Factory adaptiveVideoTrackSelectionFactory,
|
TrackSelection.Factory adaptiveVideoTrackSelectionFactory) throws ExoPlaybackException {
|
||||||
boolean exceedVideoConstraintsIfNecessary) throws ExoPlaybackException {
|
|
||||||
if (adaptiveVideoTrackSelectionFactory != null) {
|
|
||||||
int requiredAdaptiveSupport = allowNonSeamlessAdaptiveness
|
int requiredAdaptiveSupport = allowNonSeamlessAdaptiveness
|
||||||
? (RendererCapabilities.ADAPTIVE_NOT_SEAMLESS | RendererCapabilities.ADAPTIVE_SEAMLESS)
|
? (RendererCapabilities.ADAPTIVE_NOT_SEAMLESS | RendererCapabilities.ADAPTIVE_SEAMLESS)
|
||||||
: RendererCapabilities.ADAPTIVE_SEAMLESS;
|
: RendererCapabilities.ADAPTIVE_SEAMLESS;
|
||||||
boolean allowMixedMimeTypes = allowMixedMimeAdaptiveness
|
boolean allowMixedMimeTypes = allowMixedMimeAdaptiveness
|
||||||
&& (rendererCapabilities.supportsMixedMimeTypeAdaptation() & requiredAdaptiveSupport)
|
&& (rendererCapabilities.supportsMixedMimeTypeAdaptation() & requiredAdaptiveSupport) != 0;
|
||||||
!= 0;
|
|
||||||
TrackGroup largestAdaptiveGroup = null;
|
TrackGroup largestAdaptiveGroup = null;
|
||||||
int[] largestAdaptiveGroupTracks = NO_TRACKS;
|
int[] largestAdaptiveGroupTracks = NO_TRACKS;
|
||||||
for (int i = 0; i < trackGroups.length; i++) {
|
for (int i = 0; i < groups.length; i++) {
|
||||||
TrackGroup trackGroup = trackGroups.get(i);
|
TrackGroup group = groups.get(i);
|
||||||
int[] adaptiveTracks = getAdaptiveTracksOfGroup(trackGroup, formatSupport[i],
|
int[] adaptiveTracks = getAdaptiveTracksForGroup(group, formatSupport[i],
|
||||||
allowMixedMimeTypes, requiredAdaptiveSupport, maxVideoWidth, maxVideoHeight,
|
allowMixedMimeTypes, requiredAdaptiveSupport, maxVideoWidth, maxVideoHeight,
|
||||||
viewportWidth, viewportHeight, orientationMayChange);
|
viewportWidth, viewportHeight, orientationMayChange);
|
||||||
if (adaptiveTracks.length > largestAdaptiveGroupTracks.length) {
|
if (adaptiveTracks.length > largestAdaptiveGroupTracks.length) {
|
||||||
largestAdaptiveGroup = trackGroup;
|
largestAdaptiveGroup = group;
|
||||||
largestAdaptiveGroupTracks = adaptiveTracks;
|
largestAdaptiveGroupTracks = adaptiveTracks;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (largestAdaptiveGroup != null) {
|
return largestAdaptiveGroup == null ? null : adaptiveVideoTrackSelectionFactory
|
||||||
return adaptiveVideoTrackSelectionFactory.createTrackSelection(largestAdaptiveGroup,
|
.createTrackSelection(largestAdaptiveGroup, largestAdaptiveGroupTracks);
|
||||||
largestAdaptiveGroupTracks);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Should select the best supported video track, not the first one.
|
private static int[] getAdaptiveTracksForGroup(TrackGroup group, int[] formatSupport,
|
||||||
// No adaptive tracks selection could be made, so we select the first supported video track.
|
|
||||||
for (int groupIndex = 0; groupIndex < trackGroups.length; groupIndex++) {
|
|
||||||
TrackGroup trackGroup = trackGroups.get(groupIndex);
|
|
||||||
int[] trackFormatSupport = formatSupport[groupIndex];
|
|
||||||
for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
|
|
||||||
if (isSupportedVideoTrack(trackFormatSupport[trackIndex], trackGroup.getFormat(trackIndex),
|
|
||||||
maxVideoWidth, maxVideoHeight)) {
|
|
||||||
return new FixedTrackSelection(trackGroup, trackIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (exceedVideoConstraintsIfNecessary) {
|
|
||||||
return selectSmallestSupportedVideoTrack(trackGroups, formatSupport);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int[] getAdaptiveTracksOfGroup(TrackGroup trackGroup, int[] formatSupport,
|
|
||||||
boolean allowMixedMimeTypes, int requiredAdaptiveSupport, int maxVideoWidth,
|
boolean allowMixedMimeTypes, int requiredAdaptiveSupport, int maxVideoWidth,
|
||||||
int maxVideoHeight, int viewportWidth, int viewportHeight, boolean orientationMayChange) {
|
int maxVideoHeight, int viewportWidth, int viewportHeight, boolean orientationMayChange) {
|
||||||
|
if (group.length < 2) {
|
||||||
ArrayList<Integer> adaptiveTracksOfGroup = new ArrayList<>(formatSupport.length);
|
|
||||||
for (int i = 0; i < formatSupport.length; i++) {
|
|
||||||
adaptiveTracksOfGroup.add(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (viewportWidth != Integer.MAX_VALUE && viewportHeight != Integer.MAX_VALUE) {
|
|
||||||
filterFormatsForViewport(trackGroup, orientationMayChange, viewportWidth, viewportHeight,
|
|
||||||
adaptiveTracksOfGroup);
|
|
||||||
}
|
|
||||||
|
|
||||||
String mimeType = null;
|
|
||||||
int adaptiveTracksCount = 0;
|
|
||||||
if (!allowMixedMimeTypes) {
|
|
||||||
for (int i = 0; i < trackGroup.length; i++) {
|
|
||||||
if (!Util.areEqual(mimeType, trackGroup.getFormat(i).sampleMimeType)) {
|
|
||||||
int countForMimeType = getAdaptiveTrackCountForMimeType(trackGroup, formatSupport,
|
|
||||||
requiredAdaptiveSupport, trackGroup.getFormat(i).sampleMimeType, maxVideoWidth,
|
|
||||||
maxVideoHeight);
|
|
||||||
if (countForMimeType > adaptiveTracksCount) {
|
|
||||||
adaptiveTracksCount = countForMimeType;
|
|
||||||
mimeType = trackGroup.getFormat(i).sampleMimeType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = adaptiveTracksOfGroup.size() - 1; i >= 0; i--) {
|
|
||||||
if (!isSupportedAdaptiveTrack(trackGroup.getFormat(adaptiveTracksOfGroup.get(i)), mimeType,
|
|
||||||
formatSupport[i], requiredAdaptiveSupport, maxVideoWidth, maxVideoHeight)) {
|
|
||||||
adaptiveTracksOfGroup.remove(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (adaptiveTracksOfGroup.isEmpty()) {
|
|
||||||
// Not enough tracks to allow adaptation.
|
|
||||||
return NO_TRACKS;
|
return NO_TRACKS;
|
||||||
}
|
}
|
||||||
return Util.toArray(adaptiveTracksOfGroup);
|
|
||||||
|
List<Integer> selectedTrackIndices = getViewportFilteredTrackIndices(group, viewportWidth,
|
||||||
|
viewportHeight, orientationMayChange);
|
||||||
|
if (selectedTrackIndices.size() < 2) {
|
||||||
|
return NO_TRACKS;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getAdaptiveTrackCountForMimeType(TrackGroup trackGroup, int[] formatSupport,
|
String selectedMimeType = null;
|
||||||
int requiredAdaptiveSupport, String mimeType, int maxVideoWidth, int maxVideoHeight) {
|
if (!allowMixedMimeTypes) {
|
||||||
int adaptiveTracksCount = 0;
|
// Select the mime type for which we have the most adaptive tracks.
|
||||||
for (int i = 0; i < trackGroup.length; i++) {
|
HashSet<String> seenMimeTypes = new HashSet<>();
|
||||||
if (isSupportedAdaptiveTrack(trackGroup.getFormat(i), mimeType, formatSupport[i],
|
int selectedMimeTypeTrackCount = 0;
|
||||||
requiredAdaptiveSupport, maxVideoWidth, maxVideoHeight)) {
|
for (int i = 0; i < selectedTrackIndices.size(); i++) {
|
||||||
adaptiveTracksCount++;
|
int trackIndex = selectedTrackIndices.get(i);
|
||||||
|
String sampleMimeType = group.getFormat(trackIndex).sampleMimeType;
|
||||||
|
if (!seenMimeTypes.contains(sampleMimeType)) {
|
||||||
|
seenMimeTypes.add(sampleMimeType);
|
||||||
|
int countForMimeType = getAdaptiveTrackCountForMimeType(group, formatSupport,
|
||||||
|
requiredAdaptiveSupport, sampleMimeType, maxVideoWidth, maxVideoHeight,
|
||||||
|
selectedTrackIndices);
|
||||||
|
if (countForMimeType > selectedMimeTypeTrackCount) {
|
||||||
|
selectedMimeType = sampleMimeType;
|
||||||
|
selectedMimeTypeTrackCount = countForMimeType;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return adaptiveTracksCount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isSupportedAdaptiveTrack(Format format, String mimeType, int formatSupport,
|
// Filter by the selected mime type.
|
||||||
int requiredAdaptiveSupport, int maxVideoWidth, int maxVideoHeight) {
|
filterAdaptiveTrackCountForMimeType(group, formatSupport, requiredAdaptiveSupport,
|
||||||
return isSupportedVideoTrack(formatSupport, format, maxVideoWidth, maxVideoHeight)
|
selectedMimeType, maxVideoWidth, maxVideoHeight, selectedTrackIndices);
|
||||||
&& (formatSupport & requiredAdaptiveSupport) != 0
|
|
||||||
&& (mimeType == null || Util.areEqual(format.sampleMimeType, mimeType));
|
return selectedTrackIndices.size() < 2 ? NO_TRACKS : Util.toArray(selectedTrackIndices);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TrackSelection selectSmallestSupportedVideoTrack(TrackGroupArray trackGroups,
|
private static int getAdaptiveTrackCountForMimeType(TrackGroup group, int[] formatSupport,
|
||||||
int[][] formatSupport) {
|
int requiredAdaptiveSupport, String mimeType, int maxVideoWidth, int maxVideoHeight,
|
||||||
int smallestPixelCount = Integer.MAX_VALUE;
|
List<Integer> selectedTrackIndices) {
|
||||||
TrackGroup trackGroupSelection = null;
|
int adaptiveTrackCount = 0;
|
||||||
int trackIndexSelection = -1;
|
for (int i = 0; i < selectedTrackIndices.size(); i++) {
|
||||||
for (int groupIndex = 0; groupIndex < trackGroups.length; groupIndex++) {
|
int trackIndex = selectedTrackIndices.get(i);
|
||||||
TrackGroup trackGroup = trackGroups.get(groupIndex);
|
if (isSupportedAdaptiveVideoTrack(group.getFormat(trackIndex), mimeType,
|
||||||
|
formatSupport[trackIndex], requiredAdaptiveSupport, maxVideoWidth, maxVideoHeight)) {
|
||||||
|
adaptiveTrackCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return adaptiveTrackCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void filterAdaptiveTrackCountForMimeType(TrackGroup group, int[] formatSupport,
|
||||||
|
int requiredAdaptiveSupport, String mimeType, int maxVideoWidth, int maxVideoHeight,
|
||||||
|
List<Integer> selectedTrackIndices) {
|
||||||
|
for (int i = selectedTrackIndices.size() - 1; i >= 0; i--) {
|
||||||
|
int trackIndex = selectedTrackIndices.get(i);
|
||||||
|
if (!isSupportedAdaptiveVideoTrack(group.getFormat(trackIndex), mimeType,
|
||||||
|
formatSupport[trackIndex], requiredAdaptiveSupport, maxVideoWidth, maxVideoHeight)) {
|
||||||
|
selectedTrackIndices.remove(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isSupportedAdaptiveVideoTrack(Format format, String mimeType,
|
||||||
|
int formatSupport, int requiredAdaptiveSupport, int maxVideoWidth, int maxVideoHeight) {
|
||||||
|
return isSupported(formatSupport) && ((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);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TrackSelection selectFixedVideoTrack(TrackGroupArray groups,
|
||||||
|
int[][] formatSupport, int maxVideoWidth, int maxVideoHeight, int viewportWidth,
|
||||||
|
int viewportHeight, boolean orientationMayChange, boolean exceedConstraintsIfNecessary) {
|
||||||
|
TrackGroup selectedGroup = null;
|
||||||
|
int selectedTrackIndex = -1;
|
||||||
|
int selectedPixelCount = Format.NO_VALUE;
|
||||||
|
boolean selectedIsWithinConstraints = false;
|
||||||
|
for (int groupIndex = 0; groupIndex < groups.length; groupIndex++) {
|
||||||
|
TrackGroup group = groups.get(groupIndex);
|
||||||
|
List<Integer> selectedTrackIndices = getViewportFilteredTrackIndices(group, viewportWidth,
|
||||||
|
viewportHeight, orientationMayChange);
|
||||||
int[] trackFormatSupport = formatSupport[groupIndex];
|
int[] trackFormatSupport = formatSupport[groupIndex];
|
||||||
for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
|
for (int trackIndex = 0; trackIndex < group.length; trackIndex++) {
|
||||||
Format format = trackGroup.getFormat(trackIndex);
|
if (isSupported(trackFormatSupport[trackIndex])) {
|
||||||
int pixelCount = format.width * format.height;
|
Format format = group.getFormat(trackIndex);
|
||||||
if (pixelCount < smallestPixelCount
|
boolean isWithinConstraints = selectedTrackIndices.contains(trackIndex)
|
||||||
&& isSupportedVideoTrack(trackFormatSupport[trackIndex], format, Integer.MAX_VALUE,
|
&& (format.width == Format.NO_VALUE || format.width <= maxVideoWidth)
|
||||||
Integer.MAX_VALUE)) {
|
&& (format.height == Format.NO_VALUE || format.height <= maxVideoHeight);
|
||||||
smallestPixelCount = pixelCount;
|
int pixelCount = format.getPixelCount();
|
||||||
trackGroupSelection = trackGroup;
|
boolean selectTrack;
|
||||||
trackIndexSelection = trackIndex;
|
if (selectedIsWithinConstraints) {
|
||||||
|
selectTrack = isWithinConstraints
|
||||||
|
&& comparePixelCounts(pixelCount, selectedPixelCount) > 0;
|
||||||
|
} else {
|
||||||
|
selectTrack = isWithinConstraints || (exceedConstraintsIfNecessary
|
||||||
|
&& (selectedGroup == null
|
||||||
|
|| comparePixelCounts(pixelCount, selectedPixelCount) < 0));
|
||||||
|
}
|
||||||
|
if (selectTrack) {
|
||||||
|
selectedGroup = group;
|
||||||
|
selectedTrackIndex = trackIndex;
|
||||||
|
selectedPixelCount = pixelCount;
|
||||||
|
selectedIsWithinConstraints = isWithinConstraints;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return trackGroupSelection == null ? null
|
}
|
||||||
: new FixedTrackSelection(trackGroupSelection, trackIndexSelection);
|
return selectedGroup == null ? null
|
||||||
|
: new FixedTrackSelection(selectedGroup, selectedTrackIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isSupportedVideoTrack(int formatSupport, Format format, int maxVideoWidth,
|
/**
|
||||||
int maxVideoHeight) {
|
* Compares two pixel counts for order. A known pixel count is considered greater than
|
||||||
return isSupported(formatSupport) && format.width <= maxVideoWidth
|
* {@link Format#NO_VALUE}.
|
||||||
&& format.height <= maxVideoHeight;
|
*
|
||||||
|
* @param first The first pixel count.
|
||||||
|
* @param second The second pixel count.
|
||||||
|
* @return A negative integer if the first pixel count is less than the second. Zero if they are
|
||||||
|
* equal. A positive integer if the first pixel count is greater than the second.
|
||||||
|
*/
|
||||||
|
private static int comparePixelCounts(int first, int second) {
|
||||||
|
return first == Format.NO_VALUE ? (second == Format.NO_VALUE ? 0 : -1)
|
||||||
|
: (second == Format.NO_VALUE ? 1 : (first - second));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Audio track selection implementation.
|
// Audio track selection implementation.
|
||||||
|
|
||||||
private static TrackSelection selectTrackForAudioRenderer(TrackGroupArray trackGroups,
|
private static TrackSelection selectTrackForAudioRenderer(TrackGroupArray groups,
|
||||||
int[][] formatSupport, String preferredLanguage) {
|
int[][] formatSupport, String preferredLanguage) {
|
||||||
if (preferredLanguage != null) {
|
if (preferredLanguage != null) {
|
||||||
for (int groupIndex = 0; groupIndex < trackGroups.length; groupIndex++) {
|
for (int groupIndex = 0; groupIndex < groups.length; groupIndex++) {
|
||||||
TrackGroup trackGroup = trackGroups.get(groupIndex);
|
TrackGroup trackGroup = groups.get(groupIndex);
|
||||||
int[] trackFormatSupport = formatSupport[groupIndex];
|
int[] trackFormatSupport = formatSupport[groupIndex];
|
||||||
for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
|
for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
|
||||||
if (isSupported(trackFormatSupport[trackIndex])
|
if (isSupported(trackFormatSupport[trackIndex])
|
||||||
@ -406,17 +440,17 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// No preferred language was selected or no audio track presented the preferred language.
|
// No preferred language was selected or no audio track presented the preferred language.
|
||||||
return selectFirstSupportedTrack(trackGroups, formatSupport);
|
return selectFirstSupportedTrack(groups, formatSupport);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Text track selection implementation.
|
// Text track selection implementation.
|
||||||
|
|
||||||
private static TrackSelection selectTrackForTextRenderer(TrackGroupArray trackGroups,
|
private static TrackSelection selectTrackForTextRenderer(TrackGroupArray groups,
|
||||||
int[][] formatSupport, String preferredLanguage) {
|
int[][] formatSupport, String preferredLanguage) {
|
||||||
TrackGroup firstForcedGroup = null;
|
TrackGroup firstForcedGroup = null;
|
||||||
int firstForcedTrack = -1;
|
int firstForcedTrack = -1;
|
||||||
for (int groupIndex = 0; groupIndex < trackGroups.length; groupIndex++) {
|
for (int groupIndex = 0; groupIndex < groups.length; groupIndex++) {
|
||||||
TrackGroup trackGroup = trackGroups.get(groupIndex);
|
TrackGroup trackGroup = groups.get(groupIndex);
|
||||||
int[] trackFormatSupport = formatSupport[groupIndex];
|
int[] trackFormatSupport = formatSupport[groupIndex];
|
||||||
for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
|
for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
|
||||||
if (isSupported(trackFormatSupport[trackIndex])
|
if (isSupported(trackFormatSupport[trackIndex])
|
||||||
@ -438,10 +472,10 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
|
|
||||||
// General track selection methods.
|
// General track selection methods.
|
||||||
|
|
||||||
private static TrackSelection selectFirstSupportedTrack(TrackGroupArray trackGroups,
|
private static TrackSelection selectFirstSupportedTrack(TrackGroupArray groups,
|
||||||
int[][] formatSupport) {
|
int[][] formatSupport) {
|
||||||
for (int groupIndex = 0; groupIndex < trackGroups.length; groupIndex++) {
|
for (int groupIndex = 0; groupIndex < groups.length; groupIndex++) {
|
||||||
TrackGroup trackGroup = trackGroups.get(groupIndex);
|
TrackGroup trackGroup = groups.get(groupIndex);
|
||||||
int[] trackFormatSupport = formatSupport[groupIndex];
|
int[] trackFormatSupport = formatSupport[groupIndex];
|
||||||
for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
|
for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
|
||||||
if (isSupported(trackFormatSupport[trackIndex])) {
|
if (isSupported(trackFormatSupport[trackIndex])) {
|
||||||
@ -463,12 +497,22 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
|
|
||||||
// Viewport size util methods.
|
// Viewport size util methods.
|
||||||
|
|
||||||
private static void filterFormatsForViewport(TrackGroup trackGroup, boolean orientationMayChange,
|
private static List<Integer> getViewportFilteredTrackIndices(TrackGroup group, int viewportWidth,
|
||||||
int viewportWidth, int viewportHeight, List<Integer> allowedSizeTrackIndices) {
|
int viewportHeight, boolean orientationMayChange) {
|
||||||
int maxVideoPixelsToRetain = Integer.MAX_VALUE;
|
// Initially include all indices.
|
||||||
|
ArrayList<Integer> selectedTrackIndices = new ArrayList<>(group.length);
|
||||||
|
for (int i = 0; i < group.length; i++) {
|
||||||
|
selectedTrackIndices.add(i);
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < trackGroup.length; i++) {
|
if (viewportWidth == Integer.MAX_VALUE || viewportHeight == Integer.MAX_VALUE) {
|
||||||
Format format = trackGroup.getFormat(i);
|
// Viewport dimensions not set. Return the full set of indices.
|
||||||
|
return selectedTrackIndices;
|
||||||
|
}
|
||||||
|
|
||||||
|
int maxVideoPixelsToRetain = Integer.MAX_VALUE;
|
||||||
|
for (int i = 0; i < group.length; i++) {
|
||||||
|
Format format = group.getFormat(i);
|
||||||
// Keep track of the number of pixels of the selected format whose resolution is the
|
// Keep track of the number of pixels of the selected format whose resolution is the
|
||||||
// smallest to exceed the maximum size at which it can be displayed within the viewport.
|
// smallest to exceed the maximum size at which it can be displayed within the viewport.
|
||||||
// We'll discard formats of higher resolution.
|
// We'll discard formats of higher resolution.
|
||||||
@ -485,15 +529,19 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Filter out formats that exceed maxVideoPixelsToRetain. These formats have an unnecessarily
|
// Filter out formats that exceed maxVideoPixelsToRetain. These formats have an unnecessarily
|
||||||
// high resolution given the size at which the video will be displayed within the viewport.
|
// high resolution given the size at which the video will be displayed within the viewport. Also
|
||||||
|
// filter out formats with unknown dimensions, since we have some whose dimensions are known.
|
||||||
if (maxVideoPixelsToRetain != Integer.MAX_VALUE) {
|
if (maxVideoPixelsToRetain != Integer.MAX_VALUE) {
|
||||||
for (int i = allowedSizeTrackIndices.size() - 1; i >= 0; i--) {
|
for (int i = selectedTrackIndices.size() - 1; i >= 0; i--) {
|
||||||
Format format = trackGroup.getFormat(allowedSizeTrackIndices.get(i));
|
Format format = group.getFormat(selectedTrackIndices.get(i));
|
||||||
if (format.width * format.height > maxVideoPixelsToRetain) {
|
int pixelCount = format.getPixelCount();
|
||||||
allowedSizeTrackIndices.remove(i);
|
if (pixelCount == Format.NO_VALUE || pixelCount > maxVideoPixelsToRetain) {
|
||||||
|
selectedTrackIndices.remove(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return selectedTrackIndices;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -594,4 +642,3 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user