Fix HLS track selection.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=123851448
This commit is contained in:
olly 2016-06-02 04:36:37 -07:00 committed by Oliver Woodman
parent 94fa2ecfe5
commit 4888592c76
3 changed files with 27 additions and 53 deletions

View file

@ -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;
}
/**

View file

@ -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<TrackStream> allOldStreams, List<TrackSelection> allNewSelections, long positionUs,
List<TrackStream> allOldStreams, List<TrackSelection> allNewSelections,
TrackStream[] allNewStreams) {
// Get the subset of the old streams for the source.
ArrayList<TrackStream> 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);

View file

@ -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<TrackStream> oldStreams,
List<TrackSelection> newSelections, long positionUs) {
List<TrackSelection> 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();