From 0414b0d2f6cfda21c1db13166ff55d4b6cd20d2c Mon Sep 17 00:00:00 2001 From: Oliver Woodman Date: Sat, 20 Dec 2014 11:57:05 +0000 Subject: [PATCH] Fix assertion fail on seek. Issue: #214 --- .../exoplayer/hls/HlsSampleSource.java | 36 ++++++++++++++----- .../android/exoplayer/hls/TsExtractor.java | 1 + 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/library/src/main/java/com/google/android/exoplayer/hls/HlsSampleSource.java b/library/src/main/java/com/google/android/exoplayer/hls/HlsSampleSource.java index ed0573e58a..8297c4aeb9 100644 --- a/library/src/main/java/com/google/android/exoplayer/hls/HlsSampleSource.java +++ b/library/src/main/java/com/google/android/exoplayer/hls/HlsSampleSource.java @@ -171,7 +171,7 @@ public class HlsSampleSource implements SampleSource, Loader.Callback { if (isPendingReset() || extractors.isEmpty()) { return false; } - boolean haveSamples = prepared && haveSamplesForEnabledTracks(extractors.getFirst()); + boolean haveSamples = prepared && haveSamplesForEnabledTracks(getCurrentExtractor()); if (!haveSamples) { maybeThrowLoadableException(); } @@ -194,13 +194,7 @@ public class HlsSampleSource implements SampleSource, Loader.Callback { return NOTHING_READ; } - TsExtractor extractor = extractors.getFirst(); - while (extractors.size() > 1 && !haveSamplesForEnabledTracks(extractor)) { - // We're finished reading from the extractor for all tracks, and so can discard it. - extractors.removeFirst().release(); - extractor = extractors.getFirst(); - } - + TsExtractor extractor = getCurrentExtractor(); if (extractors.size() > 1) { // If there's more than one extractor, attempt to configure a seamless splice from the // current one to the next one. @@ -318,7 +312,30 @@ public class HlsSampleSource implements SampleSource, Loader.Callback { maybeStartLoading(); } + /** + * Gets the current extractor from which samples should be read. + *

+ * Calling this method discards extractors without any samples from the front of the queue. The + * last extractor is retained even if it doesn't have any samples. + *

+ * This method must not be called unless {@link #extractors} is non-empty. + * + * @return The current extractor from which samples should be read. Guaranteed to be non-null. + */ + private TsExtractor getCurrentExtractor() { + TsExtractor extractor = extractors.getFirst(); + while (extractors.size() > 1 && !haveSamplesForEnabledTracks(extractor)) { + // We're finished reading from the extractor for all tracks, and so can discard it. + extractors.removeFirst().release(); + extractor = extractors.getFirst(); + } + return extractor; + } + private void discardSamplesForDisabledTracks(TsExtractor extractor, long timeUs) { + if (!extractor.isPrepared()) { + return; + } for (int i = 0; i < trackEnabledStates.length; i++) { if (!trackEnabledStates[i]) { extractor.discardUntil(i, timeUs); @@ -327,6 +344,9 @@ public class HlsSampleSource implements SampleSource, Loader.Callback { } private boolean haveSamplesForEnabledTracks(TsExtractor extractor) { + if (!extractor.isPrepared()) { + return false; + } for (int i = 0; i < trackEnabledStates.length; i++) { if (trackEnabledStates[i] && extractor.hasSamples(i)) { return true; diff --git a/library/src/main/java/com/google/android/exoplayer/hls/TsExtractor.java b/library/src/main/java/com/google/android/exoplayer/hls/TsExtractor.java index f59a5206f9..b8e6c6ef6e 100644 --- a/library/src/main/java/com/google/android/exoplayer/hls/TsExtractor.java +++ b/library/src/main/java/com/google/android/exoplayer/hls/TsExtractor.java @@ -205,6 +205,7 @@ public final class TsExtractor { * for the specified track. False otherwise. */ public boolean hasSamples(int track) { + Assertions.checkState(prepared); return sampleQueues.valueAt(track).peek() != null; }