Commit a3be9376 by olly Committed by Oliver Woodman

Prevent unnecessary consecutive playlist loads

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=170078933
parent 792f046c
......@@ -363,9 +363,8 @@ public final class HlsPlaylistTracker implements Loader.Callback<ParsingLoadable
*
* @param url The url of the playlist.
* @param newSnapshot The new snapshot.
* @return True if a refresh should be scheduled.
*/
private boolean onPlaylistUpdated(HlsUrl url, HlsMediaPlaylist newSnapshot) {
private void onPlaylistUpdated(HlsUrl url, HlsMediaPlaylist newSnapshot) {
if (url == primaryHlsUrl) {
if (primaryUrlSnapshot == null) {
// This is the first primary url snapshot.
......@@ -378,8 +377,6 @@ public final class HlsPlaylistTracker implements Loader.Callback<ParsingLoadable
for (int i = 0; i < listenersSize; i++) {
listeners.get(i).onPlaylistChanged();
}
// If the primary playlist is not the final one, we should schedule a refresh.
return url == primaryHlsUrl && !newSnapshot.hasEndTag;
}
private void notifyPlaylistBlacklisting(HlsUrl url, long blacklistMs) {
......@@ -469,8 +466,9 @@ public final class HlsPlaylistTracker implements Loader.Callback<ParsingLoadable
private HlsMediaPlaylist playlistSnapshot;
private long lastSnapshotLoadMs;
private long lastSnapshotChangeMs;
private long earliestNextLoadTimeMs;
private long blacklistUntilMs;
private boolean pendingRefresh;
private boolean loadPending;
private IOException playlistError;
public MediaPlaylistBundle(HlsUrl playlistUrl) {
......@@ -504,8 +502,16 @@ public final class HlsPlaylistTracker implements Loader.Callback<ParsingLoadable
public void loadPlaylist() {
blacklistUntilMs = 0;
if (!pendingRefresh && !mediaPlaylistLoader.isLoading()) {
mediaPlaylistLoader.startLoading(mediaPlaylistLoadable, this, minRetryCount);
if (loadPending || mediaPlaylistLoader.isLoading()) {
// Load already pending or in progress. Do nothing.
return;
}
long currentTimeMs = SystemClock.elapsedRealtime();
if (currentTimeMs < earliestNextLoadTimeMs) {
loadPending = true;
playlistRefreshHandler.postDelayed(this, earliestNextLoadTimeMs - currentTimeMs);
} else {
loadPlaylistImmediately();
}
}
......@@ -549,8 +555,7 @@ public final class HlsPlaylistTracker implements Loader.Callback<ParsingLoadable
}
boolean shouldRetry = true;
if (ChunkedTrackBlacklistUtil.shouldBlacklist(error)) {
blacklistPlaylist();
shouldRetry = primaryHlsUrl == playlistUrl && !maybeSelectNewPrimaryUrl();
shouldRetry = blacklistPlaylist();
}
return shouldRetry ? Loader.RETRY : Loader.DONT_RETRY;
}
......@@ -559,48 +564,60 @@ public final class HlsPlaylistTracker implements Loader.Callback<ParsingLoadable
@Override
public void run() {
pendingRefresh = false;
loadPlaylist();
loadPending = false;
loadPlaylistImmediately();
}
// Internal methods.
private void loadPlaylistImmediately() {
mediaPlaylistLoader.startLoading(mediaPlaylistLoadable, this, minRetryCount);
}
private void processLoadedPlaylist(HlsMediaPlaylist loadedPlaylist) {
HlsMediaPlaylist oldPlaylist = playlistSnapshot;
long currentTimeMs = SystemClock.elapsedRealtime();
lastSnapshotLoadMs = currentTimeMs;
playlistSnapshot = getLatestPlaylistSnapshot(oldPlaylist, loadedPlaylist);
long refreshDelayUs = C.TIME_UNSET;
if (playlistSnapshot != oldPlaylist) {
playlistError = null;
lastSnapshotChangeMs = currentTimeMs;
if (onPlaylistUpdated(playlistUrl, playlistSnapshot)) {
refreshDelayUs = playlistSnapshot.targetDurationUs;
}
onPlaylistUpdated(playlistUrl, playlistSnapshot);
} else if (!playlistSnapshot.hasEndTag) {
if (currentTimeMs - lastSnapshotChangeMs
if (loadedPlaylist.mediaSequence + loadedPlaylist.segments.size()
< playlistSnapshot.mediaSequence) {
// The media sequence jumped backwards. The server has probably reset.
playlistError = new PlaylistResetException(playlistUrl.url);
} else if (currentTimeMs - lastSnapshotChangeMs
> C.usToMs(playlistSnapshot.targetDurationUs)
* PLAYLIST_STUCK_TARGET_DURATION_COEFFICIENT) {
// The playlist seems to be stuck, we blacklist it.
// The playlist seems to be stuck. Blacklist it.
playlistError = new PlaylistStuckException(playlistUrl.url);
blacklistPlaylist();
} else if (loadedPlaylist.mediaSequence + loadedPlaylist.segments.size()
< playlistSnapshot.mediaSequence) {
// The media sequence has jumped backwards. The server has likely reset.
playlistError = new PlaylistResetException(playlistUrl.url);
}
refreshDelayUs = playlistSnapshot.targetDurationUs / 2;
}
if (refreshDelayUs != C.TIME_UNSET) {
// See HLS spec v20, section 6.3.4 for more information on media playlist refreshing.
pendingRefresh = playlistRefreshHandler.postDelayed(this, C.usToMs(refreshDelayUs));
// Do not allow the playlist to load again within the target duration if we obtained a new
// snapshot, or half the target duration otherwise.
earliestNextLoadTimeMs = currentTimeMs + C.usToMs(playlistSnapshot != oldPlaylist
? playlistSnapshot.targetDurationUs : (playlistSnapshot.targetDurationUs / 2));
// Schedule a load if this is the primary playlist and it doesn't have an end tag. Else the
// next load will be scheduled when refreshPlaylist is called, or when this playlist becomes
// the primary.
if (playlistUrl == primaryHlsUrl && !playlistSnapshot.hasEndTag) {
loadPlaylist();
}
}
private void blacklistPlaylist() {
/**
* Blacklists the playlist.
*
* @return Whether the playlist is the primary, despite being blacklisted.
*/
private boolean blacklistPlaylist() {
blacklistUntilMs = SystemClock.elapsedRealtime()
+ ChunkedTrackBlacklistUtil.DEFAULT_TRACK_BLACKLIST_MS;
notifyPlaylistBlacklisting(playlistUrl, ChunkedTrackBlacklistUtil.DEFAULT_TRACK_BLACKLIST_MS);
return primaryHlsUrl == playlistUrl && !maybeSelectNewPrimaryUrl();
}
}
......
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