Bugfix: Allow discontinuity on selectTracks
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=129987709
This commit is contained in:
parent
153c0aef2b
commit
f9005c7a78
@ -727,8 +727,13 @@ import java.io.IOException;
|
|||||||
|
|
||||||
// Update streams for the new selection, recreating all streams if reading ahead.
|
// Update streams for the new selection, recreating all streams if reading ahead.
|
||||||
boolean recreateStreams = readingPeriod != playingPeriod;
|
boolean recreateStreams = readingPeriod != playingPeriod;
|
||||||
boolean[] streamResetFlags = playingPeriod.updatePeriodTrackSelection(playbackInfo.positionUs,
|
boolean[] streamResetFlags = new boolean[renderers.length];
|
||||||
loadControl, recreateStreams);
|
long positionUs = playingPeriod.updatePeriodTrackSelection(playbackInfo.positionUs,
|
||||||
|
loadControl, recreateStreams, streamResetFlags);
|
||||||
|
if (positionUs != playbackInfo.positionUs) {
|
||||||
|
playbackInfo.positionUs = positionUs;
|
||||||
|
resetInternalPosition(positionUs);
|
||||||
|
}
|
||||||
|
|
||||||
int enabledRendererCount = 0;
|
int enabledRendererCount = 0;
|
||||||
boolean[] rendererWasEnabledFlags = new boolean[renderers.length];
|
boolean[] rendererWasEnabledFlags = new boolean[renderers.length];
|
||||||
@ -1156,12 +1161,12 @@ import java.io.IOException;
|
|||||||
|
|
||||||
public final MediaPeriod mediaPeriod;
|
public final MediaPeriod mediaPeriod;
|
||||||
public final Object id;
|
public final Object id;
|
||||||
public final long startPositionUs;
|
|
||||||
|
|
||||||
public final SampleStream[] sampleStreams;
|
public final SampleStream[] sampleStreams;
|
||||||
public final boolean[] mayRetainStreamFlags;
|
public final boolean[] mayRetainStreamFlags;
|
||||||
|
|
||||||
public int index;
|
public int index;
|
||||||
|
public long startPositionUs;
|
||||||
public boolean isLast;
|
public boolean isLast;
|
||||||
public boolean prepared;
|
public boolean prepared;
|
||||||
public boolean hasEnabledTracks;
|
public boolean hasEnabledTracks;
|
||||||
@ -1205,7 +1210,7 @@ import java.io.IOException;
|
|||||||
throws ExoPlaybackException {
|
throws ExoPlaybackException {
|
||||||
prepared = true;
|
prepared = true;
|
||||||
selectTracks();
|
selectTracks();
|
||||||
updatePeriodTrackSelection(positionUs, loadControl, false);
|
startPositionUs = updatePeriodTrackSelection(positionUs, loadControl, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean selectTracks() throws ExoPlaybackException {
|
public boolean selectTracks() throws ExoPlaybackException {
|
||||||
@ -1220,19 +1225,23 @@ import java.io.IOException;
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean[] updatePeriodTrackSelection(long positionUs, LoadControl loadControl,
|
public long updatePeriodTrackSelection(long positionUs, LoadControl loadControl,
|
||||||
boolean forceRecreateStreams) throws ExoPlaybackException {
|
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++) {
|
for (int i = 0; i < trackSelections.length; i++) {
|
||||||
mayRetainStreamFlags[i] = !forceRecreateStreams
|
mayRetainStreamFlags[i] = !forceRecreateStreams
|
||||||
&& Util.areEqual(periodTrackSelections == null ? null : periodTrackSelections.get(i),
|
&& Util.areEqual(periodTrackSelections == null ? null : periodTrackSelections.get(i),
|
||||||
trackSelections.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.
|
// Disable streams on the period and get new streams for updated/newly-enabled tracks.
|
||||||
mediaPeriod.selectTracks(trackSelections.getAll(), mayRetainStreamFlags, sampleStreams,
|
positionUs = mediaPeriod.selectTracks(trackSelections.getAll(), mayRetainStreamFlags,
|
||||||
streamResetFlags, positionUs);
|
sampleStreams, streamResetFlags, positionUs);
|
||||||
periodTrackSelections = trackSelections;
|
periodTrackSelections = trackSelections;
|
||||||
|
|
||||||
hasEnabledTracks = false;
|
hasEnabledTracks = false;
|
||||||
@ -1245,8 +1254,7 @@ import java.io.IOException;
|
|||||||
|
|
||||||
// The track selection has changed.
|
// The track selection has changed.
|
||||||
loadControl.onTrackSelections(renderers, mediaPeriod.getTrackGroups(), trackSelections);
|
loadControl.onTrackSelections(renderers, mediaPeriod.getTrackGroups(), trackSelections);
|
||||||
|
return positionUs;
|
||||||
return streamResetFlags;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void release() {
|
public void release() {
|
||||||
|
@ -239,7 +239,7 @@ public final class ExtractorMediaSource implements MediaPeriod, MediaSource,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags,
|
public long selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags,
|
||||||
SampleStream[] streams, boolean[] streamResetFlags, long positionUs) {
|
SampleStream[] streams, boolean[] streamResetFlags, long positionUs) {
|
||||||
Assertions.checkState(prepared);
|
Assertions.checkState(prepared);
|
||||||
// Disable old tracks.
|
// Disable old tracks.
|
||||||
@ -284,7 +284,7 @@ public final class ExtractorMediaSource implements MediaPeriod, MediaSource,
|
|||||||
loader.cancelLoading();
|
loader.cancelLoading();
|
||||||
}
|
}
|
||||||
} else if (seenFirstTrackSelection ? selectedNewTracks : positionUs != 0) {
|
} 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.
|
// We'll need to reset renderers consuming from all streams due to the seek.
|
||||||
for (int i = 0; i < streams.length; i++) {
|
for (int i = 0; i < streams.length; i++) {
|
||||||
if (streams[i] != null) {
|
if (streams[i] != null) {
|
||||||
@ -293,6 +293,7 @@ public final class ExtractorMediaSource implements MediaPeriod, MediaSource,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
seenFirstTrackSelection = true;
|
seenFirstTrackSelection = true;
|
||||||
|
return positionUs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -110,8 +110,9 @@ public interface MediaPeriod extends SequenceableLoader {
|
|||||||
* @param streamResetFlags Will be updated to indicate new sample streams, and sample streams that
|
* @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.
|
* have been retained but with the requirement that the consuming renderer be reset.
|
||||||
* @param positionUs The current playback position in microseconds.
|
* @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);
|
SampleStream[] streams, boolean[] streamResetFlags, long positionUs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -70,7 +70,7 @@ public final class MergingMediaPeriod implements MediaPeriod, MediaPeriod.Callba
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags,
|
public long selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags,
|
||||||
SampleStream[] streams, boolean[] streamResetFlags, long positionUs) {
|
SampleStream[] streams, boolean[] streamResetFlags, long positionUs) {
|
||||||
// Map each selection and stream onto a child period index.
|
// Map each selection and stream onto a child period index.
|
||||||
int[] streamChildIndices = new int[selections.length];
|
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;
|
childStreams[j] = streamChildIndices[j] == i ? streams[j] : null;
|
||||||
childSelections[j] = selectionChildIndices[j] == i ? selections[j] : null;
|
childSelections[j] = selectionChildIndices[j] == i ? selections[j] : null;
|
||||||
}
|
}
|
||||||
periods[i].selectTracks(childSelections, mayRetainStreamFlags, childStreams, streamResetFlags,
|
long selectPositionUs = periods[i].selectTracks(childSelections, mayRetainStreamFlags,
|
||||||
positionUs);
|
childStreams, streamResetFlags, positionUs);
|
||||||
|
if (i == 0) {
|
||||||
|
positionUs = selectPositionUs;
|
||||||
|
} else if (selectPositionUs != positionUs) {
|
||||||
|
throw new IllegalStateException("Children enabled at different positions");
|
||||||
|
}
|
||||||
boolean periodEnabled = false;
|
boolean periodEnabled = false;
|
||||||
for (int j = 0; j < selections.length; j++) {
|
for (int j = 0; j < selections.length; j++) {
|
||||||
if (selectionChildIndices[j] == i) {
|
if (selectionChildIndices[j] == i) {
|
||||||
@ -118,6 +123,7 @@ public final class MergingMediaPeriod implements MediaPeriod, MediaPeriod.Callba
|
|||||||
enabledPeriods = new MediaPeriod[enabledPeriodsList.size()];
|
enabledPeriods = new MediaPeriod[enabledPeriodsList.size()];
|
||||||
enabledPeriodsList.toArray(enabledPeriods);
|
enabledPeriodsList.toArray(enabledPeriods);
|
||||||
sequenceableLoader = new CompositeSequenceableLoader(enabledPeriods);
|
sequenceableLoader = new CompositeSequenceableLoader(enabledPeriods);
|
||||||
|
return positionUs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -158,7 +158,7 @@ public final class SingleSampleMediaSource implements MediaPeriod, MediaSource,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags,
|
public long selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags,
|
||||||
SampleStream[] streams, boolean[] streamResetFlags, long positionUs) {
|
SampleStream[] streams, boolean[] streamResetFlags, long positionUs) {
|
||||||
for (int i = 0; i < selections.length; i++) {
|
for (int i = 0; i < selections.length; i++) {
|
||||||
if (streams[i] != null && (selections[i] == null || !mayRetainStreamFlags[i])) {
|
if (streams[i] != null && (selections[i] == null || !mayRetainStreamFlags[i])) {
|
||||||
@ -172,6 +172,7 @@ public final class SingleSampleMediaSource implements MediaPeriod, MediaSource,
|
|||||||
streamResetFlags[i] = true;
|
streamResetFlags[i] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return positionUs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -118,7 +118,7 @@ import java.util.List;
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags,
|
public long selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags,
|
||||||
SampleStream[] streams, boolean[] streamResetFlags, long positionUs) {
|
SampleStream[] streams, boolean[] streamResetFlags, long positionUs) {
|
||||||
ArrayList<ChunkSampleStream<DashChunkSource>> sampleStreamsList = new ArrayList<>();
|
ArrayList<ChunkSampleStream<DashChunkSource>> sampleStreamsList = new ArrayList<>();
|
||||||
for (int i = 0; i < selections.length; i++) {
|
for (int i = 0; i < selections.length; i++) {
|
||||||
@ -142,6 +142,7 @@ import java.util.List;
|
|||||||
sampleStreams = newSampleStreamArray(sampleStreamsList.size());
|
sampleStreams = newSampleStreamArray(sampleStreamsList.size());
|
||||||
sampleStreamsList.toArray(sampleStreams);
|
sampleStreamsList.toArray(sampleStreams);
|
||||||
sequenceableLoader = new CompositeSequenceableLoader(sampleStreams);
|
sequenceableLoader = new CompositeSequenceableLoader(sampleStreams);
|
||||||
|
return positionUs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -171,7 +171,7 @@ public final class HlsMediaSource implements MediaPeriod, MediaSource,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags,
|
public long selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags,
|
||||||
SampleStream[] streams, boolean[] streamResetFlags, long positionUs) {
|
SampleStream[] streams, boolean[] streamResetFlags, long positionUs) {
|
||||||
// Map each selection and stream onto a child period index.
|
// Map each selection and stream onto a child period index.
|
||||||
int[] streamChildIndices = new int[selections.length];
|
int[] streamChildIndices = new int[selections.length];
|
||||||
@ -231,6 +231,7 @@ public final class HlsMediaSource implements MediaPeriod, MediaSource,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
seenFirstTrackSelection = true;
|
seenFirstTrackSelection = true;
|
||||||
|
return positionUs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -109,7 +109,7 @@ import java.util.ArrayList;
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags,
|
public long selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags,
|
||||||
SampleStream[] streams, boolean[] streamResetFlags, long positionUs) {
|
SampleStream[] streams, boolean[] streamResetFlags, long positionUs) {
|
||||||
ArrayList<ChunkSampleStream<SsChunkSource>> sampleStreamsList = new ArrayList<>();
|
ArrayList<ChunkSampleStream<SsChunkSource>> sampleStreamsList = new ArrayList<>();
|
||||||
for (int i = 0; i < selections.length; i++) {
|
for (int i = 0; i < selections.length; i++) {
|
||||||
@ -133,6 +133,7 @@ import java.util.ArrayList;
|
|||||||
sampleStreams = newSampleStreamArray(sampleStreamsList.size());
|
sampleStreams = newSampleStreamArray(sampleStreamsList.size());
|
||||||
sampleStreamsList.toArray(sampleStreams);
|
sampleStreamsList.toArray(sampleStreams);
|
||||||
sequenceableLoader = new CompositeSequenceableLoader(sampleStreams);
|
sequenceableLoader = new CompositeSequenceableLoader(sampleStreams);
|
||||||
|
return positionUs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
x
Reference in New Issue
Block a user