Add shuffle logic to concatenated timelines.

The implementation in the abstract base class takes care to forward the queries
to the correct methods given the shuffle mode and a given shuffle order.

All concatenated timeline implementations use an unshuffled order so far. The
handling of the shuffle orders will follow in other changes.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=166191165
This commit is contained in:
tonihei 2017-08-23 06:00:51 -07:00 committed by Oliver Woodman
parent 4883a9ba9a
commit 9fd19d0e7c
4 changed files with 50 additions and 22 deletions

View file

@ -26,9 +26,17 @@ import com.google.android.exoplayer2.Timeline;
/* package */ abstract class AbstractConcatenatedTimeline extends Timeline {
private final int childCount;
private final ShuffleOrder shuffleOrder;
public AbstractConcatenatedTimeline(int childCount) {
this.childCount = childCount;
/**
* Sets up a concatenated timeline with a shuffle order of child timelines.
*
* @param shuffleOrder A shuffle order of child timelines. The number of child timelines must
* match the number of elements in the shuffle order.
*/
public AbstractConcatenatedTimeline(ShuffleOrder shuffleOrder) {
this.shuffleOrder = shuffleOrder;
this.childCount = shuffleOrder.getLength();
}
@Override
@ -42,16 +50,17 @@ import com.google.android.exoplayer2.Timeline;
shuffleModeEnabled);
if (nextWindowIndexInChild != C.INDEX_UNSET) {
return firstWindowIndexInChild + nextWindowIndexInChild;
} else {
int nextChildIndex = childIndex + 1;
if (nextChildIndex < childCount) {
return getFirstWindowIndexByChildIndex(nextChildIndex);
} else if (repeatMode == Player.REPEAT_MODE_ALL) {
return 0;
} else {
return C.INDEX_UNSET;
}
}
int nextChildIndex = shuffleModeEnabled ? shuffleOrder.getNextIndex(childIndex)
: childIndex + 1;
if (nextChildIndex != C.INDEX_UNSET && nextChildIndex < childCount) {
return getFirstWindowIndexByChildIndex(nextChildIndex)
+ getTimelineByChildIndex(nextChildIndex).getFirstWindowIndex(shuffleModeEnabled);
}
if (repeatMode == Player.REPEAT_MODE_ALL) {
return getFirstWindowIndex(shuffleModeEnabled);
}
return C.INDEX_UNSET;
}
@Override
@ -65,15 +74,31 @@ import com.google.android.exoplayer2.Timeline;
shuffleModeEnabled);
if (previousWindowIndexInChild != C.INDEX_UNSET) {
return firstWindowIndexInChild + previousWindowIndexInChild;
} else {
if (firstWindowIndexInChild > 0) {
return firstWindowIndexInChild - 1;
} else if (repeatMode == Player.REPEAT_MODE_ALL) {
return getWindowCount() - 1;
} else {
return C.INDEX_UNSET;
}
}
int previousChildIndex = shuffleModeEnabled ? shuffleOrder.getPreviousIndex(childIndex)
: childIndex - 1;
if (previousChildIndex != C.INDEX_UNSET && previousChildIndex >= 0) {
return getFirstWindowIndexByChildIndex(previousChildIndex)
+ getTimelineByChildIndex(previousChildIndex).getLastWindowIndex(shuffleModeEnabled);
}
if (repeatMode == Player.REPEAT_MODE_ALL) {
return getLastWindowIndex(shuffleModeEnabled);
}
return C.INDEX_UNSET;
}
@Override
public int getLastWindowIndex(boolean shuffleModeEnabled) {
int lastChildIndex = shuffleModeEnabled ? shuffleOrder.getLastIndex() : childCount - 1;
return getFirstWindowIndexByChildIndex(lastChildIndex)
+ getTimelineByChildIndex(lastChildIndex).getLastWindowIndex(shuffleModeEnabled);
}
@Override
public int getFirstWindowIndex(boolean shuffleModeEnabled) {
int firstChildIndex = shuffleModeEnabled ? shuffleOrder.getFirstIndex() : 0;
return getFirstWindowIndexByChildIndex(firstChildIndex)
+ getTimelineByChildIndex(firstChildIndex).getFirstWindowIndex(shuffleModeEnabled);
}
@Override

View file

@ -19,6 +19,7 @@ import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.source.ShuffleOrder.UnshuffledShuffleOrder;
import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Util;
@ -167,7 +168,7 @@ public final class ConcatenatingMediaSource implements MediaSource {
private final boolean isRepeatOneAtomic;
public ConcatenatedTimeline(Timeline[] timelines, boolean isRepeatOneAtomic) {
super(timelines.length);
super(new UnshuffledShuffleOrder(timelines.length));
int[] sourcePeriodOffsets = new int[timelines.length];
int[] sourceWindowOffsets = new int[timelines.length];
long periodCount = 0;

View file

@ -23,6 +23,7 @@ import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ExoPlayer.ExoPlayerComponent;
import com.google.android.exoplayer2.ExoPlayer.ExoPlayerMessage;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.source.ShuffleOrder.UnshuffledShuffleOrder;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.util.Assertions;
@ -397,7 +398,7 @@ public final class DynamicConcatenatingMediaSource implements MediaSource, ExoPl
public ConcatenatedTimeline(Collection<MediaSourceHolder> mediaSourceHolders, int windowCount,
int periodCount) {
super(mediaSourceHolders.size());
super(new UnshuffledShuffleOrder(mediaSourceHolders.size()));
this.windowCount = windowCount;
this.periodCount = periodCount;
int childCount = mediaSourceHolders.size();

View file

@ -19,6 +19,7 @@ import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.source.ShuffleOrder.UnshuffledShuffleOrder;
import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.util.Assertions;
import java.io.IOException;
@ -101,7 +102,7 @@ public final class LoopingMediaSource implements MediaSource {
private final int loopCount;
public LoopingTimeline(Timeline childTimeline, int loopCount) {
super(loopCount);
super(new UnshuffledShuffleOrder(loopCount));
this.childTimeline = childTimeline;
childPeriodCount = childTimeline.getPeriodCount();
childWindowCount = childTimeline.getWindowCount();