Pass MediaPeriodId to DeferredMediaPeriod when actual period is created.

This helps to distinguish between the MediaPeriodId the deferred media period is being
created with and the MediaPeriodId which is used to create the actual underlying period.

This serves two purposes:
1. The error reporting of ad prepare errors uses the correct media period id (the
   externally visible ad media period id).
2. The transition to using media period uid instead of indices is simplified.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=206160463
This commit is contained in:
tonihei 2018-07-26 08:11:10 -07:00 committed by Oliver Woodman
parent 49ef1f3f8c
commit 133f5f16b8
3 changed files with 32 additions and 22 deletions

View File

@ -392,17 +392,16 @@ public class ConcatenatingMediaSource extends CompositeMediaSource<MediaSourceHo
public final MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator) {
int mediaSourceHolderIndex = findMediaSourceHolderByPeriodIndex(id.periodIndex);
MediaSourceHolder holder = mediaSourceHolders.get(mediaSourceHolderIndex);
MediaPeriodId idInSource =
id.copyWithPeriodIndex(id.periodIndex - holder.firstPeriodIndexInChild);
DeferredMediaPeriod mediaPeriod =
new DeferredMediaPeriod(holder.mediaSource, idInSource, allocator);
DeferredMediaPeriod mediaPeriod = new DeferredMediaPeriod(holder.mediaSource, id, allocator);
mediaSourceByMediaPeriod.put(mediaPeriod, holder);
holder.activeMediaPeriods.add(mediaPeriod);
if (!holder.hasStartedPreparing) {
holder.hasStartedPreparing = true;
prepareChildSource(holder, holder.mediaSource);
} else if (holder.isPrepared) {
mediaPeriod.createPeriod();
MediaPeriodId idInSource =
id.copyWithPeriodIndex(id.periodIndex - holder.firstPeriodIndexInChild);
mediaPeriod.createPeriod(idInSource);
}
return mediaPeriod;
}
@ -599,7 +598,10 @@ public class ConcatenatingMediaSource extends CompositeMediaSource<MediaSourceHo
for (int i = 0; i < mediaSourceHolder.activeMediaPeriods.size(); i++) {
DeferredMediaPeriod deferredMediaPeriod = mediaSourceHolder.activeMediaPeriods.get(i);
deferredMediaPeriod.setDefaultPreparePositionUs(defaultPeriodPositionUs);
deferredMediaPeriod.createPeriod();
MediaPeriodId idInSource =
deferredMediaPeriod.id.copyWithPeriodIndex(
deferredMediaPeriod.id.periodIndex - mediaSourceHolder.firstPeriodIndexInChild);
deferredMediaPeriod.createPeriod(idInSource);
}
mediaSourceHolder.isPrepared = true;
}

View File

@ -40,7 +40,9 @@ public final class DeferredMediaPeriod implements MediaPeriod, MediaPeriod.Callb
void onPrepareError(MediaPeriodId mediaPeriodId, IOException exception);
}
/** The {@link MediaSource} which will create the actual media period. */
public final MediaSource mediaSource;
/** The {@link MediaPeriodId} used to create the deferred media period. */
public final MediaPeriodId id;
private final Allocator allocator;
@ -56,7 +58,7 @@ public final class DeferredMediaPeriod implements MediaPeriod, MediaPeriod.Callb
* Creates a new deferred media period.
*
* @param mediaSource The media source to wrap.
* @param id The identifier for the media period to create when {@link #createPeriod()} is called.
* @param id The identifier used to create the deferred media period.
* @param allocator The allocator used to create the media period.
*/
public DeferredMediaPeriod(MediaSource mediaSource, MediaPeriodId id, Allocator allocator) {
@ -100,8 +102,10 @@ public final class DeferredMediaPeriod implements MediaPeriod, MediaPeriod.Callb
* Calls {@link MediaSource#createPeriod(MediaPeriodId, Allocator)} on the wrapped source then
* prepares it if {@link #prepare(Callback, long)} has been called. Call {@link #releasePeriod()}
* to release the period.
*
* @param id The identifier that should be used to create the media period from the media source.
*/
public void createPeriod() {
public void createPeriod(MediaPeriodId id) {
mediaPeriod = mediaSource.createPeriod(id, allocator);
if (callback != null) {
mediaPeriod.prepare(this, preparePositionUs);

View File

@ -170,6 +170,10 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
}
// Used to identify the content "child" source for CompositeMediaSource.
private static final MediaPeriodId DUMMY_CONTENT_MEDIA_PERIOD_ID =
new MediaPeriodId(/* periodIndex= */ 0);
private final MediaSource contentMediaSource;
private final MediaSourceFactory adMediaSourceFactory;
private final AdsLoader adsLoader;
@ -314,7 +318,7 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
Assertions.checkArgument(isTopLevelSource);
final ComponentListener componentListener = new ComponentListener();
this.componentListener = componentListener;
prepareChildSource(new MediaPeriodId(/* periodIndex= */ 0), contentMediaSource);
prepareChildSource(DUMMY_CONTENT_MEDIA_PERIOD_ID, contentMediaSource);
mainHandler.post(new Runnable() {
@Override
public void run() {
@ -344,16 +348,14 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
prepareChildSource(id, adMediaSource);
}
MediaSource mediaSource = adGroupMediaSources[adGroupIndex][adIndexInAdGroup];
DeferredMediaPeriod deferredMediaPeriod =
new DeferredMediaPeriod(
mediaSource,
new MediaPeriodId(/* periodIndex= */ 0, id.windowSequenceNumber),
allocator);
DeferredMediaPeriod deferredMediaPeriod = new DeferredMediaPeriod(mediaSource, id, allocator);
deferredMediaPeriod.setPrepareErrorListener(
new AdPrepareErrorListener(adUri, adGroupIndex, adIndexInAdGroup));
List<DeferredMediaPeriod> mediaPeriods = deferredMediaPeriodByAdMediaSource.get(mediaSource);
if (mediaPeriods == null) {
deferredMediaPeriod.createPeriod();
MediaPeriodId adSourceMediaPeriodId =
new MediaPeriodId(/* periodIndex= */ 0, id.windowSequenceNumber);
deferredMediaPeriod.createPeriod(adSourceMediaPeriodId);
} else {
// Keep track of the deferred media period so it can be populated with the real media period
// when the source's info becomes available.
@ -362,7 +364,7 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
return deferredMediaPeriod;
} else {
DeferredMediaPeriod mediaPeriod = new DeferredMediaPeriod(contentMediaSource, id, allocator);
mediaPeriod.createPeriod();
mediaPeriod.createPeriod(id);
return mediaPeriod;
}
}
@ -415,8 +417,8 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
@Override
protected @Nullable MediaPeriodId getMediaPeriodIdForChildMediaPeriodId(
MediaPeriodId childId, MediaPeriodId mediaPeriodId) {
// The child id for the content period is just a dummy without window sequence number. That's
// why we need to forward the reported mediaPeriodId in this case.
// The child id for the content period is just DUMMY_CONTENT_MEDIA_PERIOD_ID. That's why we need
// to forward the reported mediaPeriodId in this case.
return childId.isAd() ? childId : mediaPeriodId;
}
@ -443,12 +445,14 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
int adIndexInAdGroup, Timeline timeline) {
Assertions.checkArgument(timeline.getPeriodCount() == 1);
adDurationsUs[adGroupIndex][adIndexInAdGroup] = timeline.getPeriod(0, period).getDurationUs();
if (deferredMediaPeriodByAdMediaSource.containsKey(mediaSource)) {
List<DeferredMediaPeriod> mediaPeriods = deferredMediaPeriodByAdMediaSource.get(mediaSource);
List<DeferredMediaPeriod> mediaPeriods = deferredMediaPeriodByAdMediaSource.remove(mediaSource);
if (mediaPeriods != null) {
for (int i = 0; i < mediaPeriods.size(); i++) {
mediaPeriods.get(i).createPeriod();
DeferredMediaPeriod mediaPeriod = mediaPeriods.get(i);
MediaPeriodId adSourceMediaPeriodId =
new MediaPeriodId(/* periodIndex= */ 0, mediaPeriod.id.windowSequenceNumber);
mediaPeriod.createPeriod(adSourceMediaPeriodId);
}
deferredMediaPeriodByAdMediaSource.remove(mediaSource);
}
maybeUpdateSourceInfo();
}