From 6607f49be609b692efbe210832544d375afc494c Mon Sep 17 00:00:00 2001 From: tonihei Date: Tue, 21 Nov 2017 09:28:10 -0800 Subject: [PATCH] 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 --- .../source/chunk/ChunkSampleStream.java | 54 +++++++++++++++---- 1 file changed, 43 insertions(+), 11 deletions(-) diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkSampleStream.java b/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkSampleStream.java index 53742238ef..cfed38dd4a 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkSampleStream.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkSampleStream.java @@ -258,8 +258,12 @@ public class ChunkSampleStream 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 implements SampleStream, S skipCount = 0; } } + if (skipCount > 0) { + maybeNotifyPrimaryTrackFormatChanged(primarySampleQueue.getReadIndex(), skipCount); + } return skipCount; } @@ -434,23 +441,48 @@ public class ChunkSampleStream 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(); - Format trackFormat = currentChunk.trackFormat; - if (!trackFormat.equals(primaryDownstreamTrackFormat)) { - eventDispatcher.downstreamFormatChanged(primaryTrackType, trackFormat, - currentChunk.trackSelectionReason, currentChunk.trackSelectionData, - currentChunk.startTimeUs); - } - primaryDownstreamTrackFormat = trackFormat; } } + 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, + currentChunk.trackSelectionReason, currentChunk.trackSelectionData, + currentChunk.startTimeUs); + } + primaryDownstreamTrackFormat = trackFormat; + } + /** * Discard upstream media chunks until the queue length is equal to the length specified. *