From c49d142981ae1498840d6cd2b4f5be4461f037a3 Mon Sep 17 00:00:00 2001 From: aquilescanta Date: Thu, 26 Jan 2017 08:55:42 -0800 Subject: [PATCH] Prevent old playlist snapshots from being used on live HLS streams This aims to replace InvalidCodeResponse's with BLWE's caused by trying to load chunks that have been removed from the server. Issue:#2344 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=145679171 --- .../exoplayer2/source/hls/HlsChunkSource.java | 22 +++++++------ .../hls/playlist/HlsPlaylistTracker.java | 33 +++++++++++++++++-- 2 files changed, 43 insertions(+), 12 deletions(-) diff --git a/library/src/main/java/com/google/android/exoplayer2/source/hls/HlsChunkSource.java b/library/src/main/java/com/google/android/exoplayer2/source/hls/HlsChunkSource.java index c2a345ace6..c7c66fbd61 100644 --- a/library/src/main/java/com/google/android/exoplayer2/source/hls/HlsChunkSource.java +++ b/library/src/main/java/com/google/android/exoplayer2/source/hls/HlsChunkSource.java @@ -194,15 +194,16 @@ import java.util.Locale; // Select the variant. trackSelection.updateSelectedTrack(bufferedDurationUs); - int newVariantIndex = trackSelection.getSelectedIndexInTrackGroup(); + int selectedVariantIndex = trackSelection.getSelectedIndexInTrackGroup(); - boolean switchingVariant = oldVariantIndex != newVariantIndex; - HlsMediaPlaylist mediaPlaylist = playlistTracker.getPlaylistSnapshot(variants[newVariantIndex]); - if (mediaPlaylist == null) { - out.playlist = variants[newVariantIndex]; + boolean switchingVariant = oldVariantIndex != selectedVariantIndex; + HlsUrl selectedUrl = variants[selectedVariantIndex]; + if (!playlistTracker.isSnapshotValid(selectedUrl)) { + out.playlist = selectedUrl; // Retry when playlist is refreshed. return; } + HlsMediaPlaylist mediaPlaylist = playlistTracker.getPlaylistSnapshot(selectedUrl); // Select the chunk. int chunkMediaSequence; @@ -218,8 +219,9 @@ import java.util.Locale; if (chunkMediaSequence < mediaPlaylist.mediaSequence && previous != null) { // We try getting the next chunk without adapting in case that's the reason for falling // behind the live window. - newVariantIndex = oldVariantIndex; - mediaPlaylist = playlistTracker.getPlaylistSnapshot(variants[newVariantIndex]); + selectedVariantIndex = oldVariantIndex; + selectedUrl = variants[selectedVariantIndex]; + mediaPlaylist = playlistTracker.getPlaylistSnapshot(selectedUrl); chunkMediaSequence = previous.getNextChunkIndex(); } } @@ -236,7 +238,7 @@ import java.util.Locale; if (mediaPlaylist.hasEndTag) { out.endOfStream = true; } else /* Live */ { - out.playlist = variants[newVariantIndex]; + out.playlist = selectedUrl; } return; } @@ -249,7 +251,7 @@ import java.util.Locale; Uri keyUri = UriUtil.resolveToUri(mediaPlaylist.baseUri, segment.encryptionKeyUri); if (!keyUri.equals(encryptionKeyUri)) { // Encryption is specified and the key has changed. - out.chunk = newEncryptionKeyChunk(keyUri, segment.encryptionIV, newVariantIndex, + out.chunk = newEncryptionKeyChunk(keyUri, segment.encryptionIV, selectedVariantIndex, trackSelection.getSelectionReason(), trackSelection.getSelectionData()); return; } @@ -279,7 +281,7 @@ import java.util.Locale; Uri chunkUri = UriUtil.resolveToUri(mediaPlaylist.baseUri, segment.url); DataSpec dataSpec = new DataSpec(chunkUri, segment.byterangeOffset, segment.byterangeLength, null); - out.chunk = new HlsMediaChunk(dataSource, dataSpec, initDataSpec, variants[newVariantIndex], + out.chunk = new HlsMediaChunk(dataSource, dataSpec, initDataSpec, selectedUrl, trackSelection.getSelectionReason(), trackSelection.getSelectionData(), startTimeUs, startTimeUs + segment.durationUs, chunkMediaSequence, discontinuitySequence, isTimestampMaster, timestampAdjuster, previous, encryptionKey, encryptionIv); diff --git a/library/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistTracker.java b/library/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistTracker.java index 92e2480da7..95784092a9 100644 --- a/library/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistTracker.java +++ b/library/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistTracker.java @@ -166,8 +166,24 @@ public final class HlsPlaylistTracker implements Loader.Callback mediaPlaylistLoadable; private HlsMediaPlaylist playlistSnapshot; + private long lastSnapshotLoadMs; private long lastSnapshotAccessTimeMs; private long blacklistUntilMs; @@ -429,6 +446,17 @@ public final class HlsPlaylistTracker implements Loader.Callback currentTimeMs; + } + public void release() { mediaPlaylistLoader.release(); } @@ -488,6 +516,7 @@ public final class HlsPlaylistTracker implements Loader.Callback