Enable window-period offset in tests by default.

This ensures all player interactions in tests automatically verify that
timestamps calculations are done correctly.

PiperOrigin-RevId: 297813324
This commit is contained in:
tonihei 2020-02-28 12:09:12 +00:00 committed by Oliver Woodman
parent 28cefe12c5
commit 697165ce56
5 changed files with 46 additions and 11 deletions

View File

@ -39,6 +39,7 @@ import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.Player; import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.Timeline.Period;
import com.google.android.exoplayer2.source.ads.AdPlaybackState; import com.google.android.exoplayer2.source.ads.AdPlaybackState;
import com.google.android.exoplayer2.source.ads.AdsLoader; import com.google.android.exoplayer2.source.ads.AdsLoader;
import com.google.android.exoplayer2.source.ads.AdsMediaSource.AdLoadException; import com.google.android.exoplayer2.source.ads.AdsMediaSource.AdLoadException;
@ -67,6 +68,8 @@ public class ImaAdsLoaderTest {
new FakeTimeline( new FakeTimeline(
new TimelineWindowDefinition( new TimelineWindowDefinition(
/* isSeekable= */ true, /* isDynamic= */ false, CONTENT_DURATION_US)); /* isSeekable= */ true, /* isDynamic= */ false, CONTENT_DURATION_US));
private static final long CONTENT_PERIOD_DURATION_US =
CONTENT_TIMELINE.getPeriod(/* periodIndex= */ 0, new Period()).durationUs;
private static final Uri TEST_URI = Uri.EMPTY; private static final Uri TEST_URI = Uri.EMPTY;
private static final long TEST_AD_DURATION_US = 5 * C.MICROS_PER_SECOND; private static final long TEST_AD_DURATION_US = 5 * C.MICROS_PER_SECOND;
private static final long[][] PREROLL_ADS_DURATIONS_US = new long[][] {{TEST_AD_DURATION_US}}; private static final long[][] PREROLL_ADS_DURATIONS_US = new long[][] {{TEST_AD_DURATION_US}};
@ -147,7 +150,7 @@ public class ImaAdsLoaderTest {
.isEqualTo( .isEqualTo(
new AdPlaybackState(/* adGroupTimesUs...= */ 0) new AdPlaybackState(/* adGroupTimesUs...= */ 0)
.withAdDurationsUs(PREROLL_ADS_DURATIONS_US) .withAdDurationsUs(PREROLL_ADS_DURATIONS_US)
.withContentDurationUs(CONTENT_DURATION_US)); .withContentDurationUs(CONTENT_PERIOD_DURATION_US));
} }
@Test @Test
@ -216,7 +219,7 @@ public class ImaAdsLoaderTest {
assertThat(adsLoaderListener.adPlaybackState) assertThat(adsLoaderListener.adPlaybackState)
.isEqualTo( .isEqualTo(
new AdPlaybackState(/* adGroupTimesUs...= */ 0) new AdPlaybackState(/* adGroupTimesUs...= */ 0)
.withContentDurationUs(CONTENT_DURATION_US) .withContentDurationUs(CONTENT_PERIOD_DURATION_US)
.withAdCount(/* adGroupIndex= */ 0, /* adCount= */ 1) .withAdCount(/* adGroupIndex= */ 0, /* adCount= */ 1)
.withAdUri(/* adGroupIndex= */ 0, /* adIndexInAdGroup= */ 0, /* uri= */ TEST_URI) .withAdUri(/* adGroupIndex= */ 0, /* adIndexInAdGroup= */ 0, /* uri= */ TEST_URI)
.withAdDurationsUs(PREROLL_ADS_DURATIONS_US) .withAdDurationsUs(PREROLL_ADS_DURATIONS_US)

View File

@ -459,7 +459,9 @@ public final class ExoPlayerTest {
public void adGroupWithLoadErrorIsSkipped() throws Exception { public void adGroupWithLoadErrorIsSkipped() throws Exception {
AdPlaybackState initialAdPlaybackState = AdPlaybackState initialAdPlaybackState =
FakeTimeline.createAdPlaybackState( FakeTimeline.createAdPlaybackState(
/* adsPerAdGroup= */ 1, /* adGroupTimesUs=... */ 5 * C.MICROS_PER_SECOND); /* adsPerAdGroup= */ 1, /* adGroupTimesUs=... */
TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US
+ 5 * C.MICROS_PER_SECOND);
Timeline fakeTimeline = Timeline fakeTimeline =
new FakeTimeline( new FakeTimeline(
new TimelineWindowDefinition( new TimelineWindowDefinition(
@ -702,7 +704,8 @@ public final class ExoPlayerTest {
EventDispatcher eventDispatcher, EventDispatcher eventDispatcher,
@Nullable TransferListener transferListener) { @Nullable TransferListener transferListener) {
FakeMediaPeriod mediaPeriod = new FakeMediaPeriod(trackGroupArray, eventDispatcher); FakeMediaPeriod mediaPeriod = new FakeMediaPeriod(trackGroupArray, eventDispatcher);
mediaPeriod.setDiscontinuityPositionUs(0); mediaPeriod.setDiscontinuityPositionUs(
TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US);
return mediaPeriod; return mediaPeriod;
} }
}; };
@ -3064,6 +3067,7 @@ public final class ExoPlayerTest {
/* isPlaceholder= */ false, /* isPlaceholder= */ false,
/* durationUs= */ 10_000_000, /* durationUs= */ 10_000_000,
/* defaultPositionUs= */ 5_000_000, /* defaultPositionUs= */ 5_000_000,
TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US,
adPlaybackState)); adPlaybackState));
FakeMediaSource fakeMediaSource = new FakeMediaSource(/* timeline= */ null); FakeMediaSource fakeMediaSource = new FakeMediaSource(/* timeline= */ null);
AtomicReference<Player> playerReference = new AtomicReference<>(); AtomicReference<Player> playerReference = new AtomicReference<>();

View File

@ -231,7 +231,8 @@ public final class MediaPeriodQueueTest {
/* startPositionUs= */ 0, /* startPositionUs= */ 0,
/* requestedContentPositionUs= */ C.TIME_UNSET, /* requestedContentPositionUs= */ C.TIME_UNSET,
/* endPositionUs= */ C.TIME_UNSET, /* endPositionUs= */ C.TIME_UNSET,
/* durationUs= */ CONTENT_DURATION_US, /* durationUs= */ CONTENT_DURATION_US
+ TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US,
/* isLastInPeriod= */ true, /* isLastInPeriod= */ true,
/* isLastInWindow= */ false, /* isLastInWindow= */ false,
/* nextAdGroupIndex= */ C.INDEX_UNSET); /* nextAdGroupIndex= */ C.INDEX_UNSET);

View File

@ -762,7 +762,8 @@ public final class AnalyticsCollectorTest {
FakeTimeline.createAdPlaybackState( FakeTimeline.createAdPlaybackState(
/* adsPerAdGroup= */ 1, /* adGroupTimesUs...= */ /* adsPerAdGroup= */ 1, /* adGroupTimesUs...= */
0, 0,
5 * C.MICROS_PER_SECOND, TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US
+ 5 * C.MICROS_PER_SECOND,
C.TIME_END_OF_SOURCE)); C.TIME_END_OF_SOURCE));
AtomicInteger playedAdCount = new AtomicInteger(0); AtomicInteger playedAdCount = new AtomicInteger(0);
Timeline adTimeline = Timeline adTimeline =
@ -997,7 +998,9 @@ public final class AnalyticsCollectorTest {
/* isDynamic= */ false, /* isDynamic= */ false,
10 * C.MICROS_PER_SECOND, 10 * C.MICROS_PER_SECOND,
FakeTimeline.createAdPlaybackState( FakeTimeline.createAdPlaybackState(
/* adsPerAdGroup= */ 1, /* adGroupTimesUs...= */ 5 * C.MICROS_PER_SECOND))); /* adsPerAdGroup= */ 1, /* adGroupTimesUs...= */
TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US
+ 5 * C.MICROS_PER_SECOND)));
FakeMediaSource fakeMediaSource = FakeMediaSource fakeMediaSource =
new FakeMediaSource(adTimeline, ExoPlayerTestRunner.Builder.VIDEO_FORMAT); new FakeMediaSource(adTimeline, ExoPlayerTestRunner.Builder.VIDEO_FORMAT);
ActionSchedule actionSchedule = ActionSchedule actionSchedule =

View File

@ -32,9 +32,13 @@ public final class FakeTimeline extends Timeline {
*/ */
public static final class TimelineWindowDefinition { public static final class TimelineWindowDefinition {
/** Default test window duration in microseconds. */ /** Default window duration in microseconds. */
public static final long DEFAULT_WINDOW_DURATION_US = 10 * C.MICROS_PER_SECOND; public static final long DEFAULT_WINDOW_DURATION_US = 10 * C.MICROS_PER_SECOND;
/** Default offset of a window in its first period in microseconds. */
public static final long DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US =
10_000 * C.MICROS_PER_SECOND;
public final int periodCount; public final int periodCount;
public final Object id; public final Object id;
public final boolean isSeekable; public final boolean isSeekable;
@ -43,6 +47,7 @@ public final class FakeTimeline extends Timeline {
public final boolean isPlaceholder; public final boolean isPlaceholder;
public final long durationUs; public final long durationUs;
public final long defaultPositionUs; public final long defaultPositionUs;
public final long windowOffsetInFirstPeriodUs;
public final AdPlaybackState adPlaybackState; public final AdPlaybackState adPlaybackState;
/** /**
@ -61,6 +66,7 @@ public final class FakeTimeline extends Timeline {
/* isPlaceholder= */ true, /* isPlaceholder= */ true,
/* durationUs= */ C.TIME_UNSET, /* durationUs= */ C.TIME_UNSET,
/* defaultPositionUs= */ 0, /* defaultPositionUs= */ 0,
/* windowOffsetInFirstPeriodUs= */ 0,
AdPlaybackState.NONE); AdPlaybackState.NONE);
} }
@ -129,6 +135,7 @@ public final class FakeTimeline extends Timeline {
/* isPlaceholder= */ false, /* isPlaceholder= */ false,
durationUs, durationUs,
/* defaultPositionUs= */ 0, /* defaultPositionUs= */ 0,
DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US,
adPlaybackState); adPlaybackState);
} }
@ -144,6 +151,8 @@ public final class FakeTimeline extends Timeline {
* @param isPlaceholder Whether the window is a placeholder. * @param isPlaceholder Whether the window is a placeholder.
* @param durationUs The duration of the window in microseconds. * @param durationUs The duration of the window in microseconds.
* @param defaultPositionUs The default position of the window in microseconds. * @param defaultPositionUs The default position of the window in microseconds.
* @param windowOffsetInFirstPeriodUs The offset of the window in the first period, in
* microseconds.
* @param adPlaybackState The ad playback state. * @param adPlaybackState The ad playback state.
*/ */
public TimelineWindowDefinition( public TimelineWindowDefinition(
@ -155,7 +164,9 @@ public final class FakeTimeline extends Timeline {
boolean isPlaceholder, boolean isPlaceholder,
long durationUs, long durationUs,
long defaultPositionUs, long defaultPositionUs,
long windowOffsetInFirstPeriodUs,
AdPlaybackState adPlaybackState) { AdPlaybackState adPlaybackState) {
Assertions.checkArgument(durationUs != C.TIME_UNSET || periodCount == 1);
this.periodCount = periodCount; this.periodCount = periodCount;
this.id = id; this.id = id;
this.isSeekable = isSeekable; this.isSeekable = isSeekable;
@ -164,6 +175,7 @@ public final class FakeTimeline extends Timeline {
this.isPlaceholder = isPlaceholder; this.isPlaceholder = isPlaceholder;
this.durationUs = durationUs; this.durationUs = durationUs;
this.defaultPositionUs = defaultPositionUs; this.defaultPositionUs = defaultPositionUs;
this.windowOffsetInFirstPeriodUs = windowOffsetInFirstPeriodUs;
this.adPlaybackState = adPlaybackState; this.adPlaybackState = adPlaybackState;
} }
} }
@ -262,7 +274,7 @@ public final class FakeTimeline extends Timeline {
windowDefinition.durationUs, windowDefinition.durationUs,
periodOffsets[windowIndex], periodOffsets[windowIndex],
periodOffsets[windowIndex + 1] - 1, periodOffsets[windowIndex + 1] - 1,
/* positionInFirstPeriodUs= */ 0); windowDefinition.windowOffsetInFirstPeriodUs);
window.isPlaceholder = windowDefinition.isPlaceholder; window.isPlaceholder = windowDefinition.isPlaceholder;
return window; return window;
} }
@ -279,8 +291,20 @@ public final class FakeTimeline extends Timeline {
TimelineWindowDefinition windowDefinition = windowDefinitions[windowIndex]; TimelineWindowDefinition windowDefinition = windowDefinitions[windowIndex];
Object id = setIds ? windowPeriodIndex : null; Object id = setIds ? windowPeriodIndex : null;
Object uid = setIds ? Pair.create(windowDefinition.id, windowPeriodIndex) : null; Object uid = setIds ? Pair.create(windowDefinition.id, windowPeriodIndex) : null;
long periodDurationUs = windowDefinition.durationUs / windowDefinition.periodCount; // Arbitrarily set period duration by distributing window duration equally among all periods.
long positionInWindowUs = periodDurationUs * windowPeriodIndex; long periodDurationUs =
windowDefinition.durationUs == C.TIME_UNSET
? C.TIME_UNSET
: windowDefinition.durationUs / windowDefinition.periodCount;
long positionInWindowUs;
if (windowPeriodIndex == 0) {
if (windowDefinition.durationUs != C.TIME_UNSET) {
periodDurationUs += windowDefinition.windowOffsetInFirstPeriodUs;
}
positionInWindowUs = -windowDefinition.windowOffsetInFirstPeriodUs;
} else {
positionInWindowUs = periodDurationUs * windowPeriodIndex;
}
return period.set( return period.set(
id, id,
uid, uid,