Pragmatic fix for Concat(source1, Looping(source2))

Issue: #2680

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=153827243
This commit is contained in:
olly 2017-04-21 07:57:37 -07:00 committed by Oliver Woodman
parent 3280dc8777
commit 1506b6d2b7
2 changed files with 17 additions and 6 deletions

View file

@ -20,6 +20,7 @@ import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Util;
import java.io.IOException;
import java.util.HashMap;
@ -152,12 +153,14 @@ public final class ConcatenatingMediaSource implements MediaSource {
public ConcatenatedTimeline(Timeline[] timelines) {
int[] sourcePeriodOffsets = new int[timelines.length];
int[] sourceWindowOffsets = new int[timelines.length];
int periodCount = 0;
long periodCount = 0;
int windowCount = 0;
for (int i = 0; i < timelines.length; i++) {
Timeline timeline = timelines[i];
periodCount += timeline.getPeriodCount();
sourcePeriodOffsets[i] = periodCount;
Assertions.checkState(periodCount <= Integer.MAX_VALUE,
"ConcatenatingMediaSource children contain too many periods");
sourcePeriodOffsets[i] = (int) periodCount;
windowCount += timeline.getWindowCount();
sourceWindowOffsets[i] = windowCount;
}

View file

@ -29,6 +29,13 @@ import java.io.IOException;
*/
public final class LoopingMediaSource implements MediaSource {
/**
* The maximum number of periods that can be exposed by the source. The value of this constant is
* large enough to cause indefinite looping in practice (the total duration of the looping source
* will be approximately five years if the duration of each period is one second).
*/
public static final int MAX_EXPOSED_PERIODS = 157680000;
private static final String TAG = "LoopingMediaSource";
private final MediaSource childSource;
@ -50,8 +57,8 @@ public final class LoopingMediaSource implements MediaSource {
*
* @param childSource The {@link MediaSource} to loop.
* @param loopCount The desired number of loops. Must be strictly positive. The actual number of
* loops will be capped at the maximum value that can achieved without causing the number of
* periods exposed by the source to exceed {@link Integer#MAX_VALUE}.
* loops will be capped at the maximum that can achieved without causing the number of
* periods exposed by the source to exceed {@link #MAX_EXPOSED_PERIODS}.
*/
public LoopingMediaSource(MediaSource childSource, int loopCount) {
Assertions.checkArgument(loopCount > 0);
@ -101,8 +108,9 @@ public final class LoopingMediaSource implements MediaSource {
this.childTimeline = childTimeline;
childPeriodCount = childTimeline.getPeriodCount();
childWindowCount = childTimeline.getWindowCount();
// This is the maximum number of loops that can be performed without overflow.
int maxLoopCount = Integer.MAX_VALUE / childPeriodCount;
// This is the maximum number of loops that can be performed without exceeding
// MAX_EXPOSED_PERIODS periods.
int maxLoopCount = MAX_EXPOSED_PERIODS / childPeriodCount;
if (loopCount > maxLoopCount) {
if (loopCount != Integer.MAX_VALUE) {
Log.w(TAG, "Capped loops to avoid overflow: " + loopCount + " -> " + maxLoopCount);