Allow renderers to read ahead further than the next source.
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=125951381
This commit is contained in:
parent
6031f89fe9
commit
fdd90256f4
@ -111,7 +111,6 @@ import java.util.ArrayList;
|
|||||||
private int customMessagesProcessed;
|
private int customMessagesProcessed;
|
||||||
private long elapsedRealtimeUs;
|
private long elapsedRealtimeUs;
|
||||||
|
|
||||||
private long sourceOffsetUs;
|
|
||||||
private long internalPositionUs;
|
private long internalPositionUs;
|
||||||
|
|
||||||
public ExoPlayerImplInternal(TrackRenderer[] renderers, TrackSelector trackSelector,
|
public ExoPlayerImplInternal(TrackRenderer[] renderers, TrackSelector trackSelector,
|
||||||
@ -356,7 +355,7 @@ import java.util.ArrayList;
|
|||||||
} else {
|
} else {
|
||||||
internalPositionUs = standaloneMediaClock.getPositionUs();
|
internalPositionUs = standaloneMediaClock.getPositionUs();
|
||||||
}
|
}
|
||||||
positionUs = internalPositionUs - sourceOffsetUs;
|
positionUs = internalPositionUs - timeline.playingSource.offsetUs;
|
||||||
}
|
}
|
||||||
playbackInfo.positionUs = positionUs;
|
playbackInfo.positionUs = positionUs;
|
||||||
elapsedRealtimeUs = SystemClock.elapsedRealtime() * 1000;
|
elapsedRealtimeUs = SystemClock.elapsedRealtime() * 1000;
|
||||||
@ -469,7 +468,6 @@ import java.util.ArrayList;
|
|||||||
|
|
||||||
if (sourceIndex != playbackInfo.sourceIndex) {
|
if (sourceIndex != playbackInfo.sourceIndex) {
|
||||||
playbackInfo = new PlaybackInfo(sourceIndex);
|
playbackInfo = new PlaybackInfo(sourceIndex);
|
||||||
playbackInfo.positionUs = seekPositionUs;
|
|
||||||
updatePlaybackPositions();
|
updatePlaybackPositions();
|
||||||
eventHandler.obtainMessage(MSG_SOURCE_CHANGED, playbackInfo).sendToTarget();
|
eventHandler.obtainMessage(MSG_SOURCE_CHANGED, playbackInfo).sendToTarget();
|
||||||
}
|
}
|
||||||
@ -483,7 +481,7 @@ import java.util.ArrayList;
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void resetInternalPosition(long sourcePositionUs) throws ExoPlaybackException {
|
private void resetInternalPosition(long sourcePositionUs) throws ExoPlaybackException {
|
||||||
internalPositionUs = sourceOffsetUs + sourcePositionUs;
|
internalPositionUs = timeline.playingSource.offsetUs + sourcePositionUs;
|
||||||
standaloneMediaClock.setPositionUs(internalPositionUs);
|
standaloneMediaClock.setPositionUs(internalPositionUs);
|
||||||
for (TrackRenderer renderer : enabledRenderers) {
|
for (TrackRenderer renderer : enabledRenderers) {
|
||||||
renderer.reset(internalPositionUs);
|
renderer.reset(internalPositionUs);
|
||||||
@ -575,7 +573,6 @@ import java.util.ArrayList;
|
|||||||
|
|
||||||
private int pendingSourceIndex;
|
private int pendingSourceIndex;
|
||||||
private long playingSourceEndPositionUs;
|
private long playingSourceEndPositionUs;
|
||||||
private long bufferingSourceOffsetUs;
|
|
||||||
|
|
||||||
public Timeline(TrackRenderer[] renderers) {
|
public Timeline(TrackRenderer[] renderers) {
|
||||||
this.renderers = renderers;
|
this.renderers = renderers;
|
||||||
@ -607,6 +604,7 @@ import java.util.ArrayList;
|
|||||||
public void updateSources() throws ExoPlaybackException, IOException {
|
public void updateSources() throws ExoPlaybackException, IOException {
|
||||||
// TODO[playlists]: Let sample source providers invalidate sources that are already buffering.
|
// TODO[playlists]: Let sample source providers invalidate sources that are already buffering.
|
||||||
|
|
||||||
|
// Update the buffering source.
|
||||||
int sourceCount = sampleSourceProvider.getSourceCount();
|
int sourceCount = sampleSourceProvider.getSourceCount();
|
||||||
if (bufferingSource == null
|
if (bufferingSource == null
|
||||||
|| (bufferingSource.isFullyBuffered() && bufferingSource.index
|
|| (bufferingSource.isFullyBuffered() && bufferingSource.index
|
||||||
@ -619,14 +617,12 @@ import java.util.ArrayList;
|
|||||||
if (sampleSource != null) {
|
if (sampleSource != null) {
|
||||||
Source newSource = new Source(sampleSource, sourceIndex, renderers.length);
|
Source newSource = new Source(sampleSource, sourceIndex, renderers.length);
|
||||||
if (bufferingSource != null) {
|
if (bufferingSource != null) {
|
||||||
bufferingSource.nextSource = newSource;
|
bufferingSource.setNextSource(newSource);
|
||||||
bufferingSourceOffsetUs += bufferingSource.sampleSource.getDurationUs();
|
|
||||||
}
|
}
|
||||||
bufferingSource = newSource;
|
bufferingSource = newSource;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bufferingSource != null) {
|
if (bufferingSource != null) {
|
||||||
if (!bufferingSource.prepared) {
|
if (!bufferingSource.prepared) {
|
||||||
// Continue preparation.
|
// Continue preparation.
|
||||||
@ -638,55 +634,46 @@ import java.util.ArrayList;
|
|||||||
bufferingSource.selectTracks(result.first, result.second, startPositionUs);
|
bufferingSource.selectTracks(result.first, result.second, startPositionUs);
|
||||||
if (playingSource == null) {
|
if (playingSource == null) {
|
||||||
// This is the first prepared source, so start playing it.
|
// This is the first prepared source, so start playing it.
|
||||||
setPlayingSource(bufferingSource, 0);
|
readingSource = bufferingSource;
|
||||||
|
setPlayingSource(readingSource);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bufferingSource.hasEnabledTracks) {
|
if (bufferingSource.hasEnabledTracks) {
|
||||||
long sourcePositionUs = internalPositionUs - bufferingSourceOffsetUs;
|
long sourcePositionUs = internalPositionUs - bufferingSource.offsetUs;
|
||||||
bufferingSource.sampleSource.continueBuffering(sourcePositionUs);
|
bufferingSource.sampleSource.continueBuffering(sourcePositionUs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the playing and reading sources.
|
||||||
if (playingSource == null) {
|
if (playingSource == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (playingSourceEndPositionUs == C.UNSET_TIME_US && playingSource.isFullyBuffered()) {
|
||||||
if (readingSource != playingSource) {
|
playingSourceEndPositionUs = playingSource.offsetUs
|
||||||
if (playingSourceEndPositionUs != C.UNSET_TIME_US
|
+ playingSource.sampleSource.getDurationUs();
|
||||||
&& internalPositionUs >= playingSourceEndPositionUs) {
|
}
|
||||||
playingSource.release();
|
while (playingSource.nextSource != null && playingSource.nextSource.prepared
|
||||||
setPlayingSource(readingSource, playingSourceEndPositionUs);
|
&& internalPositionUs >= playingSource.nextSource.offsetUs) {
|
||||||
playbackInfo = new PlaybackInfo(playingSource.index);
|
playingSource.release();
|
||||||
updatePlaybackPositions();
|
if (readingSource == playingSource) {
|
||||||
eventHandler.obtainMessage(MSG_SOURCE_CHANGED, playbackInfo).sendToTarget();
|
readingSource = playingSource.nextSource;
|
||||||
} else {
|
}
|
||||||
// We're reading ahead, but it's not time to update the playing source yet.
|
setPlayingSource(playingSource.nextSource);
|
||||||
return;
|
playbackInfo = new PlaybackInfo(playingSource.index);
|
||||||
}
|
updatePlaybackPositions();
|
||||||
|
eventHandler.obtainMessage(MSG_SOURCE_CHANGED, playbackInfo).sendToTarget();
|
||||||
|
}
|
||||||
|
if (readingSource == null) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check whether all enabled renderers have read to the end of their TrackStreams.
|
|
||||||
for (TrackRenderer renderer : enabledRenderers) {
|
for (TrackRenderer renderer : enabledRenderers) {
|
||||||
if (!renderer.hasReadStreamToEnd()) {
|
if (!renderer.hasReadStreamToEnd()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: Is playingSourceEndPositionUs equivalent to playbackInfo.durationUs?
|
if (readingSource.nextSource != null && readingSource.nextSource.prepared) {
|
||||||
if (playingSourceEndPositionUs == C.UNSET_TIME_US) {
|
readingSource = readingSource.nextSource;
|
||||||
playingSourceEndPositionUs = sourceOffsetUs + playingSource.sampleSource.getDurationUs();
|
|
||||||
}
|
|
||||||
if (sourceCount != SampleSourceProvider.UNKNOWN_SOURCE_COUNT
|
|
||||||
&& readingSource.index == sourceCount - 1) {
|
|
||||||
// This is the last source, so signal the renderers to read the end of the stream.
|
|
||||||
for (TrackRenderer renderer : enabledRenderers) {
|
|
||||||
renderer.setCurrentTrackStreamIsFinal();
|
|
||||||
}
|
|
||||||
readingSource = null;
|
|
||||||
playingSourceEndPositionUs = C.UNSET_TIME_US;
|
|
||||||
} else if (playingSource.nextSource != null && playingSource.nextSource.prepared) {
|
|
||||||
readingSource = playingSource.nextSource;
|
|
||||||
TrackSelectionArray newTrackSelections = readingSource.trackSelections;
|
TrackSelectionArray newTrackSelections = readingSource.trackSelections;
|
||||||
TrackGroupArray groups = readingSource.sampleSource.getTrackGroups();
|
TrackGroupArray groups = readingSource.sampleSource.getTrackGroups();
|
||||||
for (int i = 0; i < renderers.length; i++) {
|
for (int i = 0; i < renderers.length; i++) {
|
||||||
@ -701,7 +688,7 @@ import java.util.ArrayList;
|
|||||||
formats[j] = groups.get(selection.group).getFormat(selection.getTrack(j));
|
formats[j] = groups.get(selection.group).getFormat(selection.getTrack(j));
|
||||||
}
|
}
|
||||||
renderer.replaceTrackStream(formats, readingSource.trackStreams[i],
|
renderer.replaceTrackStream(formats, readingSource.trackStreams[i],
|
||||||
playingSourceEndPositionUs);
|
readingSource.offsetUs);
|
||||||
} else {
|
} else {
|
||||||
// The renderer will be disabled when transitioning to playing the next source. Send
|
// The renderer will be disabled when transitioning to playing the next source. Send
|
||||||
// end-of-stream to play out any remaining data.
|
// end-of-stream to play out any remaining data.
|
||||||
@ -709,6 +696,13 @@ import java.util.ArrayList;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (sourceCount != SampleSourceProvider.UNKNOWN_SOURCE_COUNT
|
||||||
|
&& readingSource.index == sourceCount - 1) {
|
||||||
|
readingSource = null;
|
||||||
|
// This is the last source, so signal the renderers to read the end of the stream.
|
||||||
|
for (TrackRenderer renderer : enabledRenderers) {
|
||||||
|
renderer.setCurrentTrackStreamIsFinal();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -727,15 +721,14 @@ import java.util.ArrayList;
|
|||||||
|
|
||||||
if (newPlayingSource != null) {
|
if (newPlayingSource != null) {
|
||||||
newPlayingSource.nextSource = null;
|
newPlayingSource.nextSource = null;
|
||||||
setPlayingSource(newPlayingSource, sourceOffsetUs);
|
setPlayingSource(newPlayingSource);
|
||||||
|
readingSource = playingSource;
|
||||||
bufferingSource = playingSource;
|
bufferingSource = playingSource;
|
||||||
bufferingSourceOffsetUs = sourceOffsetUs;
|
|
||||||
} else {
|
} else {
|
||||||
// TODO[REFACTOR]: We need to disable the renderers somewhere in here?
|
// TODO[REFACTOR]: We need to disable the renderers somewhere in here?
|
||||||
playingSource = null;
|
playingSource = null;
|
||||||
readingSource = null;
|
readingSource = null;
|
||||||
bufferingSource = null;
|
bufferingSource = null;
|
||||||
bufferingSourceOffsetUs = 0;
|
|
||||||
pendingSourceIndex = sourceIndex;
|
pendingSourceIndex = sourceIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -756,7 +749,8 @@ import java.util.ArrayList;
|
|||||||
for (int j = 0; j < formats.length; j++) {
|
for (int j = 0; j < formats.length; j++) {
|
||||||
formats[j] = groups.get(selection.group).getFormat(selection.getTrack(j));
|
formats[j] = groups.get(selection.group).getFormat(selection.getTrack(j));
|
||||||
}
|
}
|
||||||
renderer.replaceTrackStream(formats, playingSource.trackStreams[i], sourceOffsetUs);
|
renderer.replaceTrackStream(formats, playingSource.trackStreams[i],
|
||||||
|
playingSource.offsetUs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -772,7 +766,6 @@ import java.util.ArrayList;
|
|||||||
readingSource = playingSource;
|
readingSource = playingSource;
|
||||||
bufferingSource = playingSource;
|
bufferingSource = playingSource;
|
||||||
playingSourceEndPositionUs = C.UNSET_TIME_US;
|
playingSourceEndPositionUs = C.UNSET_TIME_US;
|
||||||
bufferingSourceOffsetUs = sourceOffsetUs;
|
|
||||||
|
|
||||||
// Update the track selection for the playing source.
|
// Update the track selection for the playing source.
|
||||||
Pair<TrackSelectionArray, Object> result =
|
Pair<TrackSelectionArray, Object> result =
|
||||||
@ -814,20 +807,14 @@ import java.util.ArrayList;
|
|||||||
bufferingSource = null;
|
bufferingSource = null;
|
||||||
playingSourceEndPositionUs = C.UNSET_TIME_US;
|
playingSourceEndPositionUs = C.UNSET_TIME_US;
|
||||||
pendingSourceIndex = 0;
|
pendingSourceIndex = 0;
|
||||||
sourceOffsetUs = 0;
|
|
||||||
bufferingSourceOffsetUs = 0;
|
|
||||||
playbackInfo = new PlaybackInfo(0);
|
playbackInfo = new PlaybackInfo(0);
|
||||||
eventHandler.obtainMessage(MSG_SOURCE_CHANGED, playbackInfo).sendToTarget();
|
eventHandler.obtainMessage(MSG_SOURCE_CHANGED, playbackInfo).sendToTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setPlayingSource(Source source, long offsetUs) throws ExoPlaybackException {
|
private void setPlayingSource(Source source) throws ExoPlaybackException {
|
||||||
sourceOffsetUs = offsetUs;
|
|
||||||
// Disable/enable renderers for the new source.
|
// Disable/enable renderers for the new source.
|
||||||
int enabledRendererCount = disableRenderers(true, source.trackSelections);
|
int enabledRendererCount = disableRenderers(true, source.trackSelections);
|
||||||
if (playingSource != source) {
|
trackSelector.onSelectionActivated(source.trackSelectionData);
|
||||||
trackSelector.onSelectionActivated(source.trackSelectionData);
|
|
||||||
}
|
|
||||||
readingSource = source;
|
|
||||||
playingSource = source;
|
playingSource = source;
|
||||||
playingSourceEndPositionUs = C.UNSET_TIME_US;
|
playingSourceEndPositionUs = C.UNSET_TIME_US;
|
||||||
enableRenderers(source.trackSelections, enabledRendererCount);
|
enableRenderers(source.trackSelections, enabledRendererCount);
|
||||||
@ -902,7 +889,7 @@ import java.util.ArrayList;
|
|||||||
}
|
}
|
||||||
// Enable the renderer.
|
// Enable the renderer.
|
||||||
renderer.enable(formats, playingSource.trackStreams[i], internalPositionUs, joining,
|
renderer.enable(formats, playingSource.trackStreams[i], internalPositionUs, joining,
|
||||||
sourceOffsetUs);
|
playingSource.offsetUs);
|
||||||
MediaClock mediaClock = renderer.getMediaClock();
|
MediaClock mediaClock = renderer.getMediaClock();
|
||||||
if (mediaClock != null) {
|
if (mediaClock != null) {
|
||||||
if (rendererMediaClock != null) {
|
if (rendererMediaClock != null) {
|
||||||
@ -936,7 +923,7 @@ import java.util.ArrayList;
|
|||||||
public boolean hasEnabledTracks;
|
public boolean hasEnabledTracks;
|
||||||
public TrackSelectionArray trackSelections;
|
public TrackSelectionArray trackSelections;
|
||||||
public Object trackSelectionData;
|
public Object trackSelectionData;
|
||||||
|
public long offsetUs;
|
||||||
public Source nextSource;
|
public Source nextSource;
|
||||||
|
|
||||||
public Source(SampleSource sampleSource, int index, int rendererCount) {
|
public Source(SampleSource sampleSource, int index, int rendererCount) {
|
||||||
@ -950,6 +937,11 @@ import java.util.ArrayList;
|
|||||||
|| sampleSource.getBufferedPositionUs() == C.END_OF_SOURCE_US);
|
|| sampleSource.getBufferedPositionUs() == C.END_OF_SOURCE_US);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setNextSource(Source nextSource) {
|
||||||
|
this.nextSource = nextSource;
|
||||||
|
nextSource.offsetUs = offsetUs + sampleSource.getDurationUs();
|
||||||
|
}
|
||||||
|
|
||||||
public boolean prepare(long startPositionUs) throws IOException {
|
public boolean prepare(long startPositionUs) throws IOException {
|
||||||
if (sampleSource.prepare(startPositionUs)) {
|
if (sampleSource.prepare(startPositionUs)) {
|
||||||
prepared = true;
|
prepared = true;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user