From 8ded11753ee4df9452aa8f483111b5fe8b7bb73e Mon Sep 17 00:00:00 2001 From: tonihei Date: Fri, 21 May 2021 11:49:17 +0100 Subject: [PATCH] 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 --- RELEASENOTES.md | 2 ++ .../source/hls/HlsSampleStreamWrapper.java | 17 ++++++----------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 637208f71b..a0d7634f5b 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -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. diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java index 4c7ee9f9a0..6fe936c4a7 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java @@ -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);