diff --git a/library/core/src/androidTest/java/com/google/android/exoplayer2/source/MergingMediaSourceTest.java b/library/core/src/androidTest/java/com/google/android/exoplayer2/source/MergingMediaSourceTest.java new file mode 100644 index 0000000000..ba37385c75 --- /dev/null +++ b/library/core/src/androidTest/java/com/google/android/exoplayer2/source/MergingMediaSourceTest.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.android.exoplayer2.source; + +import com.google.android.exoplayer2.C; +import com.google.android.exoplayer2.Timeline; +import com.google.android.exoplayer2.source.MergingMediaSource.IllegalMergeException; +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.MediaSourceTestRunner; +import java.io.IOException; +import junit.framework.TestCase; + +/** + * Unit tests for {@link MergingMediaSource}. + */ +public class MergingMediaSourceTest extends TestCase { + + public void testMergingDynamicTimelines() throws IOException { + FakeTimeline firstTimeline = new FakeTimeline( + new TimelineWindowDefinition(true, true, C.TIME_UNSET)); + FakeTimeline secondTimeline = new FakeTimeline( + new TimelineWindowDefinition(true, true, C.TIME_UNSET)); + testMergingMediaSourcePrepare(firstTimeline, secondTimeline); + } + + public void testMergingStaticTimelines() throws IOException { + FakeTimeline firstTimeline = new FakeTimeline( + new TimelineWindowDefinition(true, false, 20)); + FakeTimeline secondTimeline = new FakeTimeline( + new TimelineWindowDefinition(true, false, 10)); + testMergingMediaSourcePrepare(firstTimeline, secondTimeline); + } + + public void testMergingTimelinesWithDifferentPeriodCounts() throws IOException { + FakeTimeline firstTimeline = new FakeTimeline(new TimelineWindowDefinition(1, null)); + FakeTimeline secondTimeline = new FakeTimeline(new TimelineWindowDefinition(2, null)); + try { + testMergingMediaSourcePrepare(firstTimeline, secondTimeline); + fail("Expected merging to fail."); + } catch (IllegalMergeException e) { + assertEquals(IllegalMergeException.REASON_PERIOD_COUNT_MISMATCH, e.reason); + } + } + + /** + * Wraps the specified timelines in a {@link MergingMediaSource}, prepares it and checks that it + * forwards the first of the wrapped timelines. + */ + private static void testMergingMediaSourcePrepare(Timeline... timelines) throws IOException { + MediaSource[] mediaSources = new MediaSource[timelines.length]; + for (int i = 0; i < timelines.length; i++) { + mediaSources[i] = new FakeMediaSource(timelines[i], null); + } + MergingMediaSource mediaSource = new MergingMediaSource(mediaSources); + MediaSourceTestRunner testRunner = new MediaSourceTestRunner(mediaSource, null); + try { + Timeline timeline = testRunner.prepareSource(); + // The merged timeline should always be the one from the first child. + assertEquals(timelines[0], timeline); + } finally { + testRunner.release(); + } + } + +} diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/MergingMediaSource.java b/library/core/src/main/java/com/google/android/exoplayer2/source/MergingMediaSource.java index 3b468d8709..79ed864e25 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/MergingMediaSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/MergingMediaSource.java @@ -28,8 +28,7 @@ import java.util.Arrays; /** * Merges multiple {@link MediaSource}s. *

- * The {@link Timeline}s of the sources being merged must have the same number of periods, and must - * not have any dynamic windows. + * The {@link Timeline}s of the sources being merged must have the same number of periods. */ public final class MergingMediaSource implements MediaSource { @@ -42,26 +41,20 @@ public final class MergingMediaSource implements MediaSource { * The reason the merge failed. */ @Retention(RetentionPolicy.SOURCE) - @IntDef({REASON_WINDOWS_ARE_DYNAMIC, REASON_PERIOD_COUNT_MISMATCH}) + @IntDef({REASON_PERIOD_COUNT_MISMATCH}) public @interface Reason {} - /** - * One of the sources being merged has a dynamic window. - */ - public static final int REASON_WINDOWS_ARE_DYNAMIC = 0; /** * The sources have different period counts. */ - public static final int REASON_PERIOD_COUNT_MISMATCH = 1; + public static final int REASON_PERIOD_COUNT_MISMATCH = 0; /** - * The reason the merge failed. One of {@link #REASON_WINDOWS_ARE_DYNAMIC} and - * {@link #REASON_PERIOD_COUNT_MISMATCH}. + * The reason the merge failed. */ @Reason public final int reason; /** - * @param reason The reason the merge failed. One of {@link #REASON_WINDOWS_ARE_DYNAMIC} and - * {@link #REASON_PERIOD_COUNT_MISMATCH}. + * @param reason The reason the merge failed. */ public IllegalMergeException(@Reason int reason) { this.reason = reason; @@ -73,7 +66,6 @@ public final class MergingMediaSource implements MediaSource { private final MediaSource[] mediaSources; private final ArrayList pendingTimelineSources; - private final Timeline.Window window; private final CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory; private Listener listener; @@ -100,7 +92,6 @@ public final class MergingMediaSource implements MediaSource { this.mediaSources = mediaSources; this.compositeSequenceableLoaderFactory = compositeSequenceableLoaderFactory; pendingTimelineSources = new ArrayList<>(Arrays.asList(mediaSources)); - window = new Timeline.Window(); periodCount = PERIOD_COUNT_UNSET; } @@ -170,12 +161,6 @@ public final class MergingMediaSource implements MediaSource { } private IllegalMergeException checkTimelineMerges(Timeline timeline) { - int windowCount = timeline.getWindowCount(); - for (int i = 0; i < windowCount; i++) { - if (timeline.getWindow(i, window, false).isDynamic) { - return new IllegalMergeException(IllegalMergeException.REASON_WINDOWS_ARE_DYNAMIC); - } - } if (periodCount == PERIOD_COUNT_UNSET) { periodCount = timeline.getPeriodCount(); } else if (timeline.getPeriodCount() != periodCount) {