Fix issue where getFirstSampleIndex was called on spliced in chunks.

We need to avoid reading and skipping into preload chunks as they
may need to be discarded. The current code iterates over all chunks,
but this can be simplified by just checking the last chunk knowing
that the preload chunk must always be the last one.

As a result, we avoid calling getFirstSampleIndex on all chunks. This
is a bug since the method is not allowed to be called for chunks
that have been spliced in. This still leaves the smaller issue of
potentially calling this method for spliced-in preload chunks, which
will be solved separately.

Issue: #8937

#minor-release

PiperOrigin-RevId: 375053638
This commit is contained in:
tonihei 2021-05-21 11:49:17 +01:00 committed by Oliver Woodman
parent 8c9c0f8d3f
commit 8ded11753e
2 changed files with 8 additions and 11 deletions

View File

@ -52,6 +52,8 @@
* HLS
* Use the PRECISE attribute in EXT-X-START to select the default start
position.
* Fix a bug where skipping into spliced-in chunks triggered an assertion
error ([#8937](https://github.com/google/ExoPlayer/issues/8937).
* PlayerNotificationManager:
* Add `PendingIntent.FLAG_IMMUTABLE` flag to BroadcastReceiver to support
Android 12.

View File

@ -18,6 +18,7 @@ package com.google.android.exoplayer2.source.hls;
import static com.google.android.exoplayer2.source.hls.HlsChunkSource.CHUNK_PUBLICATION_STATE_PUBLISHED;
import static com.google.android.exoplayer2.source.hls.HlsChunkSource.CHUNK_PUBLICATION_STATE_REMOVED;
import static java.lang.Math.max;
import static java.lang.Math.min;
import android.net.Uri;
import android.os.Handler;
@ -638,17 +639,11 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
int skipCount = sampleQueue.getSkipCount(positionUs, loadingFinished);
// Ensure we don't skip into preload chunks until we can be sure they are permanently published.
int readIndex = sampleQueue.getReadIndex();
for (int i = 0; i < mediaChunks.size(); i++) {
HlsMediaChunk mediaChunk = mediaChunks.get(i);
int firstSampleIndex = mediaChunks.get(i).getFirstSampleIndex(sampleQueueIndex);
if (readIndex + skipCount <= firstSampleIndex) {
break;
}
if (!mediaChunk.isPublished()) {
skipCount = firstSampleIndex - readIndex;
break;
}
@Nullable HlsMediaChunk lastChunk = Iterables.getLast(mediaChunks, /* defaultValue= */ null);
if (lastChunk != null && !lastChunk.isPublished()) {
int readIndex = sampleQueue.getReadIndex();
int firstSampleIndex = lastChunk.getFirstSampleIndex(sampleQueueIndex);
skipCount = min(skipCount, firstSampleIndex - readIndex);
}
sampleQueue.skip(skipCount);