From 7d4ddfbb9174e2be5a930630eeb3a0a3420803b0 Mon Sep 17 00:00:00 2001 From: tonihei Date: Wed, 8 Jan 2025 09:20:14 -0800 Subject: [PATCH] Don't force discontinuities for server-side ad insertion transitions We currently force discontinuities for all clipped content periods that don't start from zero. This shouldn't be done for server-side ad insertion streams where we are guaranteed to get a continuous underlying stream. To enable the right decision, we need to add a flag to MediaPeriodInfo for isPrecededByTransitionFromSameStream, which mirrors the existing isFollowedByTransitionToSameStream. The problem is currently not visible due to a bug in ClippingMediaPeriod that automatically ignores most discontinuities that don't match the start of the clip. PiperOrigin-RevId: 713315398 --- .../media3/exoplayer/MediaPeriodHolder.java | 15 ++++-- .../media3/exoplayer/MediaPeriodInfo.java | 12 +++++ .../media3/exoplayer/MediaPeriodQueue.java | 35 ++++++++---- .../exoplayer/MediaPeriodQueueTest.java | 54 +++++++++++++++++++ 4 files changed, 103 insertions(+), 13 deletions(-) diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/MediaPeriodHolder.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/MediaPeriodHolder.java index 79c9a74ded..8c11585852 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/MediaPeriodHolder.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/MediaPeriodHolder.java @@ -124,7 +124,12 @@ import java.io.IOException; mayRetainStreamFlags = new boolean[rendererCapabilities.length]; mediaPeriod = createMediaPeriod( - info.id, mediaSourceList, allocator, info.startPositionUs, info.endPositionUs); + info.id, + mediaSourceList, + allocator, + info.startPositionUs, + info.endPositionUs, + info.isPrecededByTransitionFromSameStream); } /** @@ -488,12 +493,16 @@ import java.io.IOException; MediaSourceList mediaSourceList, Allocator allocator, long startPositionUs, - long endPositionUs) { + long endPositionUs, + boolean isPrecededByTransitionFromSameStream) { MediaPeriod mediaPeriod = mediaSourceList.createPeriod(id, allocator, startPositionUs); if (endPositionUs != C.TIME_UNSET) { mediaPeriod = new ClippingMediaPeriod( - mediaPeriod, /* enableInitialDiscontinuity= */ true, /* startUs= */ 0, endPositionUs); + mediaPeriod, + /* enableInitialDiscontinuity= */ !isPrecededByTransitionFromSameStream, + /* startUs= */ 0, + endPositionUs); } return mediaPeriod; } diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/MediaPeriodInfo.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/MediaPeriodInfo.java index 53c852fa4b..9900e210a8 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/MediaPeriodInfo.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/MediaPeriodInfo.java @@ -56,6 +56,12 @@ import androidx.media3.exoplayer.source.MediaSource.MediaPeriodId; */ public final long durationUs; + /** + * Whether this media period is preceded by another media period of the same server-side inserted + * as stream. + */ + public final boolean isPrecededByTransitionFromSameStream; + /** * Whether this media period is followed by a transition to another media period of the same * server-side inserted ad stream. If true, {@link #isLastInTimelinePeriod}, {@link @@ -84,6 +90,7 @@ import androidx.media3.exoplayer.source.MediaSource.MediaPeriodId; long requestedContentPositionUs, long endPositionUs, long durationUs, + boolean isPrecededByTransitionFromSameStream, boolean isFollowedByTransitionToSameStream, boolean isLastInTimelinePeriod, boolean isLastInTimelineWindow, @@ -98,6 +105,7 @@ import androidx.media3.exoplayer.source.MediaSource.MediaPeriodId; this.requestedContentPositionUs = requestedContentPositionUs; this.endPositionUs = endPositionUs; this.durationUs = durationUs; + this.isPrecededByTransitionFromSameStream = isPrecededByTransitionFromSameStream; this.isFollowedByTransitionToSameStream = isFollowedByTransitionToSameStream; this.isLastInTimelinePeriod = isLastInTimelinePeriod; this.isLastInTimelineWindow = isLastInTimelineWindow; @@ -117,6 +125,7 @@ import androidx.media3.exoplayer.source.MediaSource.MediaPeriodId; requestedContentPositionUs, endPositionUs, durationUs, + isPrecededByTransitionFromSameStream, isFollowedByTransitionToSameStream, isLastInTimelinePeriod, isLastInTimelineWindow, @@ -136,6 +145,7 @@ import androidx.media3.exoplayer.source.MediaSource.MediaPeriodId; requestedContentPositionUs, endPositionUs, durationUs, + isPrecededByTransitionFromSameStream, isFollowedByTransitionToSameStream, isLastInTimelinePeriod, isLastInTimelineWindow, @@ -155,6 +165,7 @@ import androidx.media3.exoplayer.source.MediaSource.MediaPeriodId; && requestedContentPositionUs == that.requestedContentPositionUs && endPositionUs == that.endPositionUs && durationUs == that.durationUs + && isPrecededByTransitionFromSameStream == that.isPrecededByTransitionFromSameStream && isFollowedByTransitionToSameStream == that.isFollowedByTransitionToSameStream && isLastInTimelinePeriod == that.isLastInTimelinePeriod && isLastInTimelineWindow == that.isLastInTimelineWindow @@ -170,6 +181,7 @@ import androidx.media3.exoplayer.source.MediaSource.MediaPeriodId; result = 31 * result + (int) requestedContentPositionUs; result = 31 * result + (int) endPositionUs; result = 31 * result + (int) durationUs; + result = 31 * result + (isPrecededByTransitionFromSameStream ? 1 : 0); result = 31 * result + (isFollowedByTransitionToSameStream ? 1 : 0); result = 31 * result + (isLastInTimelinePeriod ? 1 : 0); result = 31 * result + (isLastInTimelineWindow ? 1 : 0); diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/MediaPeriodQueue.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/MediaPeriodQueue.java index 9bd6f28c53..4b7540ed87 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/MediaPeriodQueue.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/MediaPeriodQueue.java @@ -324,13 +324,15 @@ import java.util.List; mediaPeriodId.adGroupIndex, mediaPeriodId.adIndexInAdGroup, /* contentPositionUs= */ positionUs, - mediaPeriodId.windowSequenceNumber) + mediaPeriodId.windowSequenceNumber, + /* isPrecededByTransitionFromSameStream= */ false) : getMediaPeriodInfoForContent( timeline, mediaPeriodId.periodUid, /* startPositionUs= */ positionUs, /* requestedContentPositionUs= */ C.TIME_UNSET, - mediaPeriodId.windowSequenceNumber); + mediaPeriodId.windowSequenceNumber, + /* isPrecededByTransitionFromSameStream= */ false); } @Nullable @@ -661,6 +663,7 @@ import java.util.List; info.requestedContentPositionUs, endPositionUs, durationUs, + info.isPrecededByTransitionFromSameStream, isFollowedByTransitionToSameStream, isLastInPeriod, isLastInWindow, @@ -1058,6 +1061,8 @@ import java.util.List; MediaPeriodInfo mediaPeriodInfo = mediaPeriodHolder.info; MediaPeriodId currentPeriodId = mediaPeriodInfo.id; timeline.getPeriodByUid(currentPeriodId.periodUid, period); + boolean isPrecededByTransitionFromSameStream = + mediaPeriodInfo.isFollowedByTransitionToSameStream; if (currentPeriodId.isAd()) { int adGroupIndex = currentPeriodId.adGroupIndex; int adCountInCurrentAdGroup = period.getAdCountInAdGroup(adGroupIndex); @@ -1074,7 +1079,8 @@ import java.util.List; adGroupIndex, nextAdIndexInAdGroup, mediaPeriodInfo.requestedContentPositionUs, - currentPeriodId.windowSequenceNumber); + currentPeriodId.windowSequenceNumber, + isPrecededByTransitionFromSameStream); } else { // Play content from the ad group position. long startPositionUs = mediaPeriodInfo.requestedContentPositionUs; @@ -1102,7 +1108,8 @@ import java.util.List; currentPeriodId.periodUid, max(minStartPositionUs, startPositionUs), mediaPeriodInfo.requestedContentPositionUs, - currentPeriodId.windowSequenceNumber); + currentPeriodId.windowSequenceNumber, + isPrecededByTransitionFromSameStream); } } else if (currentPeriodId.nextAdGroupIndex != C.INDEX_UNSET && period.isLivePostrollPlaceholder(currentPeriodId.nextAdGroupIndex)) { @@ -1127,7 +1134,8 @@ import java.util.List; currentPeriodId.periodUid, startPositionUs, /* requestedContentPositionUs= */ mediaPeriodInfo.durationUs, - currentPeriodId.windowSequenceNumber); + currentPeriodId.windowSequenceNumber, + /* isPrecededByTransitionFromSameStream= */ false); } return getMediaPeriodInfoForAd( timeline, @@ -1135,7 +1143,8 @@ import java.util.List; /* adGroupIndex= */ currentPeriodId.nextAdGroupIndex, adIndexInAdGroup, /* contentPositionUs= */ mediaPeriodInfo.durationUs, - currentPeriodId.windowSequenceNumber); + currentPeriodId.windowSequenceNumber, + isPrecededByTransitionFromSameStream); } } @@ -1157,14 +1166,16 @@ import java.util.List; id.adGroupIndex, id.adIndexInAdGroup, requestedContentPositionUs, - id.windowSequenceNumber); + id.windowSequenceNumber, + /* isPrecededByTransitionFromSameStream= */ false); } else { return getMediaPeriodInfoForContent( timeline, id.periodUid, startPositionUs, requestedContentPositionUs, - id.windowSequenceNumber); + id.windowSequenceNumber, + /* isPrecededByTransitionFromSameStream= */ false); } } @@ -1174,7 +1185,8 @@ import java.util.List; int adGroupIndex, int adIndexInAdGroup, long contentPositionUs, - long windowSequenceNumber) { + long windowSequenceNumber, + boolean isPrecededByTransitionFromSameStream) { MediaPeriodId id = new MediaPeriodId(periodUid, adGroupIndex, adIndexInAdGroup, windowSequenceNumber); long durationUs = @@ -1197,6 +1209,7 @@ import java.util.List; /* requestedContentPositionUs= */ contentPositionUs, /* endPositionUs= */ C.TIME_UNSET, durationUs, + isPrecededByTransitionFromSameStream, isFollowedByTransitionToSameStream, /* isLastInTimelinePeriod= */ false, /* isLastInTimelineWindow= */ false, @@ -1208,7 +1221,8 @@ import java.util.List; Object periodUid, long startPositionUs, long requestedContentPositionUs, - long windowSequenceNumber) { + long windowSequenceNumber, + boolean isPrecededByTransitionFromSameStream) { timeline.getPeriodByUid(periodUid, period); int nextAdGroupIndex = period.getAdGroupIndexAfterPositionUs(startPositionUs); boolean isNextAdGroupPostrollPlaceholder = @@ -1254,6 +1268,7 @@ import java.util.List; requestedContentPositionUs, endPositionUs, durationUs, + isPrecededByTransitionFromSameStream, isFollowedByTransitionToSameStream, isLastInPeriod, isLastInWindow, diff --git a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/MediaPeriodQueueTest.java b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/MediaPeriodQueueTest.java index d8ed07d0d6..8575b0d065 100644 --- a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/MediaPeriodQueueTest.java +++ b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/MediaPeriodQueueTest.java @@ -159,6 +159,7 @@ public final class MediaPeriodQueueTest { /* requestedContentPositionUs= */ C.TIME_UNSET, /* endPositionUs= */ C.TIME_UNSET, /* durationUs= */ CONTENT_DURATION_US, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false, /* isLastInPeriod= */ true, /* isLastInWindow= */ true, @@ -175,6 +176,7 @@ public final class MediaPeriodQueueTest { /* adGroupIndex= */ 0, AD_DURATION_US, /* contentPositionUs= */ C.TIME_UNSET, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false); advance(); assertGetNextMediaPeriodInfoReturnsContentMediaPeriod( @@ -183,6 +185,7 @@ public final class MediaPeriodQueueTest { /* requestedContentPositionUs= */ C.TIME_UNSET, /* endPositionUs= */ C.TIME_UNSET, /* durationUs= */ CONTENT_DURATION_US, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false, /* isLastInPeriod= */ true, /* isLastInWindow= */ true, @@ -199,6 +202,7 @@ public final class MediaPeriodQueueTest { /* requestedContentPositionUs= */ C.TIME_UNSET, /* endPositionUs= */ FIRST_AD_START_TIME_US, /* durationUs= */ FIRST_AD_START_TIME_US, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false, /* isLastInPeriod= */ false, /* isLastInWindow= */ false, @@ -210,6 +214,7 @@ public final class MediaPeriodQueueTest { /* adGroupIndex= */ 0, /* adDurationUs= */ C.TIME_UNSET, /* contentPositionUs= */ FIRST_AD_START_TIME_US, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false); setAdGroupLoaded(/* adGroupIndex= */ 0); assertNextMediaPeriodInfoIsAd( @@ -217,6 +222,7 @@ public final class MediaPeriodQueueTest { /* adGroupIndex= */ 0, AD_DURATION_US, /* contentPositionUs= */ FIRST_AD_START_TIME_US, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false); advance(); assertGetNextMediaPeriodInfoReturnsContentMediaPeriod( @@ -225,6 +231,7 @@ public final class MediaPeriodQueueTest { /* requestedContentPositionUs= */ FIRST_AD_START_TIME_US, /* endPositionUs= */ SECOND_AD_START_TIME_US, /* durationUs= */ SECOND_AD_START_TIME_US, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false, /* isLastInPeriod= */ false, /* isLastInWindow= */ false, @@ -237,6 +244,7 @@ public final class MediaPeriodQueueTest { /* adGroupIndex= */ 1, AD_DURATION_US, /* contentPositionUs= */ SECOND_AD_START_TIME_US, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false); advance(); assertGetNextMediaPeriodInfoReturnsContentMediaPeriod( @@ -245,6 +253,7 @@ public final class MediaPeriodQueueTest { /* requestedContentPositionUs= */ SECOND_AD_START_TIME_US, /* endPositionUs= */ C.TIME_UNSET, /* durationUs= */ CONTENT_DURATION_US, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false, /* isLastInPeriod= */ true, /* isLastInWindow= */ true, @@ -261,6 +270,7 @@ public final class MediaPeriodQueueTest { /* requestedContentPositionUs= */ C.TIME_UNSET, /* endPositionUs= */ FIRST_AD_START_TIME_US, /* durationUs= */ FIRST_AD_START_TIME_US, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false, /* isLastInPeriod= */ false, /* isLastInWindow= */ false, @@ -273,6 +283,7 @@ public final class MediaPeriodQueueTest { /* adGroupIndex= */ 0, AD_DURATION_US, /* contentPositionUs= */ FIRST_AD_START_TIME_US, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false); advance(); assertGetNextMediaPeriodInfoReturnsContentMediaPeriod( @@ -281,6 +292,7 @@ public final class MediaPeriodQueueTest { /* requestedContentPositionUs= */ FIRST_AD_START_TIME_US, /* endPositionUs= */ C.TIME_END_OF_SOURCE, /* durationUs= */ CONTENT_DURATION_US, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false, /* isLastInPeriod= */ false, /* isLastInWindow= */ false, @@ -293,6 +305,7 @@ public final class MediaPeriodQueueTest { /* adGroupIndex= */ 1, AD_DURATION_US, /* contentPositionUs= */ CONTENT_DURATION_US, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false); advance(); assertGetNextMediaPeriodInfoReturnsContentMediaPeriod( @@ -301,6 +314,7 @@ public final class MediaPeriodQueueTest { /* requestedContentPositionUs= */ CONTENT_DURATION_US, /* endPositionUs= */ C.TIME_UNSET, /* durationUs= */ CONTENT_DURATION_US, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false, /* isLastInPeriod= */ true, /* isLastInWindow= */ true, @@ -330,6 +344,7 @@ public final class MediaPeriodQueueTest { /* adGroupIndex= */ 0, AD_DURATION_US, /* contentPositionUs= */ C.TIME_UNSET, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false); advance(); assertGetNextMediaPeriodInfoReturnsContentMediaPeriod( @@ -338,6 +353,7 @@ public final class MediaPeriodQueueTest { /* requestedContentPositionUs= */ C.TIME_UNSET, /* endPositionUs= */ FIRST_AD_START_TIME_US, /* durationUs= */ FIRST_AD_START_TIME_US, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false, /* isLastInPeriod= */ false, /* isLastInWindow= */ false, @@ -350,6 +366,7 @@ public final class MediaPeriodQueueTest { /* adGroupIndex= */ 1, AD_DURATION_US, /* contentPositionUs= */ FIRST_AD_START_TIME_US, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false); advance(); assertGetNextMediaPeriodInfoReturnsContentMediaPeriod( @@ -358,6 +375,7 @@ public final class MediaPeriodQueueTest { /* requestedContentPositionUs= */ FIRST_AD_START_TIME_US, /* endPositionUs= */ C.TIME_END_OF_SOURCE, /* durationUs= */ CONTENT_DURATION_US, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false, /* isLastInPeriod= */ false, /* isLastInWindow= */ false, @@ -370,6 +388,7 @@ public final class MediaPeriodQueueTest { /* adGroupIndex= */ 2, AD_DURATION_US, /* contentPositionUs= */ CONTENT_DURATION_US, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false); advance(); assertGetNextMediaPeriodInfoReturnsContentMediaPeriod( @@ -378,6 +397,7 @@ public final class MediaPeriodQueueTest { /* requestedContentPositionUs= */ CONTENT_DURATION_US, /* endPositionUs= */ C.TIME_UNSET, /* durationUs= */ CONTENT_DURATION_US, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false, /* isLastInPeriod= */ true, /* isLastInWindow= */ true, @@ -407,6 +427,7 @@ public final class MediaPeriodQueueTest { /* adGroupIndex= */ 0, AD_DURATION_US, /* contentPositionUs= */ C.TIME_UNSET, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ true); advance(); assertGetNextMediaPeriodInfoReturnsContentMediaPeriod( @@ -415,6 +436,7 @@ public final class MediaPeriodQueueTest { /* requestedContentPositionUs= */ C.TIME_UNSET, /* endPositionUs= */ FIRST_AD_START_TIME_US, /* durationUs= */ FIRST_AD_START_TIME_US, + /* isPrecededByTransitionFromSameStream= */ true, /* isFollowedByTransitionToSameStream= */ true, /* isLastInPeriod= */ false, /* isLastInWindow= */ false, @@ -427,6 +449,7 @@ public final class MediaPeriodQueueTest { /* adGroupIndex= */ 1, AD_DURATION_US, /* contentPositionUs= */ FIRST_AD_START_TIME_US, + /* isPrecededByTransitionFromSameStream= */ true, /* isFollowedByTransitionToSameStream= */ true); advance(); assertGetNextMediaPeriodInfoReturnsContentMediaPeriod( @@ -435,6 +458,7 @@ public final class MediaPeriodQueueTest { /* requestedContentPositionUs= */ FIRST_AD_START_TIME_US, /* endPositionUs= */ SECOND_AD_START_TIME_US, /* durationUs= */ SECOND_AD_START_TIME_US, + /* isPrecededByTransitionFromSameStream= */ true, /* isFollowedByTransitionToSameStream= */ true, /* isLastInPeriod= */ false, /* isLastInWindow= */ false, @@ -447,6 +471,7 @@ public final class MediaPeriodQueueTest { /* adGroupIndex= */ 2, AD_DURATION_US, /* contentPositionUs= */ SECOND_AD_START_TIME_US, + /* isPrecededByTransitionFromSameStream= */ true, /* isFollowedByTransitionToSameStream= */ true); advance(); assertGetNextMediaPeriodInfoReturnsContentMediaPeriod( @@ -455,6 +480,7 @@ public final class MediaPeriodQueueTest { /* requestedContentPositionUs= */ SECOND_AD_START_TIME_US, /* endPositionUs= */ CONTENT_DURATION_US, /* durationUs= */ CONTENT_DURATION_US, + /* isPrecededByTransitionFromSameStream= */ true, /* isFollowedByTransitionToSameStream= */ false, /* isLastInPeriod= */ true, /* isLastInWindow= */ true, @@ -487,6 +513,7 @@ public final class MediaPeriodQueueTest { /* requestedContentPositionUs= */ C.TIME_UNSET, /* endPositionUs= */ C.TIME_UNSET, /* durationUs= */ contentPeriodDurationUs, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false, /* isLastInPeriod= */ true, /* isLastInWindow= */ false, @@ -499,6 +526,7 @@ public final class MediaPeriodQueueTest { /* requestedContentPositionUs= */ 0, /* endPositionUs= */ C.TIME_UNSET, /* durationUs= */ adPeriodDurationUs, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false, /* isLastInPeriod= */ true, /* isLastInWindow= */ false, @@ -511,6 +539,7 @@ public final class MediaPeriodQueueTest { /* requestedContentPositionUs= */ 0, /* endPositionUs= */ C.TIME_UNSET, /* durationUs= */ adPeriodDurationUs, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false, /* isLastInPeriod= */ true, /* isLastInWindow= */ false, @@ -523,6 +552,7 @@ public final class MediaPeriodQueueTest { /* requestedContentPositionUs= */ 0, /* endPositionUs= */ C.TIME_UNSET, /* durationUs= */ C.TIME_UNSET, // last period in live timeline + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false, /* isLastInPeriod= */ true, /* isLastInWindow= */ true, @@ -557,6 +587,7 @@ public final class MediaPeriodQueueTest { /* requestedContentPositionUs= */ C.TIME_UNSET, /* endPositionUs= */ C.TIME_UNSET, /* durationUs= */ contentPeriodDurationUs, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false, /* isLastInPeriod= */ false, /* isLastInWindow= */ false, @@ -569,6 +600,7 @@ public final class MediaPeriodQueueTest { /* requestedContentPositionUs= */ 0, /* endPositionUs= */ C.TIME_UNSET, /* durationUs= */ adPeriodDurationUs, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false, /* isLastInPeriod= */ false, /* isLastInWindow= */ false, @@ -581,6 +613,7 @@ public final class MediaPeriodQueueTest { /* requestedContentPositionUs= */ 0, /* endPositionUs= */ C.TIME_UNSET, /* durationUs= */ adPeriodDurationUs, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false, /* isLastInPeriod= */ false, /* isLastInWindow= */ false, @@ -593,6 +626,7 @@ public final class MediaPeriodQueueTest { /* requestedContentPositionUs= */ 0, /* endPositionUs= */ C.TIME_UNSET, /* durationUs= */ C.TIME_UNSET, // last period in live timeline + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false, /* isLastInPeriod= */ false, /* isLastInWindow= */ false, @@ -626,6 +660,7 @@ public final class MediaPeriodQueueTest { /* requestedContentPositionUs= */ C.TIME_UNSET, /* endPositionUs= */ C.TIME_UNSET, /* durationUs= */ contentPeriodDurationUs, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false, /* isLastInPeriod= */ false, /* isLastInWindow= */ false, @@ -638,6 +673,7 @@ public final class MediaPeriodQueueTest { /* adGroupIndex= */ 0, /* adDurationUs= */ adPeriodDurationUs, /* contentPositionUs= */ 0, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ true); advance(); assertGetNextMediaPeriodInfoReturnsContentMediaPeriod( @@ -646,6 +682,7 @@ public final class MediaPeriodQueueTest { /* requestedContentPositionUs= */ 0, /* endPositionUs= */ adPeriodDurationUs, /* durationUs= */ adPeriodDurationUs, + /* isPrecededByTransitionFromSameStream= */ true, /* isFollowedByTransitionToSameStream= */ false, /* isLastInPeriod= */ true, /* isLastInWindow= */ false, @@ -658,6 +695,7 @@ public final class MediaPeriodQueueTest { /* adGroupIndex= */ 0, /* adDurationUs= */ adPeriodDurationUs, /* contentPositionUs= */ 0, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ true); advance(); assertGetNextMediaPeriodInfoReturnsContentMediaPeriod( @@ -666,6 +704,7 @@ public final class MediaPeriodQueueTest { /* requestedContentPositionUs= */ 0, /* endPositionUs= */ adPeriodDurationUs, /* durationUs= */ adPeriodDurationUs, + /* isPrecededByTransitionFromSameStream= */ true, /* isFollowedByTransitionToSameStream= */ false, /* isLastInPeriod= */ true, /* isLastInWindow= */ false, @@ -678,6 +717,7 @@ public final class MediaPeriodQueueTest { /* requestedContentPositionUs= */ 0, /* endPositionUs= */ C.TIME_UNSET, /* durationUs= */ C.TIME_UNSET, // Last period in stream. + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false, /* isLastInPeriod= */ false, /* isLastInWindow= */ false, @@ -710,6 +750,7 @@ public final class MediaPeriodQueueTest { /* requestedContentPositionUs= */ C.TIME_UNSET, /* endPositionUs= */ C.TIME_UNSET, /* durationUs= */ contentPeriodDurationUs, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false, /* isLastInPeriod= */ false, /* isLastInWindow= */ false, @@ -722,6 +763,7 @@ public final class MediaPeriodQueueTest { /* requestedContentPositionUs= */ 0, /* endPositionUs= */ C.TIME_UNSET, /* durationUs= */ C.TIME_UNSET, // Last period in stream. + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false, /* isLastInPeriod= */ false, /* isLastInWindow= */ false, @@ -740,6 +782,7 @@ public final class MediaPeriodQueueTest { /* requestedContentPositionUs= */ C.TIME_UNSET, /* endPositionUs= */ C.TIME_END_OF_SOURCE, /* durationUs= */ CONTENT_DURATION_US, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false, /* isLastInPeriod= */ false, /* isLastInWindow= */ false, @@ -753,6 +796,7 @@ public final class MediaPeriodQueueTest { /* requestedContentPositionUs= */ CONTENT_DURATION_US, /* endPositionUs= */ C.TIME_UNSET, /* durationUs= */ CONTENT_DURATION_US, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false, /* isLastInPeriod= */ true, /* isLastInWindow= */ true, @@ -771,6 +815,7 @@ public final class MediaPeriodQueueTest { /* adGroupIndex= */ 0, AD_DURATION_US, /* contentPositionUs= */ C.TIME_UNSET, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false); setAdGroupPlayed(/* adGroupIndex= */ 0); clear(); @@ -780,6 +825,7 @@ public final class MediaPeriodQueueTest { /* requestedContentPositionUs= */ C.TIME_UNSET, /* endPositionUs= */ FIRST_AD_START_TIME_US, /* durationUs= */ FIRST_AD_START_TIME_US, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false, /* isLastInPeriod= */ false, /* isLastInWindow= */ false, @@ -793,6 +839,7 @@ public final class MediaPeriodQueueTest { /* requestedContentPositionUs= */ C.TIME_UNSET, /* endPositionUs= */ C.TIME_END_OF_SOURCE, /* durationUs= */ CONTENT_DURATION_US, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false, /* isLastInPeriod= */ false, /* isLastInWindow= */ false, @@ -806,6 +853,7 @@ public final class MediaPeriodQueueTest { /* requestedContentPositionUs= */ C.TIME_UNSET, /* endPositionUs= */ C.TIME_UNSET, /* durationUs= */ CONTENT_DURATION_US, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false, /* isLastInPeriod= */ true, /* isLastInWindow= */ true, @@ -830,6 +878,7 @@ public final class MediaPeriodQueueTest { /* requestedContentPositionUs= */ C.TIME_UNSET, /* endPositionUs= */ C.TIME_UNSET, /* durationUs= */ CONTENT_DURATION_US + DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false, /* isLastInPeriod= */ true, /* isLastInWindow= */ false, @@ -842,6 +891,7 @@ public final class MediaPeriodQueueTest { /* requestedContentPositionUs= */ 0, /* endPositionUs= */ C.TIME_UNSET, /* durationUs= */ CONTENT_DURATION_US, + /* isPrecededByTransitionFromSameStream= */ false, /* isFollowedByTransitionToSameStream= */ false, /* isLastInPeriod= */ true, /* isLastInWindow= */ true, @@ -1988,6 +2038,7 @@ public final class MediaPeriodQueueTest { long requestedContentPositionUs, long endPositionUs, long durationUs, + boolean isPrecededByTransitionFromSameStream, boolean isFollowedByTransitionToSameStream, boolean isLastInPeriod, boolean isLastInWindow, @@ -2001,6 +2052,7 @@ public final class MediaPeriodQueueTest { requestedContentPositionUs, endPositionUs, durationUs, + isPrecededByTransitionFromSameStream, isFollowedByTransitionToSameStream, isLastInPeriod, isLastInWindow, @@ -2012,6 +2064,7 @@ public final class MediaPeriodQueueTest { int adGroupIndex, long adDurationUs, long contentPositionUs, + boolean isPrecededByTransitionFromSameStream, boolean isFollowedByTransitionToSameStream) { assertThat(getNextMediaPeriodInfo()) .isEqualTo( @@ -2025,6 +2078,7 @@ public final class MediaPeriodQueueTest { /* requestedContentPositionUs= */ contentPositionUs, /* endPositionUs= */ C.TIME_UNSET, adDurationUs, + isPrecededByTransitionFromSameStream, isFollowedByTransitionToSameStream, /* isLastInTimelinePeriod= */ false, /* isLastInTimelineWindow= */ false,