Commit e390bdf9 by olly Committed by Oliver Woodman

Align Chunk/HLS sample sources.

Having moved HLS to use single sample queues per track, these
classes have become relatively similar. This CL aligns the two
to make this more obvious. It remains unclear whether it'll
ever be sensible to merge them; there are still some niggly
complications for HLS.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=120429618
parent ae8f95f6
...@@ -51,31 +51,31 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call ...@@ -51,31 +51,31 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call
public static final int DEFAULT_MIN_LOADABLE_RETRY_COUNT = 3; public static final int DEFAULT_MIN_LOADABLE_RETRY_COUNT = 3;
private final Loader loader; private final Loader loader;
private final LoadControl loadControl;
private final ChunkSource chunkSource; private final ChunkSource chunkSource;
private final ChunkHolder nextChunkHolder;
private final LinkedList<BaseMediaChunk> mediaChunks; private final LinkedList<BaseMediaChunk> mediaChunks;
private final List<BaseMediaChunk> readOnlyMediaChunks; private final List<BaseMediaChunk> readOnlyMediaChunks;
private final DefaultTrackOutput sampleQueue; private final DefaultTrackOutput sampleQueue;
private final int bufferSizeContribution; private final int bufferSizeContribution;
private final ChunkHolder nextChunkHolder;
private final EventDispatcher eventDispatcher; private final EventDispatcher eventDispatcher;
private final LoadControl loadControl;
private boolean prepared; private boolean prepared;
private long downstreamPositionUs;
private long lastSeekPositionUs;
private long pendingResetPositionUs;
private long lastPreferredQueueSizeEvaluationTimeMs; private long lastPreferredQueueSizeEvaluationTimeMs;
private boolean pendingReset; private Format downstreamFormat;
private TrackGroupArray trackGroups; private TrackGroupArray trackGroups;
private long durationUs;
private boolean loadingFinished;
private boolean trackEnabled; private boolean trackEnabled;
private long currentLoadStartTimeMs; private boolean pendingReset;
private Format downstreamSampleFormat;
private long downstreamPositionUs;
private long lastSeekPositionUs;
private long pendingResetPositionUs;
private Chunk currentLoadable; private Chunk currentLoadable;
private Format downstreamFormat; private long currentLoadStartTimeMs;
private Format downstreamSampleFormat; private boolean loadingFinished;
/** /**
* @param chunkSource A {@link ChunkSource} from which chunks to load are obtained. * @param chunkSource A {@link ChunkSource} from which chunks to load are obtained.
...@@ -139,7 +139,6 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call ...@@ -139,7 +139,6 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call
if (!chunkSource.prepare()) { if (!chunkSource.prepare()) {
return false; return false;
} }
durationUs = chunkSource.getDurationUs();
TrackGroup tracks = chunkSource.getTracks(); TrackGroup tracks = chunkSource.getTracks();
if (tracks != null) { if (tracks != null) {
trackGroups = new TrackGroupArray(tracks); trackGroups = new TrackGroupArray(tracks);
...@@ -152,7 +151,7 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call ...@@ -152,7 +151,7 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call
@Override @Override
public long getDurationUs() { public long getDurationUs() {
return durationUs; return chunkSource.getDurationUs();
} }
@Override @Override
...@@ -222,9 +221,14 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call ...@@ -222,9 +221,14 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call
} else if (isPendingReset()) { } else if (isPendingReset()) {
return pendingResetPositionUs; return pendingResetPositionUs;
} else { } else {
long largestQueuedTimestampUs = sampleQueue.getLargestQueuedTimestampUs(); long bufferedPositionUs = downstreamPositionUs;
return largestQueuedTimestampUs == Long.MIN_VALUE ? downstreamPositionUs BaseMediaChunk lastMediaChunk = mediaChunks.getLast();
: largestQueuedTimestampUs; BaseMediaChunk lastCompletedMediaChunk = lastMediaChunk != currentLoadable ? lastMediaChunk
: mediaChunks.size() > 1 ? mediaChunks.get(mediaChunks.size() - 2) : null;
if (lastCompletedMediaChunk != null) {
bufferedPositionUs = Math.max(bufferedPositionUs, lastCompletedMediaChunk.endTimeUs);
}
return Math.max(bufferedPositionUs, sampleQueue.getLargestQueuedTimestampUs());
} }
} }
...@@ -236,8 +240,7 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call ...@@ -236,8 +240,7 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call
boolean seekInsideBuffer = !isPendingReset() && sampleQueue.skipToKeyframeBefore(positionUs); boolean seekInsideBuffer = !isPendingReset() && sampleQueue.skipToKeyframeBefore(positionUs);
if (seekInsideBuffer) { if (seekInsideBuffer) {
// We succeeded. All we need to do is discard any chunks that we've moved past. // We succeeded. All we need to do is discard any chunks that we've moved past.
boolean haveSamples = !sampleQueue.isEmpty(); while (mediaChunks.size() > 1
while (haveSamples && mediaChunks.size() > 1
&& mediaChunks.get(1).getFirstSampleIndex() <= sampleQueue.getReadIndex()) { && mediaChunks.get(1).getFirstSampleIndex() <= sampleQueue.getReadIndex()) {
mediaChunks.removeFirst(); mediaChunks.removeFirst();
} }
...@@ -286,9 +289,8 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call ...@@ -286,9 +289,8 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call
return NOTHING_READ; return NOTHING_READ;
} }
boolean haveSamples = !sampleQueue.isEmpty();
BaseMediaChunk currentChunk = mediaChunks.getFirst(); BaseMediaChunk currentChunk = mediaChunks.getFirst();
while (haveSamples && mediaChunks.size() > 1 while (mediaChunks.size() > 1
&& mediaChunks.get(1).getFirstSampleIndex() <= sampleQueue.getReadIndex()) { && mediaChunks.get(1).getFirstSampleIndex() <= sampleQueue.getReadIndex()) {
mediaChunks.removeFirst(); mediaChunks.removeFirst();
currentChunk = mediaChunks.getFirst(); currentChunk = mediaChunks.getFirst();
...@@ -300,15 +302,7 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call ...@@ -300,15 +302,7 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call
downstreamFormat = currentChunk.format; downstreamFormat = currentChunk.format;
} }
Format sampleFormat = sampleQueue.getDownstreamFormat(); if (sampleQueue.isEmpty()) {
if (sampleFormat != null && !sampleFormat.equals(downstreamSampleFormat)) {
formatHolder.format = sampleFormat;
formatHolder.drmInitData = currentChunk.getDrmInitData();
downstreamSampleFormat = sampleFormat;
return FORMAT_READ;
}
if (!haveSamples) {
if (loadingFinished) { if (loadingFinished) {
buffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM); buffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM);
return BUFFER_READ; return BUFFER_READ;
...@@ -316,6 +310,14 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call ...@@ -316,6 +310,14 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call
return NOTHING_READ; return NOTHING_READ;
} }
Format sampleFormat = sampleQueue.getDownstreamFormat();
if (!sampleFormat.equals(downstreamSampleFormat)) {
formatHolder.format = sampleFormat;
formatHolder.drmInitData = currentChunk.getDrmInitData();
downstreamSampleFormat = sampleFormat;
return FORMAT_READ;
}
if (sampleQueue.readSample(buffer)) { if (sampleQueue.readSample(buffer)) {
if (buffer.timeUs < lastSeekPositionUs) { if (buffer.timeUs < lastSeekPositionUs) {
buffer.addFlag(C.BUFFER_FLAG_DECODE_ONLY); buffer.addFlag(C.BUFFER_FLAG_DECODE_ONLY);
...@@ -327,7 +329,7 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call ...@@ -327,7 +329,7 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call
return NOTHING_READ; return NOTHING_READ;
} }
// Loadable.Callback implementation. // Loader.Callback implementation.
@Override @Override
public void onLoadCompleted(Loadable loadable) { public void onLoadCompleted(Loadable loadable) {
...@@ -451,12 +453,10 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call ...@@ -451,12 +453,10 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call
currentLoadStartTimeMs = now; currentLoadStartTimeMs = now;
currentLoadable = nextLoadable; currentLoadable = nextLoadable;
if (isMediaChunk(currentLoadable)) { if (isMediaChunk(currentLoadable)) {
pendingResetPositionUs = C.UNSET_TIME_US;
BaseMediaChunk mediaChunk = (BaseMediaChunk) currentLoadable; BaseMediaChunk mediaChunk = (BaseMediaChunk) currentLoadable;
mediaChunk.init(sampleQueue); mediaChunk.init(sampleQueue);
mediaChunks.add(mediaChunk); mediaChunks.add(mediaChunk);
if (isPendingReset()) {
pendingResetPositionUs = C.UNSET_TIME_US;
}
eventDispatcher.loadStarted(mediaChunk.dataSpec.length, mediaChunk.type, mediaChunk.trigger, eventDispatcher.loadStarted(mediaChunk.dataSpec.length, mediaChunk.type, mediaChunk.trigger,
mediaChunk.format, mediaChunk.startTimeUs, mediaChunk.endTimeUs); mediaChunk.format, mediaChunk.startTimeUs, mediaChunk.endTimeUs);
} else { } else {
...@@ -480,6 +480,14 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call ...@@ -480,6 +480,14 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call
} }
} }
private boolean isMediaChunk(Chunk chunk) {
return chunk instanceof BaseMediaChunk;
}
private boolean isPendingReset() {
return pendingResetPositionUs != C.UNSET_TIME_US;
}
/** /**
* Discard upstream media chunks until the queue length is equal to the length specified. * Discard upstream media chunks until the queue length is equal to the length specified.
* *
...@@ -504,12 +512,4 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call ...@@ -504,12 +512,4 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call
return true; return true;
} }
private boolean isMediaChunk(Chunk chunk) {
return chunk instanceof BaseMediaChunk;
}
private boolean isPendingReset() {
return pendingResetPositionUs != C.UNSET_TIME_US;
}
} }
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