Add first default track selection policies

With this CL:
* The first supported video track found is selected.
* The first supported audio track with preferred language is selected.
  If none, we fallback to the first supported one.
* For text, we only present a selection if one of the tracks has the
  preferred language and the track is flagged as forced.

TODO list:
* Add a selection policy for video (probably related with adaptiveness).
* We should decide what to do with the default flag.
* Perhaps, if no audio with the preferred language(assuming there is one)
  is found, we should fall back to a text track that has the preferred
  language.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=122985006
This commit is contained in:
aquilescanta 2016-05-23 04:27:15 -07:00 committed by Oliver Woodman
parent 58953d370f
commit c539db68ca

View File

@ -15,32 +15,78 @@
*/ */
package com.google.android.exoplayer; package com.google.android.exoplayer;
import com.google.android.exoplayer.util.Util;
/** /**
* A {@link TrackSelectionPolicy} that allows configuration of common parameters. * A {@link TrackSelectionPolicy} that allows configuration of common parameters.
*/ */
public class DefaultTrackSelectionPolicy extends TrackSelectionPolicy { public class DefaultTrackSelectionPolicy extends TrackSelectionPolicy {
private String preferredLanguage;
public void setPreferredLanguage(String preferredLanguage) {
if (!Util.areEqual(this.preferredLanguage, preferredLanguage)) {
this.preferredLanguage = preferredLanguage;
invalidate();
}
}
@Override @Override
public TrackSelection[] selectTracks(TrackRenderer[] renderers, public TrackSelection[] selectTracks(TrackRenderer[] renderers,
TrackGroupArray[] rendererTrackGroupArrays, int[][][] rendererFormatSupports) { TrackGroupArray[] rendererTrackGroupArrays, int[][][] rendererFormatSupports) {
// Make a track selection for each renderer. // Make a track selection for each renderer.
TrackSelection[] rendererTrackSelections = new TrackSelection[renderers.length]; TrackSelection[] rendererTrackSelections = new TrackSelection[renderers.length];
for (int i = 0; i < renderers.length; i++) { for (int i = 0; i < renderers.length; i++) {
rendererTrackSelections[i] = selectTracksForRenderer(rendererTrackGroupArrays[i], switch (renderers[i].getTrackType()) {
rendererFormatSupports[i]); case C.TRACK_TYPE_AUDIO:
rendererTrackSelections[i] = selectTrackForAudioRenderer(
rendererTrackGroupArrays[i], rendererFormatSupports[i], preferredLanguage);
break;
case C.TRACK_TYPE_TEXT:
rendererTrackSelections[i] = selectTrackForTextRenderer(rendererTrackGroupArrays[i],
rendererFormatSupports[i], preferredLanguage);
break;
default:
rendererTrackSelections[i] = selectFirstSupportedTrack(rendererTrackGroupArrays[i],
rendererFormatSupports[i]);
break;
}
} }
return rendererTrackSelections; return rendererTrackSelections;
} }
private static TrackSelection selectTracksForRenderer(TrackGroupArray trackGroups, private TrackSelection selectTrackForTextRenderer(TrackGroupArray trackGroups,
int[][] formatSupport) { int[][] formatSupport, String preferredLanguage) {
// TODO: Allow more specific track selection parameters. int firstForcedGroup = -1;
int firstForcedTrack = -1;
for (int groupIndex = 0; groupIndex < trackGroups.length; groupIndex++) { for (int groupIndex = 0; groupIndex < trackGroups.length; groupIndex++) {
TrackGroup trackGroup = trackGroups.get(groupIndex); TrackGroup trackGroup = trackGroups.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 ((trackFormatSupport[trackIndex] & TrackRenderer.FORMAT_SUPPORT_MASK) if (isSupported(trackFormatSupport[trackIndex])
== TrackRenderer.FORMAT_HANDLED) { && (trackGroup.getFormat(trackIndex).selectionFlags
& Format.SELECTION_FLAG_FORCED) != 0) {
if (firstForcedGroup == -1) {
firstForcedGroup = groupIndex;
firstForcedTrack = trackIndex;
}
if (preferredLanguage != null
&& preferredLanguage.equals(trackGroup.getFormat(trackIndex).language)) {
return new TrackSelection(groupIndex, trackIndex);
}
}
}
}
return firstForcedGroup != -1 ? new TrackSelection(firstForcedGroup, firstForcedTrack) : null;
}
private static TrackSelection selectFirstSupportedTrack(TrackGroupArray trackGroups,
int[][] formatSupport) {
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 (isSupported(trackFormatSupport[trackIndex])) {
return new TrackSelection(groupIndex, trackIndex); return new TrackSelection(groupIndex, trackIndex);
} }
} }
@ -48,5 +94,27 @@ public class DefaultTrackSelectionPolicy extends TrackSelectionPolicy {
return null; return null;
} }
private static TrackSelection selectTrackForAudioRenderer(TrackGroupArray trackGroups,
int[][] formatSupport, String preferredLanguage) {
if (preferredLanguage != null) {
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 (isSupported(trackFormatSupport[trackIndex])
&& preferredLanguage.equals(trackGroup.getFormat(trackIndex).language)) {
return new TrackSelection(groupIndex, trackIndex);
}
}
}
}
// No preferred language was selected or no audio track presented the preferred language.
return selectFirstSupportedTrack(trackGroups, formatSupport);
}
private static boolean isSupported(int formatSupport) {
return (formatSupport & TrackRenderer.FORMAT_SUPPORT_MASK) == TrackRenderer.FORMAT_HANDLED;
}
} }