Suppress discontinuities that don't change the position

This is mostly useful for suppressing the initial position
discontinuity reported by ClippingMediaPeriod.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=176758972
This commit is contained in:
olly 2017-11-23 04:26:05 -08:00 committed by Oliver Woodman
parent ba5f35995f
commit 2086c129fc
3 changed files with 59 additions and 27 deletions

View File

@ -343,12 +343,9 @@ public final class ExoPlayerTest extends TestCase {
@Override
protected FakeMediaPeriod createFakeMediaPeriod(MediaPeriodId id,
TrackGroupArray trackGroupArray, Allocator allocator) {
return new FakeMediaPeriod(trackGroupArray) {
@Override
public long seekToUs(long positionUs) {
return positionUs + 10; // Adjusts the requested seek position.
}
};
FakeMediaPeriod mediaPeriod = new FakeMediaPeriod(trackGroupArray);
mediaPeriod.setSeekToUsOffset(10);
return mediaPeriod;
}
};
ActionSchedule actionSchedule = new ActionSchedule.Builder("testSeekDiscontinuityAdjust")
@ -359,32 +356,39 @@ public final class ExoPlayerTest extends TestCase {
Player.DISCONTINUITY_REASON_SEEK_ADJUSTMENT);
}
public void testInternalDiscontinuity() throws Exception {
public void testInternalDiscontinuityAtNewPosition() throws Exception {
FakeTimeline timeline = new FakeTimeline(1);
FakeMediaSource mediaSource = new FakeMediaSource(timeline, null, Builder.VIDEO_FORMAT) {
@Override
protected FakeMediaPeriod createFakeMediaPeriod(MediaPeriodId id,
TrackGroupArray trackGroupArray, Allocator allocator) {
return new FakeMediaPeriod(trackGroupArray) {
boolean discontinuityRead;
@Override
public long readDiscontinuity() {
if (!discontinuityRead) {
discontinuityRead = true;
return 10; // Return a discontinuity.
}
return C.TIME_UNSET;
}
};
FakeMediaPeriod mediaPeriod = new FakeMediaPeriod(trackGroupArray);
mediaPeriod.setDiscontinuityPositionUs(10);
return mediaPeriod;
}
};
ActionSchedule actionSchedule = new ActionSchedule.Builder("testInternalDiscontinuity")
.waitForPlaybackState(Player.STATE_READY).build();
ExoPlayerTestRunner testRunner = new ExoPlayerTestRunner.Builder().setMediaSource(mediaSource)
.setActionSchedule(actionSchedule).build().start().blockUntilEnded(TIMEOUT_MS);
.build().start().blockUntilEnded(TIMEOUT_MS);
testRunner.assertPositionDiscontinuityReasonsEqual(Player.DISCONTINUITY_REASON_INTERNAL);
}
public void testInternalDiscontinuityAtInitialPosition() throws Exception {
FakeTimeline timeline = new FakeTimeline(1);
FakeMediaSource mediaSource = new FakeMediaSource(timeline, null, Builder.VIDEO_FORMAT) {
@Override
protected FakeMediaPeriod createFakeMediaPeriod(MediaPeriodId id,
TrackGroupArray trackGroupArray, Allocator allocator) {
FakeMediaPeriod mediaPeriod = new FakeMediaPeriod(trackGroupArray);
mediaPeriod.setDiscontinuityPositionUs(0);
return mediaPeriod;
}
};
ExoPlayerTestRunner testRunner = new ExoPlayerTestRunner.Builder().setMediaSource(mediaSource)
.build().start().blockUntilEnded(TIMEOUT_MS);
// If the position is unchanged we do not expect the discontinuity to be reported externally.
testRunner.assertNoPositionDiscontinuities();
}
public void testAllActivatedTrackSelectionAreReleasedForSinglePeriod() throws Exception {
Timeline timeline = new FakeTimeline(/* windowCount= */ 1);
MediaSource mediaSource =

View File

@ -509,10 +509,14 @@ import java.io.IOException;
long periodPositionUs = playingPeriodHolder.mediaPeriod.readDiscontinuity();
if (periodPositionUs != C.TIME_UNSET) {
resetRendererPosition(periodPositionUs);
playbackInfo = playbackInfo.fromNewPosition(playbackInfo.periodId, periodPositionUs,
playbackInfo.contentPositionUs);
eventHandler.obtainMessage(MSG_POSITION_DISCONTINUITY, Player.DISCONTINUITY_REASON_INTERNAL,
0, playbackInfo).sendToTarget();
// A MediaPeriod may report a discontinuity at the current playback position to ensure the
// renderers are flushed. Only report the discontinuity externally if the position changed.
if (periodPositionUs != playbackInfo.positionUs) {
playbackInfo = playbackInfo.fromNewPosition(playbackInfo.periodId, periodPositionUs,
playbackInfo.contentPositionUs);
eventHandler.obtainMessage(MSG_POSITION_DISCONTINUITY, Player.DISCONTINUITY_REASON_INTERNAL,
0, playbackInfo).sendToTarget();
}
} else {
rendererPositionUs = mediaClock.syncAndGetPositionUs();
periodPositionUs = playingPeriodHolder.toPeriodTime(rendererPositionUs);

View File

@ -33,9 +33,31 @@ public class FakeMediaPeriod implements MediaPeriod {
private final TrackGroupArray trackGroupArray;
private boolean preparedPeriod;
private long seekOffsetUs;
private long discontinuityPositionUs;
public FakeMediaPeriod(TrackGroupArray trackGroupArray) {
this.trackGroupArray = trackGroupArray;
discontinuityPositionUs = C.TIME_UNSET;
}
/**
* Sets a discontinuity position to be returned from the next call to
* {@link #readDiscontinuity()}.
*
* @param discontinuityPositionUs The position to be returned, in microseconds.
*/
public void setDiscontinuityPositionUs(long discontinuityPositionUs) {
this.discontinuityPositionUs = discontinuityPositionUs;
}
/**
* Sets an offset to be applied to positions returned by {@link #seekToUs(long)}.
*
* @param seekOffsetUs The offset to be applied, in microseconds.
*/
public void setSeekToUsOffset(long seekOffsetUs) {
this.seekOffsetUs = seekOffsetUs;
}
public void release() {
@ -92,7 +114,9 @@ public class FakeMediaPeriod implements MediaPeriod {
@Override
public long readDiscontinuity() {
Assert.assertTrue(preparedPeriod);
return C.TIME_UNSET;
long positionDiscontinuityUs = this.discontinuityPositionUs;
this.discontinuityPositionUs = C.TIME_UNSET;
return positionDiscontinuityUs;
}
@Override
@ -104,7 +128,7 @@ public class FakeMediaPeriod implements MediaPeriod {
@Override
public long seekToUs(long positionUs) {
Assert.assertTrue(preparedPeriod);
return positionUs;
return positionUs + seekOffsetUs;
}
@Override