Remove TrackGroup.adaptive flag.

It's only "needed" for HLS, and this requirement will
go away soon. It's safe to remove the flag ahead of
this because a TrackSelector can/should not attempt to
adapt between multiple audio/text tracks.

Also remove unnecessary restrictions on TrackGroups
being non-empty and only of known types.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=128376601
This commit is contained in:
olly 2016-07-25 11:04:31 -07:00 committed by Oliver Woodman
parent d657360341
commit 0b4284d060
8 changed files with 21 additions and 78 deletions

View File

@ -123,7 +123,7 @@ import java.util.Locale;
TrackGroup group = trackGroups.get(groupIndex); TrackGroup group = trackGroups.get(groupIndex);
trackViews[groupIndex] = new CheckedTextView[group.length]; trackViews[groupIndex] = new CheckedTextView[group.length];
for (int trackIndex = 0; trackIndex < group.length; trackIndex++) { for (int trackIndex = 0; trackIndex < group.length; trackIndex++) {
if (trackIndex == 0 || !group.adaptive) { if (trackIndex == 0) {
root.addView(inflater.inflate(R.layout.list_divider, root, false)); root.addView(inflater.inflate(R.layout.list_divider, root, false));
} }
int trackViewLayoutId = group.length < 2 || !trackGroupsAdaptive[groupIndex] int trackViewLayoutId = group.length < 2 || !trackGroupsAdaptive[groupIndex]

View File

@ -20,24 +20,21 @@ import com.google.android.exoplayer2.util.Assertions;
import java.util.Arrays; import java.util.Arrays;
// TODO: Add an allowMultipleStreams boolean to indicate where the one stream per group restriction
// does not apply.
/** /**
* Defines a group of tracks exposed by a {@link MediaPeriod}. * Defines a group of tracks exposed by a {@link MediaPeriod}.
* <p> * <p>
* A {@link MediaPeriod} is only able to provide one {@link SampleStream} corresponding to a group * A {@link MediaPeriod} is only able to provide one {@link SampleStream} corresponding to a group
* at any given time. If {@link #adaptive} is true this {@link SampleStream} can adapt between * at any given time, however this {@link SampleStream} may adapt between multiple tracks within the
* multiple tracks within the group. If {@link #adaptive} is false then it's only possible to * group.
* consume one track from the group at a given time.
*/ */
public final class TrackGroup { public final class TrackGroup {
/** /**
* The number of tracks in the group. Always greater than zero. * The number of tracks in the group.
*/ */
public final int length; public final int length;
/**
* Whether it's possible to adapt between multiple tracks in the group.
*/
public final boolean adaptive;
private final Format[] formats; private final Format[] formats;
@ -45,19 +42,10 @@ public final class TrackGroup {
private int hashCode; private int hashCode;
/** /**
* @param format The format of the single track. * @param formats The track formats. Must not be null or contain null elements.
*/ */
public TrackGroup(Format format) { public TrackGroup(Format... formats) {
this(false, Assertions.checkNotNull(format));
}
/**
* @param adaptive Whether it's possible to adapt between multiple tracks in the group.
* @param formats The track formats. Must not be null or empty. Must not contain null elements.
*/
public TrackGroup(boolean adaptive, Format... formats) {
Assertions.checkState(formats.length > 0); Assertions.checkState(formats.length > 0);
this.adaptive = adaptive;
this.formats = formats; this.formats = formats;
this.length = formats.length; this.length = formats.length;
} }
@ -91,7 +79,6 @@ public final class TrackGroup {
public int hashCode() { public int hashCode() {
if (hashCode == 0) { if (hashCode == 0) {
int result = 17; int result = 17;
result = 31 * result + (adaptive ? 1231 : 1237);
result = 31 * result + Arrays.hashCode(formats); result = 31 * result + Arrays.hashCode(formats);
hashCode = result; hashCode = result;
} }
@ -107,8 +94,7 @@ public final class TrackGroup {
return false; return false;
} }
TrackGroup other = (TrackGroup) obj; TrackGroup other = (TrackGroup) obj;
return adaptive == other.adaptive && length == other.length return length == other.length && Arrays.equals(formats, other.formats);
&& Arrays.equals(formats, other.formats);
} }
} }

View File

@ -33,10 +33,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.Loader; import com.google.android.exoplayer2.upstream.Loader;
import android.util.Pair;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays;
import java.util.List; import java.util.List;
/** /**
@ -52,7 +49,6 @@ import java.util.List;
private final Loader loader; private final Loader loader;
private final long durationUs; private final long durationUs;
private final TrackGroupArray trackGroups; private final TrackGroupArray trackGroups;
private final int[] trackGroupAdaptationSetIndices;
private ChunkSampleStream<DashChunkSource>[] sampleStreams; private ChunkSampleStream<DashChunkSource>[] sampleStreams;
private CompositeSequenceableLoader sequenceableLoader; private CompositeSequenceableLoader sequenceableLoader;
@ -74,9 +70,7 @@ import java.util.List;
this.loader = loader; this.loader = loader;
durationUs = manifest.dynamic ? C.UNSET_TIME_US : manifest.getPeriodDuration(index) * 1000; durationUs = manifest.dynamic ? C.UNSET_TIME_US : manifest.getPeriodDuration(index) * 1000;
period = manifest.getPeriod(index); period = manifest.getPeriod(index);
Pair<TrackGroupArray, int[]> trackGroupsAndAdaptationSetIndices = buildTrackGroups(period); trackGroups = buildTrackGroups(period);
trackGroups = trackGroupsAndAdaptationSetIndices.first;
trackGroupAdaptationSetIndices = trackGroupsAndAdaptationSetIndices.second;
} }
public void updateManifest(DashManifest manifest, int index) { public void updateManifest(DashManifest manifest, int index) {
@ -206,37 +200,23 @@ import java.util.List;
// Internal methods. // Internal methods.
private static Pair<TrackGroupArray, int[]> buildTrackGroups(Period period) { private static TrackGroupArray buildTrackGroups(Period period) {
int trackGroupCount = 0;
int[] trackGroupAdaptationSetIndices = new int[period.adaptationSets.size()];
TrackGroup[] trackGroupArray = new TrackGroup[period.adaptationSets.size()]; TrackGroup[] trackGroupArray = new TrackGroup[period.adaptationSets.size()];
for (int i = 0; i < period.adaptationSets.size(); i++) { for (int i = 0; i < period.adaptationSets.size(); i++) {
AdaptationSet adaptationSet = period.adaptationSets.get(i); AdaptationSet adaptationSet = period.adaptationSets.get(i);
int adaptationSetType = adaptationSet.type;
List<Representation> representations = adaptationSet.representations; List<Representation> representations = adaptationSet.representations;
if (!representations.isEmpty() && (adaptationSetType == C.TRACK_TYPE_AUDIO
|| adaptationSetType == C.TRACK_TYPE_VIDEO || adaptationSetType == C.TRACK_TYPE_TEXT)) {
Format[] formats = new Format[representations.size()]; Format[] formats = new Format[representations.size()];
for (int j = 0; j < formats.length; j++) { for (int j = 0; j < formats.length; j++) {
formats[j] = representations.get(j).format; formats[j] = representations.get(j).format;
} }
trackGroupAdaptationSetIndices[trackGroupCount] = i; trackGroupArray[i] = new TrackGroup(formats);
boolean adaptive = adaptationSetType == C.TRACK_TYPE_VIDEO;
trackGroupArray[trackGroupCount++] = new TrackGroup(adaptive, formats);
} }
} return new TrackGroupArray(trackGroupArray);
if (trackGroupCount < trackGroupArray.length) {
trackGroupAdaptationSetIndices = Arrays.copyOf(trackGroupAdaptationSetIndices,
trackGroupCount);
trackGroupArray = Arrays.copyOf(trackGroupArray, trackGroupCount);
}
TrackGroupArray trackGroups = new TrackGroupArray(trackGroupArray);
return Pair.create(trackGroups, trackGroupAdaptationSetIndices);
} }
private ChunkSampleStream<DashChunkSource> buildSampleStream(TrackSelection selection, private ChunkSampleStream<DashChunkSource> buildSampleStream(TrackSelection selection,
long positionUs) { long positionUs) {
int adaptationSetIndex = trackGroupAdaptationSetIndices[trackGroups.indexOf(selection.group)]; int adaptationSetIndex = trackGroups.indexOf(selection.group);
AdaptationSet adaptationSet = period.adaptationSets.get(adaptationSetIndex); AdaptationSet adaptationSet = period.adaptationSets.get(adaptationSetIndex);
DashChunkSource chunkSource = chunkSourceFactory.createDashChunkSource(loader, manifest, index, DashChunkSource chunkSource = chunkSourceFactory.createDashChunkSource(loader, manifest, index,
adaptationSetIndex, selection, elapsedRealtimeOffset); adaptationSetIndex, selection, elapsedRealtimeOffset);

View File

@ -126,7 +126,7 @@ public class HlsChunkSource {
variantFormats[i] = variants[i].format; variantFormats[i] = variants[i].format;
initialTrackSelection[i] = i; initialTrackSelection[i] = i;
} }
trackGroup = new TrackGroup(formatEvaluator != null, variantFormats); trackGroup = new TrackGroup(variantFormats);
selectTracksInternal(new TrackSelection(trackGroup, initialTrackSelection), false); selectTracksInternal(new TrackSelection(trackGroup, initialTrackSelection), false);
} }

View File

@ -543,7 +543,7 @@ import java.util.List;
for (int j = 0; j < chunkSourceTrackCount; j++) { for (int j = 0; j < chunkSourceTrackCount; j++) {
formats[j] = getSampleFormat(chunkSourceTrackGroup.getFormat(j), sampleFormat); formats[j] = getSampleFormat(chunkSourceTrackGroup.getFormat(j), sampleFormat);
} }
trackGroups[i] = new TrackGroup(chunkSourceTrackGroup.adaptive, formats); trackGroups[i] = new TrackGroup(formats);
primaryTrackGroupIndex = i; primaryTrackGroupIndex = i;
} else { } else {
Format trackFormat = null; Format trackFormat = null;

View File

@ -49,7 +49,6 @@ import android.os.SystemClock;
import android.util.Base64; import android.util.Base64;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays;
import java.util.List; import java.util.List;
/** /**
@ -90,7 +89,6 @@ public final class SsMediaSource implements MediaPeriod, MediaSource,
private long durationUs; private long durationUs;
private TrackEncryptionBox[] trackEncryptionBoxes; private TrackEncryptionBox[] trackEncryptionBoxes;
private TrackGroupArray trackGroups; private TrackGroupArray trackGroups;
private int[] trackGroupElementIndices;
public SsMediaSource(Uri manifestUri, DataSource.Factory manifestDataSourceFactory, public SsMediaSource(Uri manifestUri, DataSource.Factory manifestDataSourceFactory,
SsChunkSource.Factory chunkSourceFactory, Handler eventHandler, SsChunkSource.Factory chunkSourceFactory, Handler eventHandler,
@ -254,7 +252,6 @@ public final class SsMediaSource implements MediaPeriod, MediaSource,
durationUs = 0; durationUs = 0;
trackEncryptionBoxes = null; trackEncryptionBoxes = null;
trackGroups = null; trackGroups = null;
trackGroupElementIndices = null;
} }
// SequenceableLoader.Callback implementation // SequenceableLoader.Callback implementation
@ -337,30 +334,18 @@ public final class SsMediaSource implements MediaPeriod, MediaSource,
} }
private void buildTrackGroups(SsManifest manifest) { private void buildTrackGroups(SsManifest manifest) {
int trackGroupCount = 0;
trackGroupElementIndices = new int[manifest.streamElements.length];
TrackGroup[] trackGroupArray = new TrackGroup[manifest.streamElements.length]; TrackGroup[] trackGroupArray = new TrackGroup[manifest.streamElements.length];
for (int i = 0; i < manifest.streamElements.length; i++) { for (int i = 0; i < manifest.streamElements.length; i++) {
StreamElement streamElement = manifest.streamElements[i]; StreamElement streamElement = manifest.streamElements[i];
int streamElementType = streamElement.type;
Format[] formats = streamElement.formats; Format[] formats = streamElement.formats;
if (formats.length > 0 && (streamElementType == C.TRACK_TYPE_AUDIO trackGroupArray[i] = new TrackGroup(formats);
|| streamElementType == C.TRACK_TYPE_VIDEO || streamElementType == C.TRACK_TYPE_TEXT)) {
trackGroupElementIndices[trackGroupCount] = i;
boolean adaptive = streamElementType == C.TRACK_TYPE_VIDEO;
trackGroupArray[trackGroupCount++] = new TrackGroup(adaptive, formats);
}
}
if (trackGroupCount < trackGroupArray.length) {
trackGroupElementIndices = Arrays.copyOf(trackGroupElementIndices, trackGroupCount);
trackGroupArray = Arrays.copyOf(trackGroupArray, trackGroupCount);
} }
trackGroups = new TrackGroupArray(trackGroupArray); trackGroups = new TrackGroupArray(trackGroupArray);
} }
private ChunkSampleStream<SsChunkSource> buildSampleStream(TrackSelection selection, private ChunkSampleStream<SsChunkSource> buildSampleStream(TrackSelection selection,
long positionUs) { long positionUs) {
int streamElementIndex = trackGroupElementIndices[trackGroups.indexOf(selection.group)]; int streamElementIndex = trackGroups.indexOf(selection.group);
SsChunkSource chunkSource = chunkSourceFactory.createChunkSource(manifestLoader, manifest, SsChunkSource chunkSource = chunkSourceFactory.createChunkSource(manifestLoader, manifest,
streamElementIndex, selection, trackEncryptionBoxes); streamElementIndex, selection, trackEncryptionBoxes);
return new ChunkSampleStream<>(manifest.streamElements[streamElementIndex].type, chunkSource, return new ChunkSampleStream<>(manifest.streamElements[streamElementIndex].type, chunkSource,

View File

@ -208,10 +208,6 @@ public class DefaultTrackSelector extends MappingTrackSelector {
private static int[] getAdaptiveTracksOfGroup(TrackGroup trackGroup, int[] formatSupport, private static int[] getAdaptiveTracksOfGroup(TrackGroup trackGroup, int[] formatSupport,
boolean allowMixedMimeTypes, int requiredAdaptiveSupport, int maxVideoWidth, boolean allowMixedMimeTypes, int requiredAdaptiveSupport, int maxVideoWidth,
int maxVideoHeight) { int maxVideoHeight) {
if (!trackGroup.adaptive) {
return NO_TRACKS;
}
String mimeType = null; String mimeType = null;
int adaptiveTracksCount = 0; int adaptiveTracksCount = 0;
if (allowMixedMimeTypes) { if (allowMixedMimeTypes) {

View File

@ -560,10 +560,6 @@ public abstract class MappingTrackSelector extends TrackSelector {
* {@link RendererCapabilities#ADAPTIVE_NOT_SUPPORTED}. * {@link RendererCapabilities#ADAPTIVE_NOT_SUPPORTED}.
*/ */
public int getAdaptiveSupport(int rendererIndex, int groupIndex, int[] trackIndices) { public int getAdaptiveSupport(int rendererIndex, int groupIndex, int[] trackIndices) {
TrackGroup trackGroup = trackGroups[rendererIndex].get(groupIndex);
if (!trackGroup.adaptive) {
return RendererCapabilities.ADAPTIVE_NOT_SUPPORTED;
}
int handledTrackCount = 0; int handledTrackCount = 0;
int adaptiveSupport = RendererCapabilities.ADAPTIVE_SEAMLESS; int adaptiveSupport = RendererCapabilities.ADAPTIVE_SEAMLESS;
boolean multipleMimeTypes = false; boolean multipleMimeTypes = false;