diff --git a/library/core/src/androidTest/java/com/google/android/exoplayer2/TimelineTest.java b/library/core/src/androidTest/java/com/google/android/exoplayer2/TimelineTest.java index bf6ee31165..d69f40283f 100644 --- a/library/core/src/androidTest/java/com/google/android/exoplayer2/TimelineTest.java +++ b/library/core/src/androidTest/java/com/google/android/exoplayer2/TimelineTest.java @@ -15,8 +15,9 @@ */ package com.google.android.exoplayer2; +import com.google.android.exoplayer2.testutil.FakeTimeline; +import com.google.android.exoplayer2.testutil.FakeTimeline.TimelineWindowDefinition; import com.google.android.exoplayer2.testutil.TimelineAsserts; -import com.google.android.exoplayer2.testutil.TimelineAsserts.FakeTimeline; import junit.framework.TestCase; /** @@ -29,7 +30,7 @@ public class TimelineTest extends TestCase { } public void testSinglePeriodTimeline() { - Timeline timeline = new FakeTimeline(1, 111); + Timeline timeline = new FakeTimeline(new TimelineWindowDefinition(1, 111)); TimelineAsserts.assertWindowIds(timeline, 111); TimelineAsserts.assertPeriodCounts(timeline, 1); TimelineAsserts.assertPreviousWindowIndices(timeline, ExoPlayer.REPEAT_MODE_OFF, C.INDEX_UNSET); @@ -41,7 +42,7 @@ public class TimelineTest extends TestCase { } public void testMultiPeriodTimeline() { - Timeline timeline = new FakeTimeline(5, 111); + Timeline timeline = new FakeTimeline(new TimelineWindowDefinition(5, 111)); TimelineAsserts.assertWindowIds(timeline, 111); TimelineAsserts.assertPeriodCounts(timeline, 5); TimelineAsserts.assertPreviousWindowIndices(timeline, ExoPlayer.REPEAT_MODE_OFF, C.INDEX_UNSET); diff --git a/library/core/src/androidTest/java/com/google/android/exoplayer2/source/ClippingMediaSourceTest.java b/library/core/src/androidTest/java/com/google/android/exoplayer2/source/ClippingMediaSourceTest.java index a7b37e2e23..f14ee088bc 100644 --- a/library/core/src/androidTest/java/com/google/android/exoplayer2/source/ClippingMediaSourceTest.java +++ b/library/core/src/androidTest/java/com/google/android/exoplayer2/source/ClippingMediaSourceTest.java @@ -22,8 +22,9 @@ import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.Timeline.Period; import com.google.android.exoplayer2.Timeline.Window; import com.google.android.exoplayer2.testutil.FakeMediaSource; +import com.google.android.exoplayer2.testutil.FakeTimeline; +import com.google.android.exoplayer2.testutil.FakeTimeline.TimelineWindowDefinition; import com.google.android.exoplayer2.testutil.TimelineAsserts; -import com.google.android.exoplayer2.testutil.TimelineAsserts.FakeTimeline; /** * Unit tests for {@link ClippingMediaSource}. @@ -101,7 +102,8 @@ public final class ClippingMediaSourceTest extends InstrumentationTestCase { } public void testWindowAndPeriodIndices() { - Timeline timeline = new FakeTimeline(1, 111); + Timeline timeline = new FakeTimeline( + new TimelineWindowDefinition(1, 111, true, false, TEST_PERIOD_DURATION_US)); Timeline clippedTimeline = getClippedTimeline(timeline, TEST_CLIP_AMOUNT_US, TEST_PERIOD_DURATION_US - TEST_CLIP_AMOUNT_US); TimelineAsserts.assertWindowIds(clippedTimeline, 111); diff --git a/library/core/src/androidTest/java/com/google/android/exoplayer2/source/ConcatenatingMediaSourceTest.java b/library/core/src/androidTest/java/com/google/android/exoplayer2/source/ConcatenatingMediaSourceTest.java index 40551aa38f..07a9324c52 100644 --- a/library/core/src/androidTest/java/com/google/android/exoplayer2/source/ConcatenatingMediaSourceTest.java +++ b/library/core/src/androidTest/java/com/google/android/exoplayer2/source/ConcatenatingMediaSourceTest.java @@ -19,8 +19,9 @@ import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.testutil.FakeMediaSource; +import com.google.android.exoplayer2.testutil.FakeTimeline; +import com.google.android.exoplayer2.testutil.FakeTimeline.TimelineWindowDefinition; import com.google.android.exoplayer2.testutil.TimelineAsserts; -import com.google.android.exoplayer2.testutil.TimelineAsserts.FakeTimeline; import junit.framework.TestCase; /** @@ -29,7 +30,7 @@ import junit.framework.TestCase; public final class ConcatenatingMediaSourceTest extends TestCase { public void testSingleMediaSource() { - Timeline timeline = getConcatenatedTimeline(false, new FakeTimeline(3, 111)); + Timeline timeline = getConcatenatedTimeline(false, createFakeTimeline(3, 111)); TimelineAsserts.assertWindowIds(timeline, 111); TimelineAsserts.assertPeriodCounts(timeline, 3); TimelineAsserts.assertPreviousWindowIndices(timeline, ExoPlayer.REPEAT_MODE_OFF, C.INDEX_UNSET); @@ -39,7 +40,7 @@ public final class ConcatenatingMediaSourceTest extends TestCase { TimelineAsserts.assertNextWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ONE, 0); TimelineAsserts.assertNextWindowIndices(timeline, ExoPlayer.REPEAT_MODE_ALL, 0); - timeline = getConcatenatedTimeline(true, new FakeTimeline(3, 111)); + timeline = getConcatenatedTimeline(true, createFakeTimeline(3, 111)); TimelineAsserts.assertWindowIds(timeline, 111); TimelineAsserts.assertPeriodCounts(timeline, 3); TimelineAsserts.assertPreviousWindowIndices(timeline, ExoPlayer.REPEAT_MODE_OFF, C.INDEX_UNSET); @@ -51,8 +52,8 @@ public final class ConcatenatingMediaSourceTest extends TestCase { } public void testMultipleMediaSources() { - Timeline[] timelines = { new FakeTimeline(3, 111), new FakeTimeline(1, 222), - new FakeTimeline(3, 333) }; + Timeline[] timelines = { createFakeTimeline(3, 111), createFakeTimeline(1, 222), + createFakeTimeline(3, 333) }; Timeline timeline = getConcatenatedTimeline(false, timelines); TimelineAsserts.assertWindowIds(timeline, 111, 222, 333); TimelineAsserts.assertPeriodCounts(timeline, 3, 1, 3); @@ -80,8 +81,8 @@ public final class ConcatenatingMediaSourceTest extends TestCase { public void testNestedMediaSources() { Timeline timeline = getConcatenatedTimeline(false, - getConcatenatedTimeline(false, new FakeTimeline(1, 111), new FakeTimeline(1, 222)), - getConcatenatedTimeline(true, new FakeTimeline(1, 333), new FakeTimeline(1, 444))); + getConcatenatedTimeline(false, createFakeTimeline(1, 111), createFakeTimeline(1, 222)), + getConcatenatedTimeline(true, createFakeTimeline(1, 333), createFakeTimeline(1, 444))); TimelineAsserts.assertWindowIds(timeline, 111, 222, 333, 444); TimelineAsserts.assertPeriodCounts(timeline, 1, 1, 1, 1); TimelineAsserts.assertPreviousWindowIndices(timeline, ExoPlayer.REPEAT_MODE_OFF, @@ -108,5 +109,8 @@ public final class ConcatenatingMediaSourceTest extends TestCase { new ConcatenatingMediaSource(isRepeatOneAtomic, mediaSources)); } + private static FakeTimeline createFakeTimeline(int periodCount, int windowId) { + return new FakeTimeline(new TimelineWindowDefinition(periodCount, windowId)); + } } diff --git a/library/core/src/androidTest/java/com/google/android/exoplayer2/source/DynamicConcatenatingMediaSourceTest.java b/library/core/src/androidTest/java/com/google/android/exoplayer2/source/DynamicConcatenatingMediaSourceTest.java index 982d37c3a1..520d99892a 100644 --- a/library/core/src/androidTest/java/com/google/android/exoplayer2/source/DynamicConcatenatingMediaSourceTest.java +++ b/library/core/src/androidTest/java/com/google/android/exoplayer2/source/DynamicConcatenatingMediaSourceTest.java @@ -26,8 +26,9 @@ import com.google.android.exoplayer2.PlaybackParameters; import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.source.MediaSource.Listener; import com.google.android.exoplayer2.testutil.FakeMediaSource; +import com.google.android.exoplayer2.testutil.FakeTimeline; +import com.google.android.exoplayer2.testutil.FakeTimeline.TimelineWindowDefinition; import com.google.android.exoplayer2.testutil.TimelineAsserts; -import com.google.android.exoplayer2.testutil.TimelineAsserts.FakeTimeline; import com.google.android.exoplayer2.trackselection.TrackSelectionArray; import com.google.android.exoplayer2.upstream.Allocator; import java.io.IOException; @@ -175,7 +176,7 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase { TimelineAsserts.assertWindowIds(timeline, 111, null); TimelineAsserts.assertWindowIsDynamic(timeline, false, true); - lazySources[1].triggerTimelineUpdate(new FakeTimeline(9, 999)); + lazySources[1].triggerTimelineUpdate(createFakeTimeline(8)); waitForTimelineUpdate(); TimelineAsserts.assertPeriodCounts(timeline, 1, 9); TimelineAsserts.assertWindowIds(timeline, 111, 999); @@ -194,7 +195,7 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase { TimelineAsserts.assertWindowIds(timeline, null, 111, 222, 999); TimelineAsserts.assertWindowIsDynamic(timeline, true, false, false, false); - lazySources[3].triggerTimelineUpdate(new FakeTimeline(8, 888)); + lazySources[3].triggerTimelineUpdate(createFakeTimeline(7)); waitForTimelineUpdate(); TimelineAsserts.assertPeriodCounts(timeline, 8, 1, 2, 9); TimelineAsserts.assertWindowIds(timeline, 888, 111, 222, 999); @@ -207,7 +208,7 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase { public void testIllegalArguments() { DynamicConcatenatingMediaSource mediaSource = new DynamicConcatenatingMediaSource(); - MediaSource validSource = new FakeMediaSource(new FakeTimeline(1, 1), null); + MediaSource validSource = new FakeMediaSource(createFakeTimeline(1), null); // Null sources. try { @@ -235,9 +236,7 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase { } mediaSources = new MediaSource[] { - new FakeMediaSource(new FakeTimeline(1, 1), null), - validSource - }; + new FakeMediaSource(createFakeTimeline(2), null), validSource }; try { mediaSource.addMediaSources(Arrays.asList(mediaSources)); fail("Duplicate mediaSource not allowed."); @@ -270,14 +269,18 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase { timelineUpdated = false; } - private FakeMediaSource[] createMediaSources(int count) { + private static FakeMediaSource[] createMediaSources(int count) { FakeMediaSource[] sources = new FakeMediaSource[count]; for (int i = 0; i < count; i++) { - sources[i] = new FakeMediaSource(new FakeTimeline(i + 1, (i + 1) * 111), null); + sources[i] = new FakeMediaSource(createFakeTimeline(i), null); } return sources; } + private static FakeTimeline createFakeTimeline(int index) { + return new FakeTimeline(new TimelineWindowDefinition(index + 1, (index + 1) * 111)); + } + private static class LazyMediaSource implements MediaSource { private Listener listener; diff --git a/library/core/src/androidTest/java/com/google/android/exoplayer2/source/LoopingMediaSourceTest.java b/library/core/src/androidTest/java/com/google/android/exoplayer2/source/LoopingMediaSourceTest.java index 6157487005..5c1898ac7d 100644 --- a/library/core/src/androidTest/java/com/google/android/exoplayer2/source/LoopingMediaSourceTest.java +++ b/library/core/src/androidTest/java/com/google/android/exoplayer2/source/LoopingMediaSourceTest.java @@ -19,8 +19,9 @@ import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.testutil.FakeMediaSource; +import com.google.android.exoplayer2.testutil.FakeTimeline; +import com.google.android.exoplayer2.testutil.FakeTimeline.TimelineWindowDefinition; import com.google.android.exoplayer2.testutil.TimelineAsserts; -import com.google.android.exoplayer2.testutil.TimelineAsserts.FakeTimeline; import junit.framework.TestCase; /** @@ -31,11 +32,9 @@ public class LoopingMediaSourceTest extends TestCase { private final Timeline multiWindowTimeline; public LoopingMediaSourceTest() { - multiWindowTimeline = TimelineAsserts.extractTimelineFromMediaSource( - new ConcatenatingMediaSource( - new FakeMediaSource(new FakeTimeline(1, 111), null), - new FakeMediaSource(new FakeTimeline(1, 222), null), - new FakeMediaSource(new FakeTimeline(1, 333), null))); + multiWindowTimeline = TimelineAsserts.extractTimelineFromMediaSource(new FakeMediaSource( + new FakeTimeline(new TimelineWindowDefinition(1, 111), + new TimelineWindowDefinition(1, 222), new TimelineWindowDefinition(1, 333)), null)); } public void testSingleLoop() { diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeTimeline.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeTimeline.java index 0b18b00adc..040782264b 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeTimeline.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeTimeline.java @@ -17,6 +17,7 @@ package com.google.android.exoplayer2.testutil; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.Timeline; +import com.google.android.exoplayer2.util.Util; /** * Fake {@link Timeline} which can be setup to return custom {@link TimelineWindowDefinition}s. @@ -28,11 +29,26 @@ public final class FakeTimeline extends Timeline { */ public static final class TimelineWindowDefinition { + private static final int WINDOW_DURATION_US = 100000; + + public final int periodCount; + public final Object id; public final boolean isSeekable; public final boolean isDynamic; public final long durationUs; + public TimelineWindowDefinition(int periodCount, Object id) { + this(periodCount, id, true, false, WINDOW_DURATION_US); + } + public TimelineWindowDefinition(boolean isSeekable, boolean isDynamic, long durationUs) { + this(1, 0, isSeekable, isDynamic, durationUs); + } + + public TimelineWindowDefinition(int periodCount, Object id, boolean isSeekable, + boolean isDynamic, long durationUs) { + this.periodCount = periodCount; + this.id = id; this.isSeekable = isSeekable; this.isDynamic = isDynamic; this.durationUs = durationUs; @@ -41,9 +57,15 @@ public final class FakeTimeline extends Timeline { } private final TimelineWindowDefinition[] windowDefinitions; + private final int[] periodOffsets; public FakeTimeline(TimelineWindowDefinition... windowDefinitions) { this.windowDefinitions = windowDefinitions; + periodOffsets = new int[windowDefinitions.length + 1]; + periodOffsets[0] = 0; + for (int i = 0; i < windowDefinitions.length; i++) { + periodOffsets[i + 1] = periodOffsets[i] + windowDefinitions[i].periodCount; + } } @Override @@ -55,21 +77,26 @@ public final class FakeTimeline extends Timeline { public Window getWindow(int windowIndex, Window window, boolean setIds, long defaultPositionProjectionUs) { TimelineWindowDefinition windowDefinition = windowDefinitions[windowIndex]; - Object id = setIds ? windowIndex : null; + Object id = setIds ? windowDefinition.id : null; return window.set(id, C.TIME_UNSET, C.TIME_UNSET, windowDefinition.isSeekable, - windowDefinition.isDynamic, 0, windowDefinition.durationUs, windowIndex, windowIndex, 0); + windowDefinition.isDynamic, 0, windowDefinition.durationUs, periodOffsets[windowIndex], + periodOffsets[windowIndex + 1] - 1, 0); } @Override public int getPeriodCount() { - return windowDefinitions.length; + return periodOffsets[periodOffsets.length - 1]; } @Override public Period getPeriod(int periodIndex, Period period, boolean setIds) { - TimelineWindowDefinition windowDefinition = windowDefinitions[periodIndex]; - Object id = setIds ? periodIndex : null; - return period.set(id, id, periodIndex, windowDefinition.durationUs, 0); + int windowIndex = Util.binarySearchFloor(periodOffsets, periodIndex, true, false); + int windowPeriodIndex = periodIndex - periodOffsets[windowIndex]; + TimelineWindowDefinition windowDefinition = windowDefinitions[windowIndex]; + Object id = setIds ? windowPeriodIndex : null; + Object uid = setIds ? periodIndex : null; + long periodDurationUs = windowDefinition.durationUs / windowDefinition.periodCount; + return period.set(id, uid, windowIndex, periodDurationUs, periodDurationUs * windowPeriodIndex); } @Override @@ -78,7 +105,7 @@ public final class FakeTimeline extends Timeline { return C.INDEX_UNSET; } int index = (Integer) uid; - return index >= 0 && index < windowDefinitions.length ? index : C.INDEX_UNSET; + return index >= 0 && index < getPeriodCount() ? index : C.INDEX_UNSET; } } diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/TimelineAsserts.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/TimelineAsserts.java index 97fd9b07ea..029a303a33 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/TimelineAsserts.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/TimelineAsserts.java @@ -32,48 +32,6 @@ public final class TimelineAsserts { private TimelineAsserts() {} - /** - * Fake timeline with multiple periods and user-defined window id. - */ - public static final class FakeTimeline extends Timeline { - - private static final int WINDOW_DURATION_US = 1000000; - - private final int periodCount; - private final int id; - - public FakeTimeline(int periodCount, int id) { - this.periodCount = periodCount; - this.id = id; - } - - @Override - public int getWindowCount() { - return 1; - } - - @Override - public Window getWindow(int windowIndex, Window window, boolean setIds, - long defaultPositionProjectionUs) { - return window.set(id, 0, 0, true, false, 0, WINDOW_DURATION_US, 0, periodCount - 1, 0); - } - - @Override - public int getPeriodCount() { - return periodCount; - } - - @Override - public Period getPeriod(int periodIndex, Period period, boolean setIds) { - return period.set(periodIndex, null, 0, WINDOW_DURATION_US, 0); - } - - @Override - public int getIndexOfPeriod(Object uid) { - return C.INDEX_UNSET; - } - } - /** * Extracts the timeline from a media source. */