Move media period end position from MediaperiodInfo to MediaPeriodId.

The end position is needed to make the MediaPeriodId unique as multiple
content periods may only vary in this parameter.

This also simplfies some other comparisons where the end position needed to
be compared in addition to the media period id.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=205634508
This commit is contained in:
tonihei 2018-07-23 02:53:28 -07:00 committed by Oliver Woodman
parent 41345dcb83
commit 0b3fa5176a
5 changed files with 67 additions and 50 deletions

View File

@ -676,7 +676,7 @@ import java.util.Collections;
MediaPeriodHolder oldPlayingPeriodHolder = queue.getPlayingPeriod(); MediaPeriodHolder oldPlayingPeriodHolder = queue.getPlayingPeriod();
MediaPeriodHolder newPlayingPeriodHolder = oldPlayingPeriodHolder; MediaPeriodHolder newPlayingPeriodHolder = oldPlayingPeriodHolder;
while (newPlayingPeriodHolder != null) { while (newPlayingPeriodHolder != null) {
if (shouldKeepPeriodHolder(periodId, periodPositionUs, newPlayingPeriodHolder)) { if (periodId.equals(newPlayingPeriodHolder.info.id) && newPlayingPeriodHolder.prepared) {
queue.removeAfter(newPlayingPeriodHolder); queue.removeAfter(newPlayingPeriodHolder);
break; break;
} }
@ -712,19 +712,6 @@ import java.util.Collections;
return periodPositionUs; return periodPositionUs;
} }
private boolean shouldKeepPeriodHolder(
MediaPeriodId seekPeriodId, long positionUs, MediaPeriodHolder holder) {
if (seekPeriodId.equals(holder.info.id) && holder.prepared) {
playbackInfo.timeline.getPeriod(holder.info.id.periodIndex, period);
int nextAdGroupIndex = period.getAdGroupIndexAfterPositionUs(positionUs);
if (nextAdGroupIndex == C.INDEX_UNSET
|| period.getAdGroupTimeUs(nextAdGroupIndex) == holder.info.endPositionUs) {
return true;
}
}
return false;
}
private void resetRendererPosition(long periodPositionUs) throws ExoPlaybackException { private void resetRendererPosition(long periodPositionUs) throws ExoPlaybackException {
rendererPositionUs = rendererPositionUs =
!queue.hasPlayingPeriod() !queue.hasPlayingPeriod()

View File

@ -82,13 +82,13 @@ import com.google.android.exoplayer2.util.Assertions;
sampleStreams = new SampleStream[rendererCapabilities.length]; sampleStreams = new SampleStream[rendererCapabilities.length];
mayRetainStreamFlags = new boolean[rendererCapabilities.length]; mayRetainStreamFlags = new boolean[rendererCapabilities.length];
MediaPeriod mediaPeriod = mediaSource.createPeriod(info.id, allocator); MediaPeriod mediaPeriod = mediaSource.createPeriod(info.id, allocator);
if (info.endPositionUs != C.TIME_END_OF_SOURCE) { if (info.id.endPositionUs != C.TIME_END_OF_SOURCE) {
mediaPeriod = mediaPeriod =
new ClippingMediaPeriod( new ClippingMediaPeriod(
mediaPeriod, mediaPeriod,
/* enableInitialDiscontinuity= */ true, /* enableInitialDiscontinuity= */ true,
/* startUs= */ 0, /* startUs= */ 0,
info.endPositionUs); info.id.endPositionUs);
} }
this.mediaPeriod = mediaPeriod; this.mediaPeriod = mediaPeriod;
} }
@ -219,7 +219,7 @@ import com.google.android.exoplayer2.util.Assertions;
public void release() { public void release() {
updatePeriodTrackSelectorResult(null); updatePeriodTrackSelectorResult(null);
try { try {
if (info.endPositionUs != C.TIME_END_OF_SOURCE) { if (info.id.endPositionUs != C.TIME_END_OF_SOURCE) {
mediaSource.releasePeriod(((ClippingMediaPeriod) mediaPeriod).mediaPeriod); mediaSource.releasePeriod(((ClippingMediaPeriod) mediaPeriod).mediaPeriod);
} else { } else {
mediaSource.releasePeriod(mediaPeriod); mediaSource.releasePeriod(mediaPeriod);

View File

@ -25,18 +25,13 @@ import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
public final MediaPeriodId id; public final MediaPeriodId id;
/** The start position of the media to play within the media period, in microseconds. */ /** The start position of the media to play within the media period, in microseconds. */
public final long startPositionUs; public final long startPositionUs;
/**
* The end position of the media to play within the media period, in microseconds, or {@link
* C#TIME_END_OF_SOURCE} if the end position is the end of the media period.
*/
public final long endPositionUs;
/** /**
* If this is an ad, the position to play in the next content media period. {@link C#TIME_UNSET} * If this is an ad, the position to play in the next content media period. {@link C#TIME_UNSET}
* otherwise. * otherwise.
*/ */
public final long contentPositionUs; public final long contentPositionUs;
/** /**
* The duration of the media period, like {@link #endPositionUs} but with {@link * The duration of the media period, like {@link MediaPeriodId#endPositionUs} but with {@link
* C#TIME_END_OF_SOURCE} resolved to the timeline period duration. May be {@link C#TIME_UNSET} if * C#TIME_END_OF_SOURCE} resolved to the timeline period duration. May be {@link C#TIME_UNSET} if
* the end position is not known. * the end position is not known.
*/ */
@ -55,14 +50,12 @@ import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
MediaPeriodInfo( MediaPeriodInfo(
MediaPeriodId id, MediaPeriodId id,
long startPositionUs, long startPositionUs,
long endPositionUs,
long contentPositionUs, long contentPositionUs,
long durationUs, long durationUs,
boolean isLastInTimelinePeriod, boolean isLastInTimelinePeriod,
boolean isFinal) { boolean isFinal) {
this.id = id; this.id = id;
this.startPositionUs = startPositionUs; this.startPositionUs = startPositionUs;
this.endPositionUs = endPositionUs;
this.contentPositionUs = contentPositionUs; this.contentPositionUs = contentPositionUs;
this.durationUs = durationUs; this.durationUs = durationUs;
this.isLastInTimelinePeriod = isLastInTimelinePeriod; this.isLastInTimelinePeriod = isLastInTimelinePeriod;
@ -77,7 +70,6 @@ import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
return new MediaPeriodInfo( return new MediaPeriodInfo(
id.copyWithPeriodIndex(periodIndex), id.copyWithPeriodIndex(periodIndex),
startPositionUs, startPositionUs,
endPositionUs,
contentPositionUs, contentPositionUs,
durationUs, durationUs,
isLastInTimelinePeriod, isLastInTimelinePeriod,
@ -89,7 +81,6 @@ import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
return new MediaPeriodInfo( return new MediaPeriodInfo(
id, id,
startPositionUs, startPositionUs,
endPositionUs,
contentPositionUs, contentPositionUs,
durationUs, durationUs,
isLastInTimelinePeriod, isLastInTimelinePeriod,

View File

@ -391,7 +391,12 @@ import com.google.android.exoplayer2.util.Assertions;
timeline.getPeriod(periodIndex, period); timeline.getPeriod(periodIndex, period);
int adGroupIndex = period.getAdGroupIndexForPositionUs(positionUs); int adGroupIndex = period.getAdGroupIndexForPositionUs(positionUs);
if (adGroupIndex == C.INDEX_UNSET) { if (adGroupIndex == C.INDEX_UNSET) {
return new MediaPeriodId(periodIndex, windowSequenceNumber); int nextAdGroupIndex = period.getAdGroupIndexAfterPositionUs(positionUs);
long endPositionUs =
nextAdGroupIndex == C.INDEX_UNSET
? C.TIME_END_OF_SOURCE
: period.getAdGroupTimeUs(nextAdGroupIndex);
return new MediaPeriodId(periodIndex, windowSequenceNumber, endPositionUs);
} else { } else {
int adIndexInAdGroup = period.getFirstAdIndexToPlay(adGroupIndex); int adIndexInAdGroup = period.getFirstAdIndexToPlay(adGroupIndex);
return new MediaPeriodId(periodIndex, adGroupIndex, adIndexInAdGroup, windowSequenceNumber); return new MediaPeriodId(periodIndex, adGroupIndex, adIndexInAdGroup, windowSequenceNumber);
@ -450,7 +455,6 @@ import com.google.android.exoplayer2.util.Assertions;
private boolean canKeepMediaPeriodHolder(MediaPeriodHolder periodHolder, MediaPeriodInfo info) { private boolean canKeepMediaPeriodHolder(MediaPeriodHolder periodHolder, MediaPeriodInfo info) {
MediaPeriodInfo periodHolderInfo = periodHolder.info; MediaPeriodInfo periodHolderInfo = periodHolder.info;
return periodHolderInfo.startPositionUs == info.startPositionUs return periodHolderInfo.startPositionUs == info.startPositionUs
&& periodHolderInfo.endPositionUs == info.endPositionUs
&& periodHolderInfo.id.equals(info.id); && periodHolderInfo.id.equals(info.id);
} }
@ -593,14 +597,14 @@ import com.google.android.exoplayer2.util.Assertions;
mediaPeriodInfo.contentPositionUs, mediaPeriodInfo.contentPositionUs,
currentPeriodId.windowSequenceNumber); currentPeriodId.windowSequenceNumber);
} }
} else if (mediaPeriodInfo.endPositionUs != C.TIME_END_OF_SOURCE) { } else if (mediaPeriodInfo.id.endPositionUs != C.TIME_END_OF_SOURCE) {
// Play the next ad group if it's available. // Play the next ad group if it's available.
int nextAdGroupIndex = period.getAdGroupIndexForPositionUs(mediaPeriodInfo.endPositionUs); int nextAdGroupIndex = period.getAdGroupIndexForPositionUs(mediaPeriodInfo.id.endPositionUs);
if (nextAdGroupIndex == C.INDEX_UNSET) { if (nextAdGroupIndex == C.INDEX_UNSET) {
// The next ad group can't be played. Play content from the ad group position instead. // The next ad group can't be played. Play content from the ad group position instead.
return getMediaPeriodInfoForContent( return getMediaPeriodInfoForContent(
currentPeriodId.periodIndex, currentPeriodId.periodIndex,
mediaPeriodInfo.endPositionUs, mediaPeriodInfo.id.endPositionUs,
currentPeriodId.windowSequenceNumber); currentPeriodId.windowSequenceNumber);
} }
int adIndexInAdGroup = period.getFirstAdIndexToPlay(nextAdGroupIndex); int adIndexInAdGroup = period.getFirstAdIndexToPlay(nextAdGroupIndex);
@ -610,7 +614,7 @@ import com.google.android.exoplayer2.util.Assertions;
currentPeriodId.periodIndex, currentPeriodId.periodIndex,
nextAdGroupIndex, nextAdGroupIndex,
adIndexInAdGroup, adIndexInAdGroup,
mediaPeriodInfo.endPositionUs, mediaPeriodInfo.id.endPositionUs,
currentPeriodId.windowSequenceNumber); currentPeriodId.windowSequenceNumber);
} else { } else {
// Check if the postroll ad should be played. // Check if the postroll ad should be played.
@ -639,18 +643,18 @@ import com.google.android.exoplayer2.util.Assertions;
private MediaPeriodInfo getUpdatedMediaPeriodInfo(MediaPeriodInfo info, MediaPeriodId newId) { private MediaPeriodInfo getUpdatedMediaPeriodInfo(MediaPeriodInfo info, MediaPeriodId newId) {
long startPositionUs = info.startPositionUs; long startPositionUs = info.startPositionUs;
long endPositionUs = info.endPositionUs; boolean isLastInPeriod = isLastInPeriod(newId);
boolean isLastInPeriod = isLastInPeriod(newId, endPositionUs);
boolean isLastInTimeline = isLastInTimeline(newId, isLastInPeriod); boolean isLastInTimeline = isLastInTimeline(newId, isLastInPeriod);
timeline.getPeriod(newId.periodIndex, period); timeline.getPeriod(newId.periodIndex, period);
long durationUs = long durationUs =
newId.isAd() newId.isAd()
? period.getAdDurationUs(newId.adGroupIndex, newId.adIndexInAdGroup) ? period.getAdDurationUs(newId.adGroupIndex, newId.adIndexInAdGroup)
: (endPositionUs == C.TIME_END_OF_SOURCE ? period.getDurationUs() : endPositionUs); : (newId.endPositionUs == C.TIME_END_OF_SOURCE
? period.getDurationUs()
: newId.endPositionUs);
return new MediaPeriodInfo( return new MediaPeriodInfo(
newId, newId,
startPositionUs, startPositionUs,
endPositionUs,
info.contentPositionUs, info.contentPositionUs,
durationUs, durationUs,
isLastInPeriod, isLastInPeriod,
@ -683,7 +687,7 @@ import com.google.android.exoplayer2.util.Assertions;
long windowSequenceNumber) { long windowSequenceNumber) {
MediaPeriodId id = MediaPeriodId id =
new MediaPeriodId(periodIndex, adGroupIndex, adIndexInAdGroup, windowSequenceNumber); new MediaPeriodId(periodIndex, adGroupIndex, adIndexInAdGroup, windowSequenceNumber);
boolean isLastInPeriod = isLastInPeriod(id, C.TIME_END_OF_SOURCE); boolean isLastInPeriod = isLastInPeriod(id);
boolean isLastInTimeline = isLastInTimeline(id, isLastInPeriod); boolean isLastInTimeline = isLastInTimeline(id, isLastInPeriod);
long durationUs = long durationUs =
timeline timeline
@ -696,7 +700,6 @@ import com.google.android.exoplayer2.util.Assertions;
return new MediaPeriodInfo( return new MediaPeriodInfo(
id, id,
startPositionUs, startPositionUs,
C.TIME_END_OF_SOURCE,
contentPositionUs, contentPositionUs,
durationUs, durationUs,
isLastInPeriod, isLastInPeriod,
@ -705,21 +708,22 @@ import com.google.android.exoplayer2.util.Assertions;
private MediaPeriodInfo getMediaPeriodInfoForContent( private MediaPeriodInfo getMediaPeriodInfoForContent(
int periodIndex, long startPositionUs, long windowSequenceNumber) { int periodIndex, long startPositionUs, long windowSequenceNumber) {
MediaPeriodId id = new MediaPeriodId(periodIndex, windowSequenceNumber);
timeline.getPeriod(id.periodIndex, period);
int nextAdGroupIndex = period.getAdGroupIndexAfterPositionUs(startPositionUs); int nextAdGroupIndex = period.getAdGroupIndexAfterPositionUs(startPositionUs);
long endUs = long endPositionUs =
nextAdGroupIndex == C.INDEX_UNSET nextAdGroupIndex == C.INDEX_UNSET
? C.TIME_END_OF_SOURCE ? C.TIME_END_OF_SOURCE
: period.getAdGroupTimeUs(nextAdGroupIndex); : period.getAdGroupTimeUs(nextAdGroupIndex);
boolean isLastInPeriod = isLastInPeriod(id, endUs); MediaPeriodId id = new MediaPeriodId(periodIndex, windowSequenceNumber, endPositionUs);
timeline.getPeriod(id.periodIndex, period);
boolean isLastInPeriod = isLastInPeriod(id);
boolean isLastInTimeline = isLastInTimeline(id, isLastInPeriod); boolean isLastInTimeline = isLastInTimeline(id, isLastInPeriod);
long durationUs = endUs == C.TIME_END_OF_SOURCE ? period.getDurationUs() : endUs; long durationUs =
endPositionUs == C.TIME_END_OF_SOURCE ? period.getDurationUs() : endPositionUs;
return new MediaPeriodInfo( return new MediaPeriodInfo(
id, startPositionUs, endUs, C.TIME_UNSET, durationUs, isLastInPeriod, isLastInTimeline); id, startPositionUs, C.TIME_UNSET, durationUs, isLastInPeriod, isLastInTimeline);
} }
private boolean isLastInPeriod(MediaPeriodId id, long endPositionUs) { private boolean isLastInPeriod(MediaPeriodId id) {
int adGroupCount = timeline.getPeriod(id.periodIndex, period).getAdGroupCount(); int adGroupCount = timeline.getPeriod(id.periodIndex, period).getAdGroupCount();
if (adGroupCount == 0) { if (adGroupCount == 0) {
return true; return true;
@ -729,7 +733,7 @@ import com.google.android.exoplayer2.util.Assertions;
boolean isAd = id.isAd(); boolean isAd = id.isAd();
if (period.getAdGroupTimeUs(lastAdGroupIndex) != C.TIME_END_OF_SOURCE) { if (period.getAdGroupTimeUs(lastAdGroupIndex) != C.TIME_END_OF_SOURCE) {
// There's no postroll ad. // There's no postroll ad.
return !isAd && endPositionUs == C.TIME_END_OF_SOURCE; return !isAd && id.endPositionUs == C.TIME_END_OF_SOURCE;
} }
int postrollAdCount = period.getAdCountInAdGroup(lastAdGroupIndex); int postrollAdCount = period.getAdCountInAdGroup(lastAdGroupIndex);

View File

@ -91,6 +91,15 @@ public interface MediaSource {
*/ */
public final long windowSequenceNumber; public final long windowSequenceNumber;
/**
* The end position of the media to play within the media period, in microseconds, or {@link
* C#TIME_END_OF_SOURCE} if the end position is the end of the media period.
*
* <p>Note that this only applies if the media period is for content (i.e., not for an ad) and
* is clipped to the position of the next ad group.
*/
public final long endPositionUs;
/** /**
* Creates a media period identifier for a dummy period which is not part of a buffered sequence * Creates a media period identifier for a dummy period which is not part of a buffered sequence
* of windows. * of windows.
@ -109,7 +118,20 @@ public interface MediaSource {
* windows this media period is part of. * windows this media period is part of.
*/ */
public MediaPeriodId(int periodIndex, long windowSequenceNumber) { public MediaPeriodId(int periodIndex, long windowSequenceNumber) {
this(periodIndex, C.INDEX_UNSET, C.INDEX_UNSET, windowSequenceNumber); this(periodIndex, C.INDEX_UNSET, C.INDEX_UNSET, windowSequenceNumber, C.TIME_END_OF_SOURCE);
}
/**
* Creates a media period identifier for the specified clipped period in the timeline.
*
* @param periodIndex The timeline period index.
* @param windowSequenceNumber The sequence number of the window in the buffered sequence of
* windows this media period is part of.
* @param endPositionUs The end position of the media period within the timeline period, in
* microseconds.
*/
public MediaPeriodId(int periodIndex, long windowSequenceNumber, long endPositionUs) {
this(periodIndex, C.INDEX_UNSET, C.INDEX_UNSET, windowSequenceNumber, endPositionUs);
} }
/** /**
@ -124,10 +146,20 @@ public interface MediaSource {
*/ */
public MediaPeriodId( public MediaPeriodId(
int periodIndex, int adGroupIndex, int adIndexInAdGroup, long windowSequenceNumber) { int periodIndex, int adGroupIndex, int adIndexInAdGroup, long windowSequenceNumber) {
this(periodIndex, adGroupIndex, adIndexInAdGroup, windowSequenceNumber, C.TIME_END_OF_SOURCE);
}
private MediaPeriodId(
int periodIndex,
int adGroupIndex,
int adIndexInAdGroup,
long windowSequenceNumber,
long endPositionUs) {
this.periodIndex = periodIndex; this.periodIndex = periodIndex;
this.adGroupIndex = adGroupIndex; this.adGroupIndex = adGroupIndex;
this.adIndexInAdGroup = adIndexInAdGroup; this.adIndexInAdGroup = adIndexInAdGroup;
this.windowSequenceNumber = windowSequenceNumber; this.windowSequenceNumber = windowSequenceNumber;
this.endPositionUs = endPositionUs;
} }
/** /**
@ -136,7 +168,8 @@ public interface MediaSource {
public MediaPeriodId copyWithPeriodIndex(int newPeriodIndex) { public MediaPeriodId copyWithPeriodIndex(int newPeriodIndex) {
return periodIndex == newPeriodIndex return periodIndex == newPeriodIndex
? this ? this
: new MediaPeriodId(newPeriodIndex, adGroupIndex, adIndexInAdGroup, windowSequenceNumber); : new MediaPeriodId(
newPeriodIndex, adGroupIndex, adIndexInAdGroup, windowSequenceNumber, endPositionUs);
} }
/** /**
@ -159,7 +192,8 @@ public interface MediaSource {
return periodIndex == periodId.periodIndex return periodIndex == periodId.periodIndex
&& adGroupIndex == periodId.adGroupIndex && adGroupIndex == periodId.adGroupIndex
&& adIndexInAdGroup == periodId.adIndexInAdGroup && adIndexInAdGroup == periodId.adIndexInAdGroup
&& windowSequenceNumber == periodId.windowSequenceNumber; && windowSequenceNumber == periodId.windowSequenceNumber
&& endPositionUs == periodId.endPositionUs;
} }
@Override @Override
@ -169,6 +203,7 @@ public interface MediaSource {
result = 31 * result + adGroupIndex; result = 31 * result + adGroupIndex;
result = 31 * result + adIndexInAdGroup; result = 31 * result + adIndexInAdGroup;
result = 31 * result + (int) windowSequenceNumber; result = 31 * result + (int) windowSequenceNumber;
result = 31 * result + (int) endPositionUs;
return result; return result;
} }