Commit ea95db23 by ojw28

Merge pull request #316 from jeoliva/blackplaylist_management

Better management of blacklisted playlists
parents 006986cc 2ac7046f
...@@ -106,6 +106,12 @@ public class HlsChunkSource { ...@@ -106,6 +106,12 @@ public class HlsChunkSource {
*/ */
public static final long DEFAULT_MAX_BUFFER_TO_SWITCH_DOWN_MS = 20000; public static final long DEFAULT_MAX_BUFFER_TO_SWITCH_DOWN_MS = 20000;
/**
* The default maximum time a media playlist is blacklisted without
* rechecking if it is alive again (because an encoder reset, for example)
*/
public static final long DEFAULT_MAX_TIME_MEDIA_PLAYLIST_BLACKLISTED_MS = 60000;
private static final String TAG = "HlsChunkSource"; private static final String TAG = "HlsChunkSource";
private static final String AAC_FILE_EXTENSION = ".aac"; private static final String AAC_FILE_EXTENSION = ".aac";
private static final float BANDWIDTH_FRACTION = 0.8f; private static final float BANDWIDTH_FRACTION = 0.8f;
...@@ -127,6 +133,7 @@ public class HlsChunkSource { ...@@ -127,6 +133,7 @@ public class HlsChunkSource {
/* package */ byte[] scratchSpace; /* package */ byte[] scratchSpace;
/* package */ final HlsMediaPlaylist[] mediaPlaylists; /* package */ final HlsMediaPlaylist[] mediaPlaylists;
/* package */ final boolean[] mediaPlaylistBlacklistFlags; /* package */ final boolean[] mediaPlaylistBlacklistFlags;
/* package */ final long[] mediaPlaylistBlacklistedTimeMs;
/* package */ final long[] lastMediaPlaylistLoadTimesMs; /* package */ final long[] lastMediaPlaylistLoadTimesMs;
/* package */ boolean live; /* package */ boolean live;
/* package */ long durationUs; /* package */ long durationUs;
...@@ -182,6 +189,7 @@ public class HlsChunkSource { ...@@ -182,6 +189,7 @@ public class HlsChunkSource {
enabledVariants = new Variant[] {new Variant(0, playlistUrl, 0, null, -1, -1)}; enabledVariants = new Variant[] {new Variant(0, playlistUrl, 0, null, -1, -1)};
mediaPlaylists = new HlsMediaPlaylist[1]; mediaPlaylists = new HlsMediaPlaylist[1];
mediaPlaylistBlacklistFlags = new boolean[1]; mediaPlaylistBlacklistFlags = new boolean[1];
mediaPlaylistBlacklistedTimeMs = new long[1];
lastMediaPlaylistLoadTimesMs = new long[1]; lastMediaPlaylistLoadTimesMs = new long[1];
setMediaPlaylist(0, (HlsMediaPlaylist) playlist); setMediaPlaylist(0, (HlsMediaPlaylist) playlist);
} else { } else {
...@@ -189,6 +197,7 @@ public class HlsChunkSource { ...@@ -189,6 +197,7 @@ public class HlsChunkSource {
enabledVariants = filterVariants((HlsMasterPlaylist) playlist, variantIndices); enabledVariants = filterVariants((HlsMasterPlaylist) playlist, variantIndices);
mediaPlaylists = new HlsMediaPlaylist[enabledVariants.length]; mediaPlaylists = new HlsMediaPlaylist[enabledVariants.length];
mediaPlaylistBlacklistFlags = new boolean[enabledVariants.length]; mediaPlaylistBlacklistFlags = new boolean[enabledVariants.length];
mediaPlaylistBlacklistedTimeMs = new long[enabledVariants.length];
lastMediaPlaylistLoadTimesMs = new long[enabledVariants.length]; lastMediaPlaylistLoadTimesMs = new long[enabledVariants.length];
} }
...@@ -362,6 +371,7 @@ public class HlsChunkSource { ...@@ -362,6 +371,7 @@ public class HlsChunkSource {
if (responseCode == 404 || responseCode == 410) { if (responseCode == 404 || responseCode == 410) {
MediaPlaylistChunk playlistChunk = (MediaPlaylistChunk) chunk; MediaPlaylistChunk playlistChunk = (MediaPlaylistChunk) chunk;
mediaPlaylistBlacklistFlags[playlistChunk.variantIndex] = true; mediaPlaylistBlacklistFlags[playlistChunk.variantIndex] = true;
mediaPlaylistBlacklistedTimeMs[playlistChunk.variantIndex] = SystemClock.elapsedRealtime();
if (!allPlaylistsBlacklisted()) { if (!allPlaylistsBlacklisted()) {
// We've handled the 404/410 by blacklisting the playlist. // We've handled the 404/410 by blacklisting the playlist.
Log.w(TAG, "Blacklisted playlist (" + responseCode + "): " Log.w(TAG, "Blacklisted playlist (" + responseCode + "): "
...@@ -372,6 +382,7 @@ public class HlsChunkSource { ...@@ -372,6 +382,7 @@ public class HlsChunkSource {
Log.w(TAG, "Final playlist not blacklisted (" + responseCode + "): " Log.w(TAG, "Final playlist not blacklisted (" + responseCode + "): "
+ playlistChunk.dataSpec.uri); + playlistChunk.dataSpec.uri);
mediaPlaylistBlacklistFlags[playlistChunk.variantIndex] = false; mediaPlaylistBlacklistFlags[playlistChunk.variantIndex] = false;
mediaPlaylistBlacklistedTimeMs[playlistChunk.variantIndex] = 0;
return false; return false;
} }
} }
...@@ -380,6 +391,7 @@ public class HlsChunkSource { ...@@ -380,6 +391,7 @@ public class HlsChunkSource {
} }
private int getNextVariantIndex(TsChunk previousTsChunk, long playbackPositionUs) { private int getNextVariantIndex(TsChunk previousTsChunk, long playbackPositionUs) {
clearStaleBlacklistedPlaylists();
int idealVariantIndex = getVariantIndexForBandwdith( int idealVariantIndex = getVariantIndexForBandwdith(
(int) (bandwidthMeter.getBitrateEstimate() * BANDWIDTH_FRACTION)); (int) (bandwidthMeter.getBitrateEstimate() * BANDWIDTH_FRACTION));
if (idealVariantIndex == variantIndex) { if (idealVariantIndex == variantIndex) {
...@@ -541,6 +553,17 @@ public class HlsChunkSource { ...@@ -541,6 +553,17 @@ public class HlsChunkSource {
return true; return true;
} }
private void clearStaleBlacklistedPlaylists() {
long currentTime = SystemClock.elapsedRealtime();
for (int i = 0; i < mediaPlaylistBlacklistFlags.length; i++) {
if (mediaPlaylistBlacklistFlags[i] &&
currentTime - mediaPlaylistBlacklistedTimeMs[i] > DEFAULT_MAX_TIME_MEDIA_PLAYLIST_BLACKLISTED_MS) {
mediaPlaylistBlacklistFlags[i] = false;
mediaPlaylistBlacklistedTimeMs[i] = 0;
}
}
}
private class MediaPlaylistChunk extends DataChunk { private class MediaPlaylistChunk extends DataChunk {
@SuppressWarnings("hiding") @SuppressWarnings("hiding")
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment