Commit f09b86a1 by olly Committed by Oliver Woodman

Fix SampleSource limbo state - Part II

This change optimizes startup and track selection for HLS. Changes
in HlsChunkSource avoid unnecessary re-requests for media playlists.
Changes in HlsSampleSource optimize exit from the limbo state (i.e.
when endTrackSelection is first called).
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=118026962
parent b3ce415e
...@@ -83,8 +83,9 @@ public final class HlsSampleSource implements SampleSource, Loader.Callback { ...@@ -83,8 +83,9 @@ public final class HlsSampleSource implements SampleSource, Loader.Callback {
// Indexed by track (as exposed by this source). // Indexed by track (as exposed by this source).
private TrackGroupArray trackGroups; private TrackGroupArray trackGroups;
private int primaryTrackGroupIndex; private int primaryTrackGroupIndex;
private int[] primarySelectedTracks; private boolean isFirstTrackSelection;
private boolean primarySelectedTracksChanged; private boolean newTracksSelected;
private boolean primaryTracksDeselected;
// Indexed by group. // Indexed by group.
private boolean[] groupEnabledStates; private boolean[] groupEnabledStates;
private boolean[] pendingResets; private boolean[] pendingResets;
...@@ -146,6 +147,7 @@ public final class HlsSampleSource implements SampleSource, Loader.Callback { ...@@ -146,6 +147,7 @@ public final class HlsSampleSource implements SampleSource, Loader.Callback {
if (chunkSource.getTrackCount() == 0) { if (chunkSource.getTrackCount() == 0) {
trackGroups = new TrackGroupArray(); trackGroups = new TrackGroupArray();
state = STATE_SELECTING_TRACKS; state = STATE_SELECTING_TRACKS;
isFirstTrackSelection = true;
return true; return true;
} }
if (!extractors.isEmpty()) { if (!extractors.isEmpty()) {
...@@ -155,6 +157,7 @@ public final class HlsSampleSource implements SampleSource, Loader.Callback { ...@@ -155,6 +157,7 @@ public final class HlsSampleSource implements SampleSource, Loader.Callback {
if (extractor.isPrepared()) { if (extractor.isPrepared()) {
buildTracks(extractor); buildTracks(extractor);
state = STATE_SELECTING_TRACKS; state = STATE_SELECTING_TRACKS;
isFirstTrackSelection = true;
maybeStartLoading(); // Update the load control. maybeStartLoading(); // Update the load control.
return true; return true;
} else if (extractors.size() > 1) { } else if (extractors.size() > 1) {
...@@ -197,7 +200,9 @@ public final class HlsSampleSource implements SampleSource, Loader.Callback { ...@@ -197,7 +200,9 @@ public final class HlsSampleSource implements SampleSource, Loader.Callback {
public void startTrackSelection() { public void startTrackSelection() {
Assertions.checkState(state == STATE_READING); Assertions.checkState(state == STATE_READING);
state = STATE_SELECTING_TRACKS; state = STATE_SELECTING_TRACKS;
primarySelectedTracksChanged = false; isFirstTrackSelection = false;
newTracksSelected = false;
primaryTracksDeselected = false;
} }
@Override @Override
...@@ -208,9 +213,9 @@ public final class HlsSampleSource implements SampleSource, Loader.Callback { ...@@ -208,9 +213,9 @@ public final class HlsSampleSource implements SampleSource, Loader.Callback {
setTrackGroupEnabledState(group, true); setTrackGroupEnabledState(group, true);
downstreamSampleFormats[group] = null; downstreamSampleFormats[group] = null;
pendingResets[group] = false; pendingResets[group] = false;
if (group == primaryTrackGroupIndex && !Arrays.equals(tracks, primarySelectedTracks)) { newTracksSelected = true;
primarySelectedTracks = tracks; if (group == primaryTrackGroupIndex) {
primarySelectedTracksChanged = true; primaryTracksDeselected |= chunkSource.selectTracks(tracks);
} }
return new TrackStreamImpl(group); return new TrackStreamImpl(group);
} }
...@@ -242,24 +247,12 @@ public final class HlsSampleSource implements SampleSource, Loader.Callback { ...@@ -242,24 +247,12 @@ public final class HlsSampleSource implements SampleSource, Loader.Callback {
loadControl.trimAllocator(); loadControl.trimAllocator();
} }
} }
} else { } else if (primaryTracksDeselected || (!isFirstTrackSelection && newTracksSelected)) {
if (!loadControlRegistered) { if (!loadControlRegistered) {
loadControl.register(this, bufferSizeContribution); loadControl.register(this, bufferSizeContribution);
loadControlRegistered = true; loadControlRegistered = true;
} }
// Treat enabling of a live stream as occurring at t=0 in both of the blocks below.
positionUs = chunkSource.isLive() ? 0 : positionUs;
if (primarySelectedTracksChanged) {
// If the primary tracks change then this will affect other exposed tracks that are enabled
// as well. Hence we implement the restart as a seek so that all downstream renderers
// receive a discontinuity event.
chunkSource.selectTracks(primarySelectedTracks);
seekToInternal(positionUs); seekToInternal(positionUs);
} else {
lastSeekPositionUs = positionUs;
downstreamPositionUs = positionUs;
restartFrom(positionUs);
}
} }
} }
...@@ -370,7 +363,7 @@ public final class HlsSampleSource implements SampleSource, Loader.Callback { ...@@ -370,7 +363,7 @@ public final class HlsSampleSource implements SampleSource, Loader.Callback {
if (enabledTrackCount == 0) { if (enabledTrackCount == 0) {
return; return;
} }
seekToInternal(chunkSource.isLive() ? 0 : positionUs); seekToInternal(positionUs);
} }
@Override @Override
...@@ -595,6 +588,8 @@ public final class HlsSampleSource implements SampleSource, Loader.Callback { ...@@ -595,6 +588,8 @@ public final class HlsSampleSource implements SampleSource, Loader.Callback {
* @param positionUs The position to seek to. * @param positionUs The position to seek to.
*/ */
private void seekToInternal(long positionUs) { private void seekToInternal(long positionUs) {
// Treat all seeks into non-seekable media as being to t=0.
positionUs = chunkSource.isLive() ? 0 : positionUs;
lastSeekPositionUs = positionUs; lastSeekPositionUs = positionUs;
downstreamPositionUs = positionUs; downstreamPositionUs = positionUs;
Arrays.fill(pendingResets, true); Arrays.fill(pendingResets, true);
......
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