From 5c0745cedff6a0c2f373ff63a787780dcf491607 Mon Sep 17 00:00:00 2001 From: Oliver Woodman Date: Mon, 7 Sep 2015 13:59:55 +0100 Subject: [PATCH] Add some generally useful error propagation logic for HLS. Issue #765 --- .../android/exoplayer/hls/HlsChunkSource.java | 23 +++++++++++++++++++ .../exoplayer/hls/HlsSampleSource.java | 3 +++ 2 files changed, 26 insertions(+) diff --git a/library/src/main/java/com/google/android/exoplayer/hls/HlsChunkSource.java b/library/src/main/java/com/google/android/exoplayer/hls/HlsChunkSource.java index aa89804e9d..23659a5baf 100644 --- a/library/src/main/java/com/google/android/exoplayer/hls/HlsChunkSource.java +++ b/library/src/main/java/com/google/android/exoplayer/hls/HlsChunkSource.java @@ -138,6 +138,7 @@ public class HlsChunkSource { private byte[] scratchSpace; private boolean live; private long durationUs; + private IOException fatalError; private Uri encryptionKeyUri; private byte[] encryptionKey; @@ -223,6 +224,18 @@ public class HlsChunkSource { return live ? C.UNKNOWN_TIME_US : durationUs; } + /** + * If the source is currently having difficulty providing chunks, then this method throws the + * underlying error. Otherwise does nothing. + * + * @throws IOException The underlying error. + */ + public void maybeThrowError() throws IOException { + if (fatalError != null) { + throw fatalError; + } + } + /** * Returns the next {@link Chunk} that should be loaded. * @@ -262,9 +275,15 @@ public class HlsChunkSource { chunkMediaSequence = switchingVariantSpliced ? previousTsChunk.chunkIndex : previousTsChunk.chunkIndex + 1; if (chunkMediaSequence < mediaPlaylist.mediaSequence) { + // TODO: Decide what we want to do with: https://github.com/google/ExoPlayer/issues/765 + // if (allowSkipAhead) { // If the chunk is no longer in the playlist. Skip ahead and start again. chunkMediaSequence = getLiveStartChunkMediaSequence(nextVariantIndex); liveDiscontinuity = true; + // } else { + // fatalError = new BehindLiveWindowException(); + // return null; + // } } } } else { @@ -414,6 +433,10 @@ public class HlsChunkSource { return false; } + public void reset() { + fatalError = null; + } + private int getNextVariantIndex(TsChunk previousTsChunk, long playbackPositionUs) { clearStaleBlacklistedVariants(); long bitrateEstimate = bandwidthMeter.getBitrateEstimate(); 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 1d30242465..e75d48fb0b 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 @@ -206,6 +206,7 @@ public final class HlsSampleSource implements SampleSource, SampleSourceReader, enabledTrackCount--; trackEnabledStates[track] = false; if (enabledTrackCount == 0) { + chunkSource.reset(); downstreamPositionUs = Long.MIN_VALUE; if (loadControlRegistered) { loadControl.unregister(this); @@ -317,6 +318,8 @@ public final class HlsSampleSource implements SampleSource, SampleSourceReader, public void maybeThrowError() throws IOException { if (currentLoadableException != null && currentLoadableExceptionCount > minLoadableRetryCount) { throw currentLoadableException; + } else if (currentLoadable == null) { + chunkSource.maybeThrowError(); } }