Fix reporting of format changes in ChunkSampleStream.

Until recently, changing primary track formats were reported when the
corresponding media chunk was discarded which always happened immediately
after the sample has been read.

Now, media chunks may be discarded later on or in batches, leaving the
current reporting mechanism broken because changes may never be reported.

This fix separates the discarding from the reporting such that format changes
can be reported when the media chunk is first read from, while the discarding
operation only discards without reporting format changes.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=176519071
This commit is contained in:
tonihei 2017-11-21 09:28:10 -08:00 committed by Oliver Woodman
parent 15a1f9a552
commit 6607f49be6

View File

@ -258,8 +258,12 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
if (isPendingReset()) {
return C.RESULT_NOTHING_READ;
}
return primarySampleQueue.read(formatHolder, buffer, formatRequired, loadingFinished,
int result = primarySampleQueue.read(formatHolder, buffer, formatRequired, loadingFinished,
lastSeekPositionUs);
if (result == C.RESULT_BUFFER_READ) {
maybeNotifyPrimaryTrackFormatChanged(primarySampleQueue.getReadIndex(), 1);
}
return result;
}
@Override
@ -274,6 +278,9 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
skipCount = 0;
}
}
if (skipCount > 0) {
maybeNotifyPrimaryTrackFormatChanged(primarySampleQueue.getReadIndex(), skipCount);
}
return skipCount;
}
@ -434,13 +441,39 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
return pendingResetPositionUs != C.TIME_UNSET;
}
private void discardDownstreamMediaChunks(int primaryStreamReadIndex) {
private void discardDownstreamMediaChunks(int discardToPrimaryStreamIndex) {
if (!mediaChunks.isEmpty()) {
while (mediaChunks.size() > 1
&& mediaChunks.get(1).getFirstSampleIndex(0) <= primaryStreamReadIndex) {
&& mediaChunks.get(1).getFirstSampleIndex(0) <= discardToPrimaryStreamIndex) {
mediaChunks.removeFirst();
}
BaseMediaChunk currentChunk = mediaChunks.getFirst();
}
}
private void maybeNotifyPrimaryTrackFormatChanged(int toPrimaryStreamReadIndex, int readCount) {
if (!mediaChunks.isEmpty()) {
int fromPrimaryStreamReadIndex = toPrimaryStreamReadIndex - readCount;
int fromChunkIndex = 0;
while (fromChunkIndex < mediaChunks.size() - 1
&& mediaChunks.get(fromChunkIndex + 1).getFirstSampleIndex(0)
<= fromPrimaryStreamReadIndex) {
fromChunkIndex++;
}
int toChunkIndex = fromChunkIndex + 1;
if (readCount > 1) {
while (toChunkIndex < mediaChunks.size()
&& mediaChunks.get(toChunkIndex).getFirstSampleIndex(0) < toPrimaryStreamReadIndex) {
toChunkIndex++;
}
}
for (int i = fromChunkIndex; i < toChunkIndex; i++) {
maybeNotifyPrimaryTrackFormatChanged(i);
}
}
}
private void maybeNotifyPrimaryTrackFormatChanged(int mediaChunkReadIndex) {
BaseMediaChunk currentChunk = mediaChunks.get(mediaChunkReadIndex);
Format trackFormat = currentChunk.trackFormat;
if (!trackFormat.equals(primaryDownstreamTrackFormat)) {
eventDispatcher.downstreamFormatChanged(primaryTrackType, trackFormat,
@ -449,7 +482,6 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
}
primaryDownstreamTrackFormat = trackFormat;
}
}
/**
* Discard upstream media chunks until the queue length is equal to the length specified.