From 6d6efed6d4a222fd9041b758a77ecdfb2496744d 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 PiperOrigin-RevId: 375053638 --- RELEASENOTES.md | 3 +++ .../source/hls/HlsSampleStreamWrapper.java | 17 ++++++----------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index a4a335b981..71d5b046ff 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -9,6 +9,9 @@ * Extractors: * Add support for MPEG-H 3D Audio in MP4 extractors ([#8860](https://github.com/google/ExoPlayer/pull/8860)). +* HLS + * Fix a bug where skipping into spliced-in chunks triggered an assertion + error ([#8937](https://github.com/google/ExoPlayer/issues/8937). ### 2.14.0 (2021-05-13) 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 61afe9bcd8..37468bfb1d 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; @@ -636,17 +637,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);