From 1a12018daeb7fafa2756dcd4d10e3f3682015ff9 Mon Sep 17 00:00:00 2001 From: tonihei Date: Thu, 18 Feb 2021 12:33:19 +0000 Subject: [PATCH] Add ConcatenatingMediaSource version that fully combines windows. The published Timeline contains one window only with all periods of the child sources. Issue: #4868 PiperOrigin-RevId: 358150276 --- .../google/android/exoplayer2/Timeline.java | 21 ++++++++++++------- .../exoplayer2/source/MediaPeriodId.java | 8 +++++++ .../exoplayer2/source/MediaSource.java | 10 +++++++++ 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/library/common/src/main/java/com/google/android/exoplayer2/Timeline.java b/library/common/src/main/java/com/google/android/exoplayer2/Timeline.java index d7e1e955db..1b7e84309d 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/Timeline.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/Timeline.java @@ -435,7 +435,13 @@ public abstract class Timeline { */ public long durationUs; - private long positionInWindowUs; + /** + * The position of the start of this period relative to the start of the window to which it + * belongs, in microseconds. May be negative if the start of the period is not within the + * window. + */ + public long positionInWindowUs; + private AdPlaybackState adPlaybackState; /** Creates a new instance with no ad playback state. */ @@ -922,13 +928,14 @@ public abstract class Timeline { } } int periodIndex = window.firstPeriodIndex; - long periodPositionUs = window.getPositionInFirstPeriodUs() + windowPositionUs; - long periodDurationUs = getPeriod(periodIndex, period, /* setIds= */ true).getDurationUs(); - while (periodDurationUs != C.TIME_UNSET && periodPositionUs >= periodDurationUs - && periodIndex < window.lastPeriodIndex) { - periodPositionUs -= periodDurationUs; - periodDurationUs = getPeriod(++periodIndex, period, /* setIds= */ true).getDurationUs(); + getPeriod(periodIndex, period); + while (periodIndex < window.lastPeriodIndex + && period.positionInWindowUs != windowPositionUs + && getPeriod(periodIndex + 1, period).positionInWindowUs <= windowPositionUs) { + periodIndex++; } + getPeriod(periodIndex, period, /* setIds= */ true); + long periodPositionUs = windowPositionUs - period.positionInWindowUs; return Pair.create(Assertions.checkNotNull(period.uid), periodPositionUs); } diff --git a/library/common/src/main/java/com/google/android/exoplayer2/source/MediaPeriodId.java b/library/common/src/main/java/com/google/android/exoplayer2/source/MediaPeriodId.java index ad0e289ba9..8192486a1b 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/source/MediaPeriodId.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/source/MediaPeriodId.java @@ -152,6 +152,14 @@ public class MediaPeriodId { newPeriodUid, adGroupIndex, adIndexInAdGroup, windowSequenceNumber, nextAdGroupIndex); } + /** Returns a copy of this period identifier with a new {@code windowSequenceNumber}. */ + public MediaPeriodId copyWithWindowSequenceNumber(long windowSequenceNumber) { + return this.windowSequenceNumber == windowSequenceNumber + ? this + : new MediaPeriodId( + periodUid, adGroupIndex, adIndexInAdGroup, windowSequenceNumber, nextAdGroupIndex); + } + /** Returns whether this period identifier identifies an ad in an ad group in a period. */ public boolean isAd() { return adGroupIndex != C.INDEX_UNSET; diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/MediaSource.java b/library/core/src/main/java/com/google/android/exoplayer2/source/MediaSource.java index f6f2ab496d..4b5229ba00 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/MediaSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/MediaSource.java @@ -104,9 +104,19 @@ public interface MediaSource { } /** See {@link com.google.android.exoplayer2.source.MediaPeriodId#copyWithPeriodUid(Object)}. */ + @Override public MediaPeriodId copyWithPeriodUid(Object newPeriodUid) { return new MediaPeriodId(super.copyWithPeriodUid(newPeriodUid)); } + + /** + * See {@link + * com.google.android.exoplayer2.source.MediaPeriodId#copyWithWindowSequenceNumber(long)}. + */ + @Override + public MediaPeriodId copyWithWindowSequenceNumber(long windowSequenceNumber) { + return new MediaPeriodId(super.copyWithWindowSequenceNumber(windowSequenceNumber)); + } } /**