From 4888592c76be25d74378817451c1e7eba044ee54 Mon Sep 17 00:00:00 2001 From: olly Date: Thu, 2 Jun 2016 04:36:37 -0700 Subject: [PATCH] Fix HLS track selection. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=123851448 --- .../android/exoplayer/hls/HlsChunkSource.java | 18 ++----- .../exoplayer/hls/HlsSampleSource.java | 11 ++-- .../exoplayer/hls/HlsTrackStreamWrapper.java | 51 ++++++------------- 3 files changed, 27 insertions(+), 53 deletions(-) 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 e669fa536a..07641d4952 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 @@ -112,7 +112,7 @@ public class HlsChunkSource { evaluation = new Evaluation(); variantPlaylists = new HlsMediaPlaylist[variants.length]; variantLastPlaylistLoadTimesMs = new long[variants.length]; - selectTracks(new int[] {0}); + selectTracks(new int[] {0}, false); } /** @@ -187,11 +187,9 @@ public class HlsChunkSource { * This method should only be called after the source has been prepared. * * @param tracks The track indices. - * @return True if one or more tracks was unselected. False otherwise. + * @param isFirstTrackSelection True if this is the first selection, false otherwise. */ - public boolean selectTracks(int[] tracks) { - Variant[] oldEnabledVariants = enabledVariants; - + public void selectTracks(int[] tracks, boolean isFirstTrackSelection) { // Construct and sort the enabled variants. enabledVariants = new Variant[tracks.length]; for (int i = 0; i < tracks.length; i++) { @@ -217,16 +215,10 @@ public class HlsChunkSource { } // TODO[REFACTOR]: We need to disable this at some point. adaptiveFormatEvaluator.enable(formats); - } - - if (oldEnabledVariants != null) { - for (Variant oldVariant : oldEnabledVariants) { - if (!Util.contains(enabledVariants, oldVariant)) { - return true; - } + if (!isFirstTrackSelection || !Util.contains(formats, evaluation.format)) { + evaluation.format = null; } } - return false; } /** 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 6a1b8d7043..9dacf05b35 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 @@ -163,7 +163,7 @@ public final class HlsSampleSource implements SampleSource, int enabledTrackStreamWrapperCount = 0; for (int i = 0; i < trackStreamWrappers.length; i++) { selectedTrackCounts[i] += selectTracks(trackStreamWrappers[i], oldStreams, newSelections, - positionUs, newStreams); + newStreams); if (selectedTrackCounts[i] > 0) { enabledTrackStreamWrapperCount++; } @@ -176,6 +176,9 @@ public final class HlsSampleSource implements SampleSource, enabledTrackStreamWrappers[enabledTrackStreamWrapperCount++] = trackStreamWrappers[i]; } } + if (enabledTrackStreamWrapperCount > 0 && seenFirstTrackSelection && !newSelections.isEmpty()) { + seekToUs(positionUs); + } seenFirstTrackSelection = true; return newStreams; } @@ -220,7 +223,7 @@ public final class HlsSampleSource implements SampleSource, timestampAdjusterProvider.reset(); for (HlsTrackStreamWrapper trackStreamWrapper : enabledTrackStreamWrappers) { trackStreamWrapper.setReadingEnabled(false); - trackStreamWrapper.seekToUs(positionUs); + trackStreamWrapper.restartFrom(positionUs); } } @@ -335,7 +338,7 @@ public final class HlsSampleSource implements SampleSource, } private int selectTracks(HlsTrackStreamWrapper trackStreamWrapper, - List allOldStreams, List allNewSelections, long positionUs, + List allOldStreams, List allNewSelections, TrackStream[] allNewStreams) { // Get the subset of the old streams for the source. ArrayList oldStreams = new ArrayList<>(); @@ -363,7 +366,7 @@ public final class HlsSampleSource implements SampleSource, } // Perform the selection. TrackStream[] newStreams = trackStreamWrapper.selectTracks(oldStreams, newSelections, - positionUs); + !seenFirstTrackSelection); for (int j = 0; j < newStreams.length; j++) { allNewStreams[newSelectionOriginalIndices[j]] = newStreams[j]; trackStreamSources.put(newStreams[j], trackStreamWrapper); diff --git a/library/src/main/java/com/google/android/exoplayer/hls/HlsTrackStreamWrapper.java b/library/src/main/java/com/google/android/exoplayer/hls/HlsTrackStreamWrapper.java index 01c211da50..ad3de7b79b 100644 --- a/library/src/main/java/com/google/android/exoplayer/hls/HlsTrackStreamWrapper.java +++ b/library/src/main/java/com/google/android/exoplayer/hls/HlsTrackStreamWrapper.java @@ -69,7 +69,6 @@ import java.util.List; private volatile boolean sampleQueuesBuilt; private boolean prepared; - private boolean seenFirstTrackSelection; private boolean readingEnabled; private int enabledTrackCount; private Format downstreamFormat; @@ -171,7 +170,7 @@ import java.util.List; } public TrackStream[] selectTracks(List oldStreams, - List newSelections, long positionUs) { + List newSelections, boolean isFirstTrackSelection) { Assertions.checkState(prepared); boolean tracksWereEnabled = enabledTrackCount > 0; // Unselect old tracks. @@ -180,7 +179,6 @@ import java.util.List; setTrackGroupEnabledState(group, false); } // Select new tracks. - boolean primaryTracksDeselected = false; TrackStream[] newStreams = new TrackStream[newSelections.size()]; for (int i = 0; i < newStreams.length; i++) { TrackSelection selection = newSelections.get(i); @@ -189,7 +187,7 @@ import java.util.List; setTrackGroupEnabledState(group, true); sampleQueues.valueAt(group).needDownstreamFormat(); if (group == primaryTrackGroupIndex) { - primaryTracksDeselected |= chunkSource.selectTracks(tracks); + chunkSource.selectTracks(tracks, isFirstTrackSelection); } newStreams[i] = new TrackStreamImpl(group); } @@ -207,15 +205,9 @@ import java.util.List; clearState(); loadControl.trimAllocator(); } - } else { - if (!tracksWereEnabled) { - loadControl.register(this, bufferSizeContribution); - } - if (primaryTracksDeselected || (seenFirstTrackSelection && newStreams.length > 0)) { - seekToInternal(positionUs); - } + } else if (!tracksWereEnabled) { + loadControl.register(this, bufferSizeContribution); } - seenFirstTrackSelection = true; return newStreams; } @@ -253,8 +245,17 @@ import java.util.List; } } - public void seekToUs(long positionUs) { - seekToInternal(positionUs); + public void restartFrom(long positionUs) { + lastSeekPositionUs = positionUs; + downstreamPositionUs = positionUs; + pendingResetPositionUs = positionUs; + loadingFinished = false; + if (loader.isLoading()) { + loader.cancelLoading(); + } else { + clearState(); + maybeStartLoading(); + } } public void release() { @@ -500,17 +501,6 @@ import java.util.List; containerFormat.width, containerFormat.height, 0, containerFormat.language); } - /** - * Performs a seek. The operation is performed even if the seek is to the current position. - * - * @param positionUs The position to seek to. - */ - private void seekToInternal(long positionUs) { - lastSeekPositionUs = positionUs; - downstreamPositionUs = positionUs; - restartFrom(positionUs); - } - private void discardSamplesForDisabledTracks() { if (!prepared) { return; @@ -522,17 +512,6 @@ import java.util.List; } } - private void restartFrom(long positionUs) { - pendingResetPositionUs = positionUs; - loadingFinished = false; - if (loader.isLoading()) { - loader.cancelLoading(); - } else { - clearState(); - maybeStartLoading(); - } - } - private void clearState() { for (int i = 0; i < sampleQueues.size(); i++) { sampleQueues.valueAt(i).clear();