Create MediaPeriods based on an identifier not an index

This will allow MediaSources to provide MediaPeriods that correspond to ad
breaks in a timeline period rather than content for a timeline period, in a
future change.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=160267841
This commit is contained in:
andrewlewis 2017-06-27 06:29:29 -07:00 committed by Oliver Woodman
parent d4059ecc65
commit 675756d32d
14 changed files with 60 additions and 33 deletions

View file

@ -159,7 +159,8 @@ public final class ImaAdsMediaSource implements MediaSource {
}
@Override
public MediaPeriod createPeriod(int index, Allocator allocator) {
public MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator) {
int index = id.periodIndex;
if (timeline.isPeriodAd(index)) {
int adBreakIndex = timeline.getAdBreakIndex(index);
int adIndexInAdBreak = timeline.getAdIndexInAdBreak(index);
@ -174,13 +175,15 @@ public final class ImaAdsMediaSource implements MediaSource {
}
MediaSource adBreakMediaSource = adBreakMediaSources[adBreakIndex][adIndexInAdBreak];
MediaPeriod adBreakMediaPeriod = adBreakMediaSource.createPeriod(0, allocator);
MediaPeriod adBreakMediaPeriod =
adBreakMediaSource.createPeriod(new MediaPeriodId(0), allocator);
mediaSourceByMediaPeriod.put(adBreakMediaPeriod, adBreakMediaSource);
return adBreakMediaPeriod;
} else {
long startUs = timeline.getContentStartTimeUs(index);
long endUs = timeline.getContentEndTimeUs(index);
MediaPeriod contentMediaPeriod = contentMediaSource.createPeriod(0, allocator);
MediaPeriod contentMediaPeriod =
contentMediaSource.createPeriod(new MediaPeriodId(0), allocator);
ClippingMediaPeriod clippingPeriod = new ClippingMediaPeriod(contentMediaPeriod, true);
clippingPeriod.setClipping(startUs, endUs == C.TIME_UNSET ? C.TIME_END_OF_SOURCE : endUs);
mediaSourceByMediaPeriod.put(contentMediaPeriod, contentMediaSource);
@ -445,7 +448,7 @@ public final class ImaAdsMediaSource implements MediaSource {
}
public void setMediaSource(MediaSource mediaSource) {
mediaPeriod = mediaSource.createPeriod(index, allocator);
mediaPeriod = mediaSource.createPeriod(new MediaPeriodId(index), allocator);
if (callback != null) {
mediaPeriod.prepare(this, positionUs);
}

View file

@ -535,8 +535,8 @@ public final class ExoPlayerTest extends TestCase {
}
@Override
public MediaPeriod createPeriod(int index, Allocator allocator) {
Assertions.checkIndex(index, 0, timeline.getPeriodCount());
public MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator) {
Assertions.checkIndex(id.periodIndex, 0, timeline.getPeriodCount());
assertTrue(preparedSource);
assertFalse(releasedSource);
FakeMediaPeriod mediaPeriod = new FakeMediaPeriod(trackGroupArray);

View file

@ -98,7 +98,7 @@ public class TimelineTest extends TestCase {
}
@Override
public MediaPeriod createPeriod(int index, Allocator allocator) {
public MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator) {
return null;
}

View file

@ -26,6 +26,7 @@ import android.util.Pair;
import com.google.android.exoplayer2.ExoPlayer.ExoPlayerMessage;
import com.google.android.exoplayer2.source.MediaPeriod;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
import com.google.android.exoplayer2.source.SampleStream;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
@ -1543,7 +1544,8 @@ import java.io.IOException;
this.startPositionUs = startPositionUs;
sampleStreams = new SampleStream[renderers.length];
mayRetainStreamFlags = new boolean[renderers.length];
mediaPeriod = mediaSource.createPeriod(periodIndex, loadControl.getAllocator());
mediaPeriod = mediaSource.createPeriod(new MediaPeriodId(periodIndex),
loadControl.getAllocator());
}
public long toRendererTime(long periodTimeUs) {

View file

@ -91,9 +91,9 @@ public final class ClippingMediaSource implements MediaSource, MediaSource.Liste
}
@Override
public MediaPeriod createPeriod(int index, Allocator allocator) {
public MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator) {
ClippingMediaPeriod mediaPeriod = new ClippingMediaPeriod(
mediaSource.createPeriod(index, allocator), enableInitialDiscontinuity);
mediaSource.createPeriod(id, allocator), enableInitialDiscontinuity);
mediaPeriods.add(mediaPeriod);
mediaPeriod.setClipping(clippingTimeline.startUs, clippingTimeline.endUs);
return mediaPeriod;

View file

@ -91,11 +91,11 @@ public final class ConcatenatingMediaSource implements MediaSource {
}
@Override
public MediaPeriod createPeriod(int index, Allocator allocator) {
int sourceIndex = timeline.getChildIndexByPeriodIndex(index);
int periodIndexInSource = index - timeline.getFirstPeriodIndexInChild(sourceIndex);
MediaPeriod mediaPeriod =
mediaSources[sourceIndex].createPeriod(periodIndexInSource, allocator);
public MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator) {
int sourceIndex = timeline.getChildIndexByPeriodIndex(id.periodIndex);
MediaPeriodId periodIdInSource =
new MediaPeriodId(id.periodIndex - timeline.getFirstPeriodIndexInChild(sourceIndex));
MediaPeriod mediaPeriod = mediaSources[sourceIndex].createPeriod(periodIdInSource, allocator);
sourceIndexByMediaPeriod.put(mediaPeriod, sourceIndex);
return mediaPeriod;
}

View file

@ -165,8 +165,8 @@ public final class ExtractorMediaSource implements MediaSource, MediaSource.List
}
@Override
public MediaPeriod createPeriod(int index, Allocator allocator) {
Assertions.checkArgument(index == 0);
public MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator) {
Assertions.checkArgument(id.periodIndex == 0);
return new ExtractorMediaPeriod(uri, dataSourceFactory.createDataSource(),
extractorsFactory.createExtractors(), minLoadableRetryCount, eventHandler, eventListener,
this, allocator, customCacheKey, continueLoadingCheckIntervalBytes);

View file

@ -76,10 +76,10 @@ public final class LoopingMediaSource implements MediaSource {
}
@Override
public MediaPeriod createPeriod(int index, Allocator allocator) {
public MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator) {
return loopCount != Integer.MAX_VALUE
? childSource.createPeriod(index % childPeriodCount, allocator)
: childSource.createPeriod(index, allocator);
? childSource.createPeriod(new MediaPeriodId(id.periodIndex % childPeriodCount), allocator)
: childSource.createPeriod(id, allocator);
}
@Override

View file

@ -41,6 +41,27 @@ public interface MediaSource {
}
/**
* Identifier for a {@link MediaPeriod}.
*/
final class MediaPeriodId {
/**
* The timeline period index.
*/
public final int periodIndex;
/**
* Creates a media period identifier for the specified period in the timeline.
*
* @param periodIndex The timeline period index.
*/
public MediaPeriodId(int periodIndex) {
this.periodIndex = periodIndex;
}
}
/**
* Starts preparation of the source.
*
@ -59,15 +80,15 @@ public interface MediaSource {
void maybeThrowSourceInfoRefreshError() throws IOException;
/**
* Returns a new {@link MediaPeriod} corresponding to the period at the specified {@code index}.
* This method may be called multiple times with the same index without an intervening call to
* Returns a new {@link MediaPeriod} identified by {@code periodId}. This method may be called
* multiple times with the same period identifier without an intervening call to
* {@link #releasePeriod(MediaPeriod)}.
*
* @param index The index of the period.
* @param id The identifier of the period.
* @param allocator An {@link Allocator} from which to obtain media buffer allocations.
* @return A new {@link MediaPeriod}.
*/
MediaPeriod createPeriod(int index, Allocator allocator);
MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator);
/**
* Releases the period.

View file

@ -116,10 +116,10 @@ public final class MergingMediaSource implements MediaSource {
}
@Override
public MediaPeriod createPeriod(int index, Allocator allocator) {
public MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator) {
MediaPeriod[] periods = new MediaPeriod[mediaSources.length];
for (int i = 0; i < periods.length; i++) {
periods[i] = mediaSources[i].createPeriod(index, allocator);
periods[i] = mediaSources[i].createPeriod(id, allocator);
}
return new MergingMediaPeriod(periods);
}

View file

@ -95,8 +95,8 @@ public final class SingleSampleMediaSource implements MediaSource {
}
@Override
public MediaPeriod createPeriod(int index, Allocator allocator) {
Assertions.checkArgument(index == 0);
public MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator) {
Assertions.checkArgument(id.periodIndex == 0);
return new SingleSampleMediaPeriod(uri, dataSourceFactory, format, minLoadableRetryCount,
eventHandler, eventListener, eventSourceId);
}

View file

@ -281,7 +281,8 @@ public final class DashMediaSource implements MediaSource {
}
@Override
public MediaPeriod createPeriod(int periodIndex, Allocator allocator) {
public MediaPeriod createPeriod(MediaPeriodId periodId, Allocator allocator) {
int periodIndex = periodId.periodIndex;
EventDispatcher periodEventDispatcher = eventDispatcher.copyWithMediaTimeOffsetMs(
manifest.getPeriod(periodIndex).startMs);
DashMediaPeriod mediaPeriod = new DashMediaPeriod(firstPeriodId + periodIndex, manifest,

View file

@ -88,8 +88,8 @@ public final class HlsMediaSource implements MediaSource,
}
@Override
public MediaPeriod createPeriod(int index, Allocator allocator) {
Assertions.checkArgument(index == 0);
public MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator) {
Assertions.checkArgument(id.periodIndex == 0);
return new HlsMediaPeriod(playlistTracker, dataSourceFactory, minLoadableRetryCount,
eventDispatcher, allocator);
}

View file

@ -222,8 +222,8 @@ public final class SsMediaSource implements MediaSource,
}
@Override
public MediaPeriod createPeriod(int index, Allocator allocator) {
Assertions.checkArgument(index == 0);
public MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator) {
Assertions.checkArgument(id.periodIndex == 0);
SsMediaPeriod period = new SsMediaPeriod(manifest, chunkSourceFactory, minLoadableRetryCount,
eventDispatcher, manifestLoaderErrorThrower, allocator);
mediaPeriods.add(period);