Commit eb3460b3 by olly Committed by Oliver Woodman

Refactor #6.2: Start to simplify components.

Parse the duration of the media directly from the manifest
in the DASH/SS SampleSource implementations.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=121001296
parent b38d0045
...@@ -43,7 +43,7 @@ import java.util.List; ...@@ -43,7 +43,7 @@ import java.util.List;
* A {@link SampleSource} that loads media in {@link Chunk}s, which are themselves obtained from a * A {@link SampleSource} that loads media in {@link Chunk}s, which are themselves obtained from a
* {@link ChunkSource}. * {@link ChunkSource}.
*/ */
public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Callback { public class ChunkSampleSource implements TrackStream, Loader.Callback {
/** /**
* The default minimum number of times to retry loading data prior to failing. * The default minimum number of times to retry loading data prior to failing.
...@@ -60,7 +60,6 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call ...@@ -60,7 +60,6 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call
private final EventDispatcher eventDispatcher; private final EventDispatcher eventDispatcher;
private final LoadControl loadControl; private final LoadControl loadControl;
private boolean prepared;
private boolean notifyReset; private boolean notifyReset;
private long lastPreferredQueueSizeEvaluationTimeMs; private long lastPreferredQueueSizeEvaluationTimeMs;
private Format downstreamFormat; private Format downstreamFormat;
...@@ -130,35 +129,21 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call ...@@ -130,35 +129,21 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call
// SampleSource implementation. // SampleSource implementation.
@Override public void prepare() {
public boolean prepare(long positionUs) throws IOException {
if (prepared) {
return true;
}
TrackGroup tracks = chunkSource.getTracks(); TrackGroup tracks = chunkSource.getTracks();
if (tracks != null) { if (tracks != null) {
trackGroups = new TrackGroupArray(tracks); trackGroups = new TrackGroupArray(tracks);
} else { } else {
trackGroups = new TrackGroupArray(); trackGroups = new TrackGroupArray();
} }
prepared = true;
return true;
} }
@Override
public long getDurationUs() {
return chunkSource.getDurationUs();
}
@Override
public TrackGroupArray getTrackGroups() { public TrackGroupArray getTrackGroups() {
return trackGroups; return trackGroups;
} }
@Override
public TrackStream[] selectTracks(List<TrackStream> oldStreams, public TrackStream[] selectTracks(List<TrackStream> oldStreams,
List<TrackSelection> newSelections, long positionUs) { List<TrackSelection> newSelections, long positionUs) {
Assertions.checkState(prepared);
Assertions.checkState(oldStreams.size() <= 1); Assertions.checkState(oldStreams.size() <= 1);
Assertions.checkState(newSelections.size() <= 1); Assertions.checkState(newSelections.size() <= 1);
boolean trackWasEnabled = trackEnabled; boolean trackWasEnabled = trackEnabled;
...@@ -201,7 +186,6 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call ...@@ -201,7 +186,6 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call
return newStreams; return newStreams;
} }
@Override
public void continueBuffering(long positionUs) { public void continueBuffering(long positionUs) {
downstreamPositionUs = positionUs; downstreamPositionUs = positionUs;
if (!loader.isLoading()) { if (!loader.isLoading()) {
...@@ -209,7 +193,6 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call ...@@ -209,7 +193,6 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call
} }
} }
@Override
public long readReset() { public long readReset() {
if (notifyReset) { if (notifyReset) {
notifyReset = false; notifyReset = false;
...@@ -218,7 +201,6 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call ...@@ -218,7 +201,6 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call
return C.UNSET_TIME_US; return C.UNSET_TIME_US;
} }
@Override
public long getBufferedPositionUs() { public long getBufferedPositionUs() {
if (loadingFinished) { if (loadingFinished) {
return C.END_OF_SOURCE_US; return C.END_OF_SOURCE_US;
...@@ -236,7 +218,6 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call ...@@ -236,7 +218,6 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call
} }
} }
@Override
public void seekToUs(long positionUs) { public void seekToUs(long positionUs) {
downstreamPositionUs = positionUs; downstreamPositionUs = positionUs;
lastSeekPositionUs = positionUs; lastSeekPositionUs = positionUs;
...@@ -256,7 +237,6 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call ...@@ -256,7 +237,6 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call
notifyReset = true; notifyReset = true;
} }
@Override
public void release() { public void release() {
if (trackEnabled) { if (trackEnabled) {
loadControl.unregister(this); loadControl.unregister(this);
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
*/ */
package com.google.android.exoplayer.chunk; package com.google.android.exoplayer.chunk;
import com.google.android.exoplayer.C;
import com.google.android.exoplayer.TrackGroup; import com.google.android.exoplayer.TrackGroup;
import java.io.IOException; import java.io.IOException;
...@@ -42,16 +41,6 @@ public interface ChunkSource { ...@@ -42,16 +41,6 @@ public interface ChunkSource {
void maybeThrowError() throws IOException; void maybeThrowError() throws IOException;
/** /**
* Gets the duration of the source in microseconds.
* <p>
* This method should only be called after the source has been prepared.
*
* @return The duration of the source in microseconds, or {@link C#UNSET_TIME_US} if the duration
* is unknown.
*/
long getDurationUs();
/**
* Gets the group of tracks provided by the source. * Gets the group of tracks provided by the source.
* <p> * <p>
* This method should only be called after the source has been prepared. * This method should only be called after the source has been prepared.
......
...@@ -71,10 +71,6 @@ public class DashChunkSource implements ChunkSource { ...@@ -71,10 +71,6 @@ public class DashChunkSource implements ChunkSource {
private final FormatEvaluator adaptiveFormatEvaluator; private final FormatEvaluator adaptiveFormatEvaluator;
private final Evaluation evaluation; private final Evaluation evaluation;
// Properties of the initial manifest.
private boolean live;
private long durationUs;
private MediaPresentationDescription currentManifest; private MediaPresentationDescription currentManifest;
private DrmInitData drmInitData; private DrmInitData drmInitData;
...@@ -119,11 +115,6 @@ public class DashChunkSource implements ChunkSource { ...@@ -119,11 +115,6 @@ public class DashChunkSource implements ChunkSource {
} }
@Override @Override
public long getDurationUs() {
return durationUs;
}
@Override
public final TrackGroup getTracks() { public final TrackGroup getTracks() {
return trackGroup; return trackGroup;
} }
...@@ -293,9 +284,6 @@ public class DashChunkSource implements ChunkSource { ...@@ -293,9 +284,6 @@ public class DashChunkSource implements ChunkSource {
private void initForManifest(MediaPresentationDescription manifest) { private void initForManifest(MediaPresentationDescription manifest) {
Period period = manifest.getPeriod(0); Period period = manifest.getPeriod(0);
live = currentManifest.dynamic;
durationUs = live ? C.UNSET_TIME_US : currentManifest.duration * 1000;
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);
if (adaptationSet.type == adaptationSetType) { if (adaptationSet.type == adaptationSetType) {
......
...@@ -52,8 +52,8 @@ public final class DashSampleSource implements SampleSource { ...@@ -52,8 +52,8 @@ public final class DashSampleSource implements SampleSource {
private final ManifestFetcher<MediaPresentationDescription> manifestFetcher; private final ManifestFetcher<MediaPresentationDescription> manifestFetcher;
private final DashChunkSource[] chunkSources; private final DashChunkSource[] chunkSources;
private final SampleSource[] sources; private final ChunkSampleSource[] sources;
private final IdentityHashMap<TrackStream, SampleSource> trackStreamSources; private final IdentityHashMap<TrackStream, ChunkSampleSource> trackStreamSources;
private final int[] selectedTrackCounts; private final int[] selectedTrackCounts;
private MediaPresentationDescription currentManifest; private MediaPresentationDescription currentManifest;
...@@ -61,7 +61,7 @@ public final class DashSampleSource implements SampleSource { ...@@ -61,7 +61,7 @@ public final class DashSampleSource implements SampleSource {
private boolean seenFirstTrackSelection; private boolean seenFirstTrackSelection;
private long durationUs; private long durationUs;
private TrackGroupArray trackGroups; private TrackGroupArray trackGroups;
private SampleSource[] enabledSources; private ChunkSampleSource[] enabledSources;
public DashSampleSource(Uri uri, DataSourceFactory dataSourceFactory, public DashSampleSource(Uri uri, DataSourceFactory dataSourceFactory,
BandwidthMeter bandwidthMeter, Handler eventHandler, BandwidthMeter bandwidthMeter, Handler eventHandler,
...@@ -94,7 +94,7 @@ public final class DashSampleSource implements SampleSource { ...@@ -94,7 +94,7 @@ public final class DashSampleSource implements SampleSource {
C.DEFAULT_TEXT_BUFFER_SIZE, eventHandler, eventListener, C.TRACK_TYPE_TEXT); C.DEFAULT_TEXT_BUFFER_SIZE, eventHandler, eventListener, C.TRACK_TYPE_TEXT);
chunkSources = new DashChunkSource[] {videoChunkSource, audioChunkSource, textChunkSource}; chunkSources = new DashChunkSource[] {videoChunkSource, audioChunkSource, textChunkSource};
sources = new SampleSource[] {videoSampleSource, audioSampleSource, textSampleSource}; sources = new ChunkSampleSource[] {videoSampleSource, audioSampleSource, textSampleSource};
trackStreamSources = new IdentityHashMap<>(); trackStreamSources = new IdentityHashMap<>();
selectedTrackCounts = new int[sources.length]; selectedTrackCounts = new int[sources.length];
} }
...@@ -112,32 +112,23 @@ public final class DashSampleSource implements SampleSource { ...@@ -112,32 +112,23 @@ public final class DashSampleSource implements SampleSource {
manifestFetcher.requestRefresh(); manifestFetcher.requestRefresh();
return false; return false;
} else { } else {
durationUs = currentManifest.dynamic ? C.UNSET_TIME_US : currentManifest.duration * 1000;
for (DashChunkSource chunkSource : chunkSources) { for (DashChunkSource chunkSource : chunkSources) {
chunkSource.init(currentManifest); chunkSource.init(currentManifest);
} }
} }
} }
boolean sourcesPrepared = true; for (ChunkSampleSource source : sources) {
for (SampleSource source : sources) { source.prepare();
sourcesPrepared &= source.prepare(positionUs);
} }
if (!sourcesPrepared) {
return false;
}
durationUs = 0;
int totalTrackGroupCount = 0; int totalTrackGroupCount = 0;
for (SampleSource source : sources) { for (ChunkSampleSource source : sources) {
totalTrackGroupCount += source.getTrackGroups().length; totalTrackGroupCount += source.getTrackGroups().length;
if (durationUs != C.UNSET_TIME_US) {
long sourceDurationUs = source.getDurationUs();
durationUs = sourceDurationUs == C.UNSET_TIME_US
? C.UNSET_TIME_US : Math.max(durationUs, sourceDurationUs);
}
} }
TrackGroup[] trackGroupArray = new TrackGroup[totalTrackGroupCount]; TrackGroup[] trackGroupArray = new TrackGroup[totalTrackGroupCount];
int trackGroupIndex = 0; int trackGroupIndex = 0;
for (SampleSource source : sources) { for (ChunkSampleSource source : sources) {
int sourceTrackGroupCount = source.getTrackGroups().length; int sourceTrackGroupCount = source.getTrackGroups().length;
for (int j = 0; j < sourceTrackGroupCount; j++) { for (int j = 0; j < sourceTrackGroupCount; j++) {
trackGroupArray[trackGroupIndex++] = source.getTrackGroups().get(j); trackGroupArray[trackGroupIndex++] = source.getTrackGroups().get(j);
...@@ -173,7 +164,7 @@ public final class DashSampleSource implements SampleSource { ...@@ -173,7 +164,7 @@ public final class DashSampleSource implements SampleSource {
} }
} }
// Update the enabled sources. // Update the enabled sources.
enabledSources = new SampleSource[enabledSourceCount]; enabledSources = new ChunkSampleSource[enabledSourceCount];
enabledSourceCount = 0; enabledSourceCount = 0;
for (int i = 0; i < sources.length; i++) { for (int i = 0; i < sources.length; i++) {
if (selectedTrackCounts[i] > 0) { if (selectedTrackCounts[i] > 0) {
...@@ -210,7 +201,7 @@ public final class DashSampleSource implements SampleSource { ...@@ -210,7 +201,7 @@ public final class DashSampleSource implements SampleSource {
} }
} }
for (SampleSource source : enabledSources) { for (ChunkSampleSource source : enabledSources) {
source.continueBuffering(positionUs); source.continueBuffering(positionUs);
} }
} }
...@@ -218,7 +209,7 @@ public final class DashSampleSource implements SampleSource { ...@@ -218,7 +209,7 @@ public final class DashSampleSource implements SampleSource {
@Override @Override
public long readReset() { public long readReset() {
long resetPositionUs = C.UNSET_TIME_US; long resetPositionUs = C.UNSET_TIME_US;
for (SampleSource source : enabledSources) { for (ChunkSampleSource source : enabledSources) {
long childResetPositionUs = source.readReset(); long childResetPositionUs = source.readReset();
if (resetPositionUs == C.UNSET_TIME_US) { if (resetPositionUs == C.UNSET_TIME_US) {
resetPositionUs = childResetPositionUs; resetPositionUs = childResetPositionUs;
...@@ -232,7 +223,7 @@ public final class DashSampleSource implements SampleSource { ...@@ -232,7 +223,7 @@ public final class DashSampleSource implements SampleSource {
@Override @Override
public long getBufferedPositionUs() { public long getBufferedPositionUs() {
long bufferedPositionUs = durationUs != C.UNSET_TIME_US ? durationUs : Long.MAX_VALUE; long bufferedPositionUs = durationUs != C.UNSET_TIME_US ? durationUs : Long.MAX_VALUE;
for (SampleSource source : enabledSources) { for (ChunkSampleSource source : enabledSources) {
long rendererBufferedPositionUs = source.getBufferedPositionUs(); long rendererBufferedPositionUs = source.getBufferedPositionUs();
if (rendererBufferedPositionUs == C.UNSET_TIME_US) { if (rendererBufferedPositionUs == C.UNSET_TIME_US) {
return C.UNSET_TIME_US; return C.UNSET_TIME_US;
...@@ -247,7 +238,7 @@ public final class DashSampleSource implements SampleSource { ...@@ -247,7 +238,7 @@ public final class DashSampleSource implements SampleSource {
@Override @Override
public void seekToUs(long positionUs) { public void seekToUs(long positionUs) {
for (SampleSource source : enabledSources) { for (ChunkSampleSource source : enabledSources) {
source.seekToUs(positionUs); source.seekToUs(positionUs);
} }
} }
...@@ -255,14 +246,14 @@ public final class DashSampleSource implements SampleSource { ...@@ -255,14 +246,14 @@ public final class DashSampleSource implements SampleSource {
@Override @Override
public void release() { public void release() {
manifestFetcher.release(); manifestFetcher.release();
for (SampleSource source : sources) { for (ChunkSampleSource source : sources) {
source.release(); source.release();
} }
} }
// Internal methods. // Internal methods.
private int selectTracks(SampleSource source, List<TrackStream> allOldStreams, private int selectTracks(ChunkSampleSource source, List<TrackStream> allOldStreams,
List<TrackSelection> allNewSelections, long positionUs, TrackStream[] allNewStreams) { List<TrackSelection> allNewSelections, long positionUs, TrackStream[] allNewStreams) {
// Get the subset of the old streams for the source. // Get the subset of the old streams for the source.
ArrayList<TrackStream> oldStreams = new ArrayList<>(); ArrayList<TrackStream> oldStreams = new ArrayList<>();
...@@ -278,7 +269,7 @@ public final class DashSampleSource implements SampleSource { ...@@ -278,7 +269,7 @@ public final class DashSampleSource implements SampleSource {
int[] newSelectionOriginalIndices = new int[allNewSelections.size()]; int[] newSelectionOriginalIndices = new int[allNewSelections.size()];
for (int i = 0; i < allNewSelections.size(); i++) { for (int i = 0; i < allNewSelections.size(); i++) {
TrackSelection selection = allNewSelections.get(i); TrackSelection selection = allNewSelections.get(i);
Pair<SampleSource, Integer> sourceAndGroup = getSourceAndGroup(selection.group); Pair<ChunkSampleSource, Integer> sourceAndGroup = getSourceAndGroup(selection.group);
if (sourceAndGroup.first == source) { if (sourceAndGroup.first == source) {
newSelectionOriginalIndices[newSelections.size()] = i; newSelectionOriginalIndices[newSelections.size()] = i;
newSelections.add(new TrackSelection(sourceAndGroup.second, selection.getTracks())); newSelections.add(new TrackSelection(sourceAndGroup.second, selection.getTracks()));
...@@ -297,9 +288,9 @@ public final class DashSampleSource implements SampleSource { ...@@ -297,9 +288,9 @@ public final class DashSampleSource implements SampleSource {
return newSelections.size() - oldStreams.size(); return newSelections.size() - oldStreams.size();
} }
private Pair<SampleSource, Integer> getSourceAndGroup(int group) { private Pair<ChunkSampleSource, Integer> getSourceAndGroup(int group) {
int totalTrackGroupCount = 0; int totalTrackGroupCount = 0;
for (SampleSource source : sources) { for (ChunkSampleSource source : sources) {
int sourceTrackGroupCount = source.getTrackGroups().length; int sourceTrackGroupCount = source.getTrackGroups().length;
if (group < totalTrackGroupCount + sourceTrackGroupCount) { if (group < totalTrackGroupCount + sourceTrackGroupCount) {
return Pair.create(source, group - totalTrackGroupCount); return Pair.create(source, group - totalTrackGroupCount);
......
...@@ -60,7 +60,6 @@ public class SmoothStreamingChunkSource implements ChunkSource { ...@@ -60,7 +60,6 @@ public class SmoothStreamingChunkSource implements ChunkSource {
private final Evaluation evaluation; private final Evaluation evaluation;
private final FormatEvaluator adaptiveFormatEvaluator; private final FormatEvaluator adaptiveFormatEvaluator;
private long durationUs;
private TrackEncryptionBox[] trackEncryptionBoxes; private TrackEncryptionBox[] trackEncryptionBoxes;
private DrmInitData.Mapped drmInitData; private DrmInitData.Mapped drmInitData;
private SmoothStreamingManifest currentManifest; private SmoothStreamingManifest currentManifest;
...@@ -107,7 +106,6 @@ public class SmoothStreamingChunkSource implements ChunkSource { ...@@ -107,7 +106,6 @@ public class SmoothStreamingChunkSource implements ChunkSource {
public void init(SmoothStreamingManifest initialManifest) { public void init(SmoothStreamingManifest initialManifest) {
currentManifest = initialManifest; currentManifest = initialManifest;
durationUs = currentManifest.durationUs;
ProtectionElement protectionElement = currentManifest.protectionElement; ProtectionElement protectionElement = currentManifest.protectionElement;
if (protectionElement != null) { if (protectionElement != null) {
byte[] keyId = getProtectionElementKeyId(protectionElement.data); byte[] keyId = getProtectionElementKeyId(protectionElement.data);
...@@ -124,11 +122,6 @@ public class SmoothStreamingChunkSource implements ChunkSource { ...@@ -124,11 +122,6 @@ public class SmoothStreamingChunkSource implements ChunkSource {
} }
@Override @Override
public long getDurationUs() {
return durationUs;
}
@Override
public final TrackGroup getTracks() { public final TrackGroup getTracks() {
return trackGroup; return trackGroup;
} }
...@@ -274,8 +267,9 @@ public class SmoothStreamingChunkSource implements ChunkSource { ...@@ -274,8 +267,9 @@ public class SmoothStreamingChunkSource implements ChunkSource {
extractorWrappers = new ChunkExtractorWrapper[formats.length]; extractorWrappers = new ChunkExtractorWrapper[formats.length];
for (int j = 0; j < formats.length; j++) { for (int j = 0; j < formats.length; j++) {
int nalUnitLengthFieldLength = streamElementType == C.TRACK_TYPE_VIDEO ? 4 : -1; int nalUnitLengthFieldLength = streamElementType == C.TRACK_TYPE_VIDEO ? 4 : -1;
Track track = new Track(j, streamElementType, timescale, C.UNSET_TIME_US, durationUs, Track track = new Track(j, streamElementType, timescale, C.UNSET_TIME_US,
formats[j], trackEncryptionBoxes, nalUnitLengthFieldLength, null, null); manifest.durationUs, formats[j], trackEncryptionBoxes, nalUnitLengthFieldLength,
null, null);
FragmentedMp4Extractor extractor = new FragmentedMp4Extractor( FragmentedMp4Extractor extractor = new FragmentedMp4Extractor(
FragmentedMp4Extractor.FLAG_WORKAROUND_EVERY_VIDEO_FRAME_IS_SYNC_FRAME FragmentedMp4Extractor.FLAG_WORKAROUND_EVERY_VIDEO_FRAME_IS_SYNC_FRAME
| FragmentedMp4Extractor.FLAG_WORKAROUND_IGNORE_TFDT_BOX, track); | FragmentedMp4Extractor.FLAG_WORKAROUND_IGNORE_TFDT_BOX, track);
......
...@@ -53,8 +53,8 @@ public final class SmoothStreamingSampleSource implements SampleSource { ...@@ -53,8 +53,8 @@ public final class SmoothStreamingSampleSource implements SampleSource {
private final ManifestFetcher<SmoothStreamingManifest> manifestFetcher; private final ManifestFetcher<SmoothStreamingManifest> manifestFetcher;
private final SmoothStreamingChunkSource[] chunkSources; private final SmoothStreamingChunkSource[] chunkSources;
private final SampleSource[] sources; private final ChunkSampleSource[] sources;
private final IdentityHashMap<TrackStream, SampleSource> trackStreamSources; private final IdentityHashMap<TrackStream, ChunkSampleSource> trackStreamSources;
private final int[] selectedTrackCounts; private final int[] selectedTrackCounts;
private SmoothStreamingManifest currentManifest; private SmoothStreamingManifest currentManifest;
...@@ -62,7 +62,7 @@ public final class SmoothStreamingSampleSource implements SampleSource { ...@@ -62,7 +62,7 @@ public final class SmoothStreamingSampleSource implements SampleSource {
private boolean seenFirstTrackSelection; private boolean seenFirstTrackSelection;
private long durationUs; private long durationUs;
private TrackGroupArray trackGroups; private TrackGroupArray trackGroups;
private SampleSource[] enabledSources; private ChunkSampleSource[] enabledSources;
public SmoothStreamingSampleSource(Uri uri, DataSourceFactory dataSourceFactory, public SmoothStreamingSampleSource(Uri uri, DataSourceFactory dataSourceFactory,
BandwidthMeter bandwidthMeter, Handler eventHandler, BandwidthMeter bandwidthMeter, Handler eventHandler,
...@@ -99,7 +99,7 @@ public final class SmoothStreamingSampleSource implements SampleSource { ...@@ -99,7 +99,7 @@ public final class SmoothStreamingSampleSource implements SampleSource {
chunkSources = new SmoothStreamingChunkSource[] {videoChunkSource, audioChunkSource, chunkSources = new SmoothStreamingChunkSource[] {videoChunkSource, audioChunkSource,
textChunkSource}; textChunkSource};
sources = new SampleSource[] {videoSampleSource, audioSampleSource, textSampleSource}; sources = new ChunkSampleSource[] {videoSampleSource, audioSampleSource, textSampleSource};
trackStreamSources = new IdentityHashMap<>(); trackStreamSources = new IdentityHashMap<>();
selectedTrackCounts = new int[sources.length]; selectedTrackCounts = new int[sources.length];
} }
...@@ -117,32 +117,23 @@ public final class SmoothStreamingSampleSource implements SampleSource { ...@@ -117,32 +117,23 @@ public final class SmoothStreamingSampleSource implements SampleSource {
manifestFetcher.requestRefresh(); manifestFetcher.requestRefresh();
return false; return false;
} else { } else {
durationUs = currentManifest.durationUs;
for (SmoothStreamingChunkSource chunkSource : chunkSources) { for (SmoothStreamingChunkSource chunkSource : chunkSources) {
chunkSource.init(currentManifest); chunkSource.init(currentManifest);
} }
} }
} }
boolean sourcesPrepared = true; for (ChunkSampleSource source : sources) {
for (SampleSource source : sources) { source.prepare();
sourcesPrepared &= source.prepare(positionUs);
} }
if (!sourcesPrepared) {
return false;
}
durationUs = 0;
int totalTrackGroupCount = 0; int totalTrackGroupCount = 0;
for (SampleSource source : sources) { for (ChunkSampleSource source : sources) {
totalTrackGroupCount += source.getTrackGroups().length; totalTrackGroupCount += source.getTrackGroups().length;
if (durationUs != C.UNSET_TIME_US) {
long sourceDurationUs = source.getDurationUs();
durationUs = sourceDurationUs == C.UNSET_TIME_US
? C.UNSET_TIME_US : Math.max(durationUs, sourceDurationUs);
}
} }
TrackGroup[] trackGroupArray = new TrackGroup[totalTrackGroupCount]; TrackGroup[] trackGroupArray = new TrackGroup[totalTrackGroupCount];
int trackGroupIndex = 0; int trackGroupIndex = 0;
for (SampleSource source : sources) { for (ChunkSampleSource source : sources) {
int sourceTrackGroupCount = source.getTrackGroups().length; int sourceTrackGroupCount = source.getTrackGroups().length;
for (int j = 0; j < sourceTrackGroupCount; j++) { for (int j = 0; j < sourceTrackGroupCount; j++) {
trackGroupArray[trackGroupIndex++] = source.getTrackGroups().get(j); trackGroupArray[trackGroupIndex++] = source.getTrackGroups().get(j);
...@@ -178,7 +169,7 @@ public final class SmoothStreamingSampleSource implements SampleSource { ...@@ -178,7 +169,7 @@ public final class SmoothStreamingSampleSource implements SampleSource {
} }
} }
// Update the enabled sources. // Update the enabled sources.
enabledSources = new SampleSource[enabledSourceCount]; enabledSources = new ChunkSampleSource[enabledSourceCount];
enabledSourceCount = 0; enabledSourceCount = 0;
for (int i = 0; i < sources.length; i++) { for (int i = 0; i < sources.length; i++) {
if (selectedTrackCounts[i] > 0) { if (selectedTrackCounts[i] > 0) {
...@@ -211,7 +202,7 @@ public final class SmoothStreamingSampleSource implements SampleSource { ...@@ -211,7 +202,7 @@ public final class SmoothStreamingSampleSource implements SampleSource {
} }
} }
for (SampleSource source : enabledSources) { for (ChunkSampleSource source : enabledSources) {
source.continueBuffering(positionUs); source.continueBuffering(positionUs);
} }
} }
...@@ -219,7 +210,7 @@ public final class SmoothStreamingSampleSource implements SampleSource { ...@@ -219,7 +210,7 @@ public final class SmoothStreamingSampleSource implements SampleSource {
@Override @Override
public long readReset() { public long readReset() {
long resetPositionUs = C.UNSET_TIME_US; long resetPositionUs = C.UNSET_TIME_US;
for (SampleSource source : enabledSources) { for (ChunkSampleSource source : enabledSources) {
long childResetPositionUs = source.readReset(); long childResetPositionUs = source.readReset();
if (resetPositionUs == C.UNSET_TIME_US) { if (resetPositionUs == C.UNSET_TIME_US) {
resetPositionUs = childResetPositionUs; resetPositionUs = childResetPositionUs;
...@@ -233,7 +224,7 @@ public final class SmoothStreamingSampleSource implements SampleSource { ...@@ -233,7 +224,7 @@ public final class SmoothStreamingSampleSource implements SampleSource {
@Override @Override
public long getBufferedPositionUs() { public long getBufferedPositionUs() {
long bufferedPositionUs = durationUs != C.UNSET_TIME_US ? durationUs : Long.MAX_VALUE; long bufferedPositionUs = durationUs != C.UNSET_TIME_US ? durationUs : Long.MAX_VALUE;
for (SampleSource source : enabledSources) { for (ChunkSampleSource source : enabledSources) {
long rendererBufferedPositionUs = source.getBufferedPositionUs(); long rendererBufferedPositionUs = source.getBufferedPositionUs();
if (rendererBufferedPositionUs == C.UNSET_TIME_US) { if (rendererBufferedPositionUs == C.UNSET_TIME_US) {
return C.UNSET_TIME_US; return C.UNSET_TIME_US;
...@@ -248,7 +239,7 @@ public final class SmoothStreamingSampleSource implements SampleSource { ...@@ -248,7 +239,7 @@ public final class SmoothStreamingSampleSource implements SampleSource {
@Override @Override
public void seekToUs(long positionUs) { public void seekToUs(long positionUs) {
for (SampleSource source : enabledSources) { for (ChunkSampleSource source : enabledSources) {
source.seekToUs(positionUs); source.seekToUs(positionUs);
} }
} }
...@@ -256,14 +247,14 @@ public final class SmoothStreamingSampleSource implements SampleSource { ...@@ -256,14 +247,14 @@ public final class SmoothStreamingSampleSource implements SampleSource {
@Override @Override
public void release() { public void release() {
manifestFetcher.release(); manifestFetcher.release();
for (SampleSource source : sources) { for (ChunkSampleSource source : sources) {
source.release(); source.release();
} }
} }
// Internal methods. // Internal methods.
private int selectTracks(SampleSource source, List<TrackStream> allOldStreams, private int selectTracks(ChunkSampleSource source, List<TrackStream> allOldStreams,
List<TrackSelection> allNewSelections, long positionUs, TrackStream[] allNewStreams) { List<TrackSelection> allNewSelections, long positionUs, TrackStream[] allNewStreams) {
// Get the subset of the old streams for the source. // Get the subset of the old streams for the source.
ArrayList<TrackStream> oldStreams = new ArrayList<>(); ArrayList<TrackStream> oldStreams = new ArrayList<>();
...@@ -279,7 +270,7 @@ public final class SmoothStreamingSampleSource implements SampleSource { ...@@ -279,7 +270,7 @@ public final class SmoothStreamingSampleSource implements SampleSource {
int[] newSelectionOriginalIndices = new int[allNewSelections.size()]; int[] newSelectionOriginalIndices = new int[allNewSelections.size()];
for (int i = 0; i < allNewSelections.size(); i++) { for (int i = 0; i < allNewSelections.size(); i++) {
TrackSelection selection = allNewSelections.get(i); TrackSelection selection = allNewSelections.get(i);
Pair<SampleSource, Integer> sourceAndGroup = getSourceAndGroup(selection.group); Pair<ChunkSampleSource, Integer> sourceAndGroup = getSourceAndGroup(selection.group);
if (sourceAndGroup.first == source) { if (sourceAndGroup.first == source) {
newSelectionOriginalIndices[newSelections.size()] = i; newSelectionOriginalIndices[newSelections.size()] = i;
newSelections.add(new TrackSelection(sourceAndGroup.second, selection.getTracks())); newSelections.add(new TrackSelection(sourceAndGroup.second, selection.getTracks()));
...@@ -298,9 +289,9 @@ public final class SmoothStreamingSampleSource implements SampleSource { ...@@ -298,9 +289,9 @@ public final class SmoothStreamingSampleSource implements SampleSource {
return newSelections.size() - oldStreams.size(); return newSelections.size() - oldStreams.size();
} }
private Pair<SampleSource, Integer> getSourceAndGroup(int group) { private Pair<ChunkSampleSource, Integer> getSourceAndGroup(int group) {
int totalTrackGroupCount = 0; int totalTrackGroupCount = 0;
for (SampleSource source : sources) { for (ChunkSampleSource source : sources) {
int sourceTrackGroupCount = source.getTrackGroups().length; int sourceTrackGroupCount = source.getTrackGroups().length;
if (group < totalTrackGroupCount + sourceTrackGroupCount) { if (group < totalTrackGroupCount + sourceTrackGroupCount) {
return Pair.create(source, group - totalTrackGroupCount); return Pair.create(source, group - totalTrackGroupCount);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment