Bugfix: Allow discontinuity on selectTracks

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=129987709
This commit is contained in:
olly 2016-08-11 08:14:02 -07:00 committed by Oliver Woodman
parent 153c0aef2b
commit f9005c7a78
8 changed files with 41 additions and 21 deletions

View File

@ -727,8 +727,13 @@ import java.io.IOException;
// Update streams for the new selection, recreating all streams if reading ahead.
boolean recreateStreams = readingPeriod != playingPeriod;
boolean[] streamResetFlags = playingPeriod.updatePeriodTrackSelection(playbackInfo.positionUs,
loadControl, recreateStreams);
boolean[] streamResetFlags = new boolean[renderers.length];
long positionUs = playingPeriod.updatePeriodTrackSelection(playbackInfo.positionUs,
loadControl, recreateStreams, streamResetFlags);
if (positionUs != playbackInfo.positionUs) {
playbackInfo.positionUs = positionUs;
resetInternalPosition(positionUs);
}
int enabledRendererCount = 0;
boolean[] rendererWasEnabledFlags = new boolean[renderers.length];
@ -1156,12 +1161,12 @@ import java.io.IOException;
public final MediaPeriod mediaPeriod;
public final Object id;
public final long startPositionUs;
public final SampleStream[] sampleStreams;
public final boolean[] mayRetainStreamFlags;
public int index;
public long startPositionUs;
public boolean isLast;
public boolean prepared;
public boolean hasEnabledTracks;
@ -1205,7 +1210,7 @@ import java.io.IOException;
throws ExoPlaybackException {
prepared = true;
selectTracks();
updatePeriodTrackSelection(positionUs, loadControl, false);
startPositionUs = updatePeriodTrackSelection(positionUs, loadControl, false);
}
public boolean selectTracks() throws ExoPlaybackException {
@ -1220,19 +1225,23 @@ import java.io.IOException;
return true;
}
public boolean[] updatePeriodTrackSelection(long positionUs, LoadControl loadControl,
public long updatePeriodTrackSelection(long positionUs, LoadControl loadControl,
boolean forceRecreateStreams) throws ExoPlaybackException {
return updatePeriodTrackSelection(positionUs, loadControl, forceRecreateStreams,
new boolean[renderers.length]);
}
public long updatePeriodTrackSelection(long positionUs, LoadControl loadControl,
boolean forceRecreateStreams, boolean[] streamResetFlags) throws ExoPlaybackException {
for (int i = 0; i < trackSelections.length; i++) {
mayRetainStreamFlags[i] = !forceRecreateStreams
&& Util.areEqual(periodTrackSelections == null ? null : periodTrackSelections.get(i),
trackSelections.get(i));
}
boolean[] streamResetFlags = new boolean[renderers.length];
// Disable streams on the period and get new streams for updated/newly-enabled tracks.
mediaPeriod.selectTracks(trackSelections.getAll(), mayRetainStreamFlags, sampleStreams,
streamResetFlags, positionUs);
positionUs = mediaPeriod.selectTracks(trackSelections.getAll(), mayRetainStreamFlags,
sampleStreams, streamResetFlags, positionUs);
periodTrackSelections = trackSelections;
hasEnabledTracks = false;
@ -1245,8 +1254,7 @@ import java.io.IOException;
// The track selection has changed.
loadControl.onTrackSelections(renderers, mediaPeriod.getTrackGroups(), trackSelections);
return streamResetFlags;
return positionUs;
}
public void release() {

View File

@ -239,7 +239,7 @@ public final class ExtractorMediaSource implements MediaPeriod, MediaSource,
}
@Override
public void selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags,
public long selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags,
SampleStream[] streams, boolean[] streamResetFlags, long positionUs) {
Assertions.checkState(prepared);
// Disable old tracks.
@ -284,7 +284,7 @@ public final class ExtractorMediaSource implements MediaPeriod, MediaSource,
loader.cancelLoading();
}
} else if (seenFirstTrackSelection ? selectedNewTracks : positionUs != 0) {
seekToUs(positionUs);
positionUs = seekToUs(positionUs);
// We'll need to reset renderers consuming from all streams due to the seek.
for (int i = 0; i < streams.length; i++) {
if (streams[i] != null) {
@ -293,6 +293,7 @@ public final class ExtractorMediaSource implements MediaPeriod, MediaSource,
}
}
seenFirstTrackSelection = true;
return positionUs;
}
@Override

View File

@ -110,8 +110,9 @@ public interface MediaPeriod extends SequenceableLoader {
* @param streamResetFlags Will be updated to indicate new sample streams, and sample streams that
* have been retained but with the requirement that the consuming renderer be reset.
* @param positionUs The current playback position in microseconds.
* @return The actual position at which the tracks were enabled, in microseconds.
*/
void selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags,
long selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags,
SampleStream[] streams, boolean[] streamResetFlags, long positionUs);
/**

View File

@ -70,7 +70,7 @@ public final class MergingMediaPeriod implements MediaPeriod, MediaPeriod.Callba
}
@Override
public void selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags,
public long selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags,
SampleStream[] streams, boolean[] streamResetFlags, long positionUs) {
// Map each selection and stream onto a child period index.
int[] streamChildIndices = new int[selections.length];
@ -98,8 +98,13 @@ public final class MergingMediaPeriod implements MediaPeriod, MediaPeriod.Callba
childStreams[j] = streamChildIndices[j] == i ? streams[j] : null;
childSelections[j] = selectionChildIndices[j] == i ? selections[j] : null;
}
periods[i].selectTracks(childSelections, mayRetainStreamFlags, childStreams, streamResetFlags,
positionUs);
long selectPositionUs = periods[i].selectTracks(childSelections, mayRetainStreamFlags,
childStreams, streamResetFlags, positionUs);
if (i == 0) {
positionUs = selectPositionUs;
} else if (selectPositionUs != positionUs) {
throw new IllegalStateException("Children enabled at different positions");
}
boolean periodEnabled = false;
for (int j = 0; j < selections.length; j++) {
if (selectionChildIndices[j] == i) {
@ -118,6 +123,7 @@ public final class MergingMediaPeriod implements MediaPeriod, MediaPeriod.Callba
enabledPeriods = new MediaPeriod[enabledPeriodsList.size()];
enabledPeriodsList.toArray(enabledPeriods);
sequenceableLoader = new CompositeSequenceableLoader(enabledPeriods);
return positionUs;
}
@Override

View File

@ -158,7 +158,7 @@ public final class SingleSampleMediaSource implements MediaPeriod, MediaSource,
}
@Override
public void selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags,
public long selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags,
SampleStream[] streams, boolean[] streamResetFlags, long positionUs) {
for (int i = 0; i < selections.length; i++) {
if (streams[i] != null && (selections[i] == null || !mayRetainStreamFlags[i])) {
@ -172,6 +172,7 @@ public final class SingleSampleMediaSource implements MediaPeriod, MediaSource,
streamResetFlags[i] = true;
}
}
return positionUs;
}
@Override

View File

@ -118,7 +118,7 @@ import java.util.List;
}
@Override
public void selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags,
public long selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags,
SampleStream[] streams, boolean[] streamResetFlags, long positionUs) {
ArrayList<ChunkSampleStream<DashChunkSource>> sampleStreamsList = new ArrayList<>();
for (int i = 0; i < selections.length; i++) {
@ -142,6 +142,7 @@ import java.util.List;
sampleStreams = newSampleStreamArray(sampleStreamsList.size());
sampleStreamsList.toArray(sampleStreams);
sequenceableLoader = new CompositeSequenceableLoader(sampleStreams);
return positionUs;
}
@Override

View File

@ -171,7 +171,7 @@ public final class HlsMediaSource implements MediaPeriod, MediaSource,
}
@Override
public void selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags,
public long selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags,
SampleStream[] streams, boolean[] streamResetFlags, long positionUs) {
// Map each selection and stream onto a child period index.
int[] streamChildIndices = new int[selections.length];
@ -231,6 +231,7 @@ public final class HlsMediaSource implements MediaPeriod, MediaSource,
}
}
seenFirstTrackSelection = true;
return positionUs;
}
@Override

View File

@ -109,7 +109,7 @@ import java.util.ArrayList;
}
@Override
public void selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags,
public long selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags,
SampleStream[] streams, boolean[] streamResetFlags, long positionUs) {
ArrayList<ChunkSampleStream<SsChunkSource>> sampleStreamsList = new ArrayList<>();
for (int i = 0; i < selections.length; i++) {
@ -133,6 +133,7 @@ import java.util.ArrayList;
sampleStreams = newSampleStreamArray(sampleStreamsList.size());
sampleStreamsList.toArray(sampleStreams);
sequenceableLoader = new CompositeSequenceableLoader(sampleStreams);
return positionUs;
}
@Override