Fix ExoPlayerImplInternal timestamp conversions

This fixes VOD->Live transitions, with the caveat that
the Live portion still ends up further behind the live
edge than intended. This will be fixed in a following
change.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=138407066
This commit is contained in:
olly 2016-11-07 10:22:47 -08:00 committed by Oliver Woodman
parent 3c8db3b9cb
commit 89ad5e6db3

View File

@ -414,7 +414,7 @@ import java.io.IOException;
} else { } else {
rendererPositionUs = standaloneMediaClock.getPositionUs(); rendererPositionUs = standaloneMediaClock.getPositionUs();
} }
periodPositionUs = rendererPositionUs - playingPeriodHolder.rendererPositionOffsetUs; periodPositionUs = playingPeriodHolder.toPeriodTime(rendererPositionUs);
} }
playbackInfo.positionUs = periodPositionUs; playbackInfo.positionUs = periodPositionUs;
elapsedRealtimeUs = SystemClock.elapsedRealtime() * 1000; elapsedRealtimeUs = SystemClock.elapsedRealtime() * 1000;
@ -547,13 +547,6 @@ import java.io.IOException;
private long seekToPeriodPosition(int periodIndex, long periodPositionUs) private long seekToPeriodPosition(int periodIndex, long periodPositionUs)
throws ExoPlaybackException { throws ExoPlaybackException {
if (mediaSource == null) {
if (periodPositionUs != C.TIME_UNSET) {
resetRendererPosition(periodPositionUs);
}
return periodPositionUs;
}
stopRenderers(); stopRenderers();
rebuffering = false; rebuffering = false;
setState(ExoPlayer.STATE_BUFFERING); setState(ExoPlayer.STATE_BUFFERING);
@ -622,9 +615,8 @@ import java.io.IOException;
} }
private void resetRendererPosition(long periodPositionUs) throws ExoPlaybackException { private void resetRendererPosition(long periodPositionUs) throws ExoPlaybackException {
long periodOffsetUs = playingPeriodHolder == null ? 0 rendererPositionUs = playingPeriodHolder == null ? periodPositionUs
: playingPeriodHolder.rendererPositionOffsetUs; : playingPeriodHolder.toRendererTime(periodPositionUs);
rendererPositionUs = periodOffsetUs + periodPositionUs;
standaloneMediaClock.setPositionUs(rendererPositionUs); standaloneMediaClock.setPositionUs(rendererPositionUs);
for (Renderer renderer : enabledRenderers) { for (Renderer renderer : enabledRenderers) {
renderer.resetPosition(rendererPositionUs); renderer.resetPosition(rendererPositionUs);
@ -769,7 +761,7 @@ import java.io.IOException;
renderer.disable(); renderer.disable();
} else if (streamResetFlags[i]) { } else if (streamResetFlags[i]) {
// The renderer will continue to consume from its current stream, but needs to be reset. // The renderer will continue to consume from its current stream, but needs to be reset.
renderer.resetPosition(playbackInfo.positionUs); renderer.resetPosition(rendererPositionUs);
} }
} }
} }
@ -785,9 +777,11 @@ import java.io.IOException;
bufferAheadPeriodCount--; bufferAheadPeriodCount--;
} }
loadingPeriodHolder.next = null; loadingPeriodHolder.next = null;
long loadingPeriodPositionUs = Math.max(0, if (loadingPeriodHolder.prepared) {
rendererPositionUs - loadingPeriodHolder.rendererPositionOffsetUs); long loadingPeriodPositionUs = Math.max(loadingPeriodHolder.startPositionUs,
loadingPeriodHolder.updatePeriodTrackSelection(loadingPeriodPositionUs, loadControl, false); loadingPeriodHolder.toPeriodTime(rendererPositionUs));
loadingPeriodHolder.updatePeriodTrackSelection(loadingPeriodPositionUs, loadControl, false);
}
} }
maybeContinueLoading(); maybeContinueLoading();
updatePlaybackPositions(); updatePlaybackPositions();
@ -798,10 +792,9 @@ import java.io.IOException;
if (loadingPeriodHolder == null) { if (loadingPeriodHolder == null) {
return false; return false;
} }
long loadingPeriodPositionUs = rendererPositionUs long loadingPeriodBufferedPositionUs = !loadingPeriodHolder.prepared
- loadingPeriodHolder.rendererPositionOffsetUs; ? loadingPeriodHolder.startPositionUs
long loadingPeriodBufferedPositionUs = : loadingPeriodHolder.mediaPeriod.getBufferedPositionUs();
!loadingPeriodHolder.prepared ? 0 : loadingPeriodHolder.mediaPeriod.getBufferedPositionUs();
if (loadingPeriodBufferedPositionUs == C.TIME_END_OF_SOURCE) { if (loadingPeriodBufferedPositionUs == C.TIME_END_OF_SOURCE) {
if (loadingPeriodHolder.isLast) { if (loadingPeriodHolder.isLast) {
return true; return true;
@ -810,7 +803,8 @@ import java.io.IOException;
.getDurationUs(); .getDurationUs();
} }
return loadControl.shouldStartPlayback( return loadControl.shouldStartPlayback(
loadingPeriodBufferedPositionUs - loadingPeriodPositionUs, rebuffering); loadingPeriodBufferedPositionUs - loadingPeriodHolder.toPeriodTime(rendererPositionUs),
rebuffering);
} }
private void maybeThrowPeriodPrepareError() throws IOException { private void maybeThrowPeriodPrepareError() throws IOException {
@ -1084,7 +1078,10 @@ import java.io.IOException;
if (loadingPeriodHolder != null) { if (loadingPeriodHolder != null) {
loadingPeriodHolder.setNext(newPeriodHolder); loadingPeriodHolder.setNext(newPeriodHolder);
newPeriodHolder.rendererPositionOffsetUs = loadingPeriodHolder.rendererPositionOffsetUs newPeriodHolder.rendererPositionOffsetUs = loadingPeriodHolder.rendererPositionOffsetUs
+ timeline.getPeriod(loadingPeriodHolder.index, period).getDurationUs(); + timeline.getPeriod(loadingPeriodHolder.index, period).getDurationUs()
- loadingPeriodHolder.startPositionUs;
} else {
newPeriodHolder.rendererPositionOffsetUs = periodStartPositionUs;
} }
bufferAheadPeriodCount++; bufferAheadPeriodCount++;
loadingPeriodHolder = newPeriodHolder; loadingPeriodHolder = newPeriodHolder;
@ -1148,7 +1145,7 @@ import java.io.IOException;
formats[j] = newSelection.getFormat(j); formats[j] = newSelection.getFormat(j);
} }
renderer.replaceStream(formats, readingPeriodHolder.sampleStreams[i], renderer.replaceStream(formats, readingPeriodHolder.sampleStreams[i],
readingPeriodHolder.rendererPositionOffsetUs); readingPeriodHolder.getRendererOffset());
} else { } else {
// The renderer will be disabled when transitioning to playing the next period. Mark the // The renderer will be disabled when transitioning to playing the next period. Mark the
// SampleStream as final to play out any remaining data. // SampleStream as final to play out any remaining data.
@ -1168,7 +1165,6 @@ import java.io.IOException;
if (playingPeriodHolder == null) { if (playingPeriodHolder == null) {
// This is the first prepared period, so start playing it. // This is the first prepared period, so start playing it.
readingPeriodHolder = loadingPeriodHolder; readingPeriodHolder = loadingPeriodHolder;
resetRendererPosition(readingPeriodHolder.startPositionUs);
setPlayingPeriodHolder(readingPeriodHolder); setPlayingPeriodHolder(readingPeriodHolder);
if (playbackInfo.startPositionUs == C.TIME_UNSET) { if (playbackInfo.startPositionUs == C.TIME_UNSET) {
// Update the playback info when seeking to a default position. // Update the playback info when seeking to a default position.
@ -1191,9 +1187,10 @@ import java.io.IOException;
private void maybeContinueLoading() { private void maybeContinueLoading() {
long nextLoadPositionUs = loadingPeriodHolder.mediaPeriod.getNextLoadPositionUs(); long nextLoadPositionUs = loadingPeriodHolder.mediaPeriod.getNextLoadPositionUs();
if (nextLoadPositionUs != C.TIME_END_OF_SOURCE) { if (nextLoadPositionUs == C.TIME_END_OF_SOURCE) {
long loadingPeriodPositionUs = rendererPositionUs setIsLoading(false);
- loadingPeriodHolder.rendererPositionOffsetUs; } else {
long loadingPeriodPositionUs = loadingPeriodHolder.toPeriodTime(rendererPositionUs);
long bufferedDurationUs = nextLoadPositionUs - loadingPeriodPositionUs; long bufferedDurationUs = nextLoadPositionUs - loadingPeriodPositionUs;
boolean continueLoading = loadControl.shouldContinueLoading(bufferedDurationUs); boolean continueLoading = loadControl.shouldContinueLoading(bufferedDurationUs);
setIsLoading(continueLoading); setIsLoading(continueLoading);
@ -1203,8 +1200,6 @@ import java.io.IOException;
} else { } else {
loadingPeriodHolder.needsContinueLoading = true; loadingPeriodHolder.needsContinueLoading = true;
} }
} else {
setIsLoading(false);
} }
} }
@ -1216,6 +1211,12 @@ import java.io.IOException;
} }
private void setPlayingPeriodHolder(MediaPeriodHolder periodHolder) throws ExoPlaybackException { private void setPlayingPeriodHolder(MediaPeriodHolder periodHolder) throws ExoPlaybackException {
boolean isFirstPeriod = playingPeriodHolder == null;
playingPeriodHolder = periodHolder;
if (isFirstPeriod) {
resetRendererPosition(playingPeriodHolder.startPositionUs);
}
int enabledRendererCount = 0; int enabledRendererCount = 0;
boolean[] rendererWasEnabledFlags = new boolean[renderers.length]; boolean[] rendererWasEnabledFlags = new boolean[renderers.length];
for (int i = 0; i < renderers.length; i++) { for (int i = 0; i < renderers.length; i++) {
@ -1239,7 +1240,6 @@ import java.io.IOException;
} }
eventHandler.obtainMessage(MSG_TRACKS_CHANGED, periodHolder.getTrackInfo()).sendToTarget(); eventHandler.obtainMessage(MSG_TRACKS_CHANGED, periodHolder.getTrackInfo()).sendToTarget();
playingPeriodHolder = periodHolder;
enableRenderers(rendererWasEnabledFlags, enabledRendererCount); enableRenderers(rendererWasEnabledFlags, enabledRendererCount);
} }
@ -1273,7 +1273,7 @@ import java.io.IOException;
} }
// Enable the renderer. // Enable the renderer.
renderer.enable(formats, playingPeriodHolder.sampleStreams[i], rendererPositionUs, renderer.enable(formats, playingPeriodHolder.sampleStreams[i], rendererPositionUs,
joining, playingPeriodHolder.rendererPositionOffsetUs); joining, playingPeriodHolder.getRendererOffset());
MediaClock mediaClock = renderer.getMediaClock(); MediaClock mediaClock = renderer.getMediaClock();
if (mediaClock != null) { if (mediaClock != null) {
if (rendererMediaClock != null) { if (rendererMediaClock != null) {
@ -1336,6 +1336,18 @@ import java.io.IOException;
startPositionUs = positionUs; startPositionUs = positionUs;
} }
public long toRendererTime(long periodTimeUs) {
return periodTimeUs + getRendererOffset();
}
public long toPeriodTime(long rendererTimeUs) {
return rendererTimeUs - getRendererOffset();
}
public long getRendererOffset() {
return rendererPositionOffsetUs - startPositionUs;
}
public void setNext(MediaPeriodHolder next) { public void setNext(MediaPeriodHolder next) {
this.next = next; this.next = next;
} }