From 692b7a674a6214ac26f4abef0da38ebc8c53223b Mon Sep 17 00:00:00 2001 From: falhassen Date: Thu, 12 Apr 2018 09:23:32 -0700 Subject: [PATCH] Automated g4 rollback of changelist 190906020. *** Reason for rollback *** Breaks looping. *** Original change description *** Automated g4 rollback of changelist 190628272. *** Reason for rollback *** b/76391022 was caused by a timestamp correction in StabilizableSimpleExoPlayer which will be fixed with this CL. *** Original change description *** Automated g4 rollback of changelist 189570277. *** Reason for rollback *** causes b/76391022, motion still playback in Photos is broken *** Original change description *** Used fixed time frame in clipping media period. Currently, whenever the clipping is updated, we... *** ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=192621199 --- .../android/exoplayer2/MediaPeriodHolder.java | 9 +- .../source/ClippingMediaPeriod.java | 105 +++++----- .../source/ClippingMediaSource.java | 184 ++++-------------- .../source/ClippingMediaSourceTest.java | 6 +- 4 files changed, 89 insertions(+), 215 deletions(-) diff --git a/library/core/src/main/java/com/google/android/exoplayer2/MediaPeriodHolder.java b/library/core/src/main/java/com/google/android/exoplayer2/MediaPeriodHolder.java index 2f71d0d547..7f09c63db5 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/MediaPeriodHolder.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/MediaPeriodHolder.java @@ -83,12 +83,9 @@ import com.google.android.exoplayer2.util.Assertions; mayRetainStreamFlags = new boolean[rendererCapabilities.length]; MediaPeriod mediaPeriod = mediaSource.createPeriod(info.id, allocator); if (info.endPositionUs != C.TIME_END_OF_SOURCE) { - mediaPeriod = - new ClippingMediaPeriod( - mediaPeriod, - /* enableInitialDiscontinuity= */ true, - /* startUs= */ 0, - info.endPositionUs); + ClippingMediaPeriod clippingMediaPeriod = new ClippingMediaPeriod(mediaPeriod, true); + clippingMediaPeriod.setClipping(0, info.endPositionUs); + mediaPeriod = clippingMediaPeriod; } this.mediaPeriod = mediaPeriod; } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/ClippingMediaPeriod.java b/library/core/src/main/java/com/google/android/exoplayer2/source/ClippingMediaPeriod.java index c078053110..98bd7daaec 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/ClippingMediaPeriod.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/ClippingMediaPeriod.java @@ -23,7 +23,6 @@ import com.google.android.exoplayer2.decoder.DecoderInputBuffer; import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.MimeTypes; -import com.google.android.exoplayer2.util.Util; import java.io.IOException; /** @@ -44,36 +43,35 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb /* package */ long endUs; /** - * Creates a new clipping media period that provides a clipped view of the specified {@link - * MediaPeriod}'s sample streams. - * - *

If the start point is guaranteed to be a key frame, pass {@code false} to {@code + * Creates a new clipping media period that provides a clipped view of the specified + * {@link MediaPeriod}'s sample streams. + *

+ * The clipping start/end positions must be specified by calling {@link #setClipping(long, long)} + * on the playback thread before preparation completes. + *

+ * If the start point is guaranteed to be a key frame, pass {@code false} to {@code * enableInitialPositionDiscontinuity} to suppress an initial discontinuity when the period is * first read from. * * @param mediaPeriod The media period to clip. * @param enableInitialDiscontinuity Whether the initial discontinuity should be enabled. - * @param startUs The clipping start time, in microseconds. - * @param endUs The clipping end time, in microseconds, or {@link C#TIME_END_OF_SOURCE} to - * indicate the end of the period. */ - public ClippingMediaPeriod( - MediaPeriod mediaPeriod, boolean enableInitialDiscontinuity, long startUs, long endUs) { + public ClippingMediaPeriod(MediaPeriod mediaPeriod, boolean enableInitialDiscontinuity) { this.mediaPeriod = mediaPeriod; sampleStreams = new ClippingSampleStream[0]; - pendingInitialDiscontinuityPositionUs = enableInitialDiscontinuity ? startUs : C.TIME_UNSET; - this.startUs = startUs; - this.endUs = endUs; + pendingInitialDiscontinuityPositionUs = enableInitialDiscontinuity ? 0 : C.TIME_UNSET; + startUs = C.TIME_UNSET; + endUs = C.TIME_UNSET; } /** - * Updates the clipping start/end times for this period, in microseconds. + * Sets the clipping start/end times for this period, in microseconds. * * @param startUs The clipping start time, in microseconds. * @param endUs The clipping end time, in microseconds, or {@link C#TIME_END_OF_SOURCE} to * indicate the end of the period. */ - public void updateClipping(long startUs, long endUs) { + public void setClipping(long startUs, long endUs) { this.startUs = startUs; this.endUs = endUs; } @@ -81,7 +79,7 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb @Override public void prepare(MediaPeriod.Callback callback, long positionUs) { this.callback = callback; - mediaPeriod.prepare(this, positionUs); + mediaPeriod.prepare(this, startUs + positionUs); } @Override @@ -103,19 +101,13 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb sampleStreams[i] = (ClippingSampleStream) streams[i]; childStreams[i] = sampleStreams[i] != null ? sampleStreams[i].childStream : null; } - long enablePositionUs = - mediaPeriod.selectTracks( - selections, mayRetainStreamFlags, childStreams, streamResetFlags, positionUs); - pendingInitialDiscontinuityPositionUs = - isPendingInitialDiscontinuity() - && positionUs == startUs - && shouldKeepInitialDiscontinuity(startUs, selections) - ? enablePositionUs - : C.TIME_UNSET; - Assertions.checkState( - enablePositionUs == positionUs - || (enablePositionUs >= startUs - && (endUs == C.TIME_END_OF_SOURCE || enablePositionUs <= endUs))); + long enablePositionUs = mediaPeriod.selectTracks(selections, mayRetainStreamFlags, + childStreams, streamResetFlags, positionUs + startUs) - startUs; + pendingInitialDiscontinuityPositionUs = isPendingInitialDiscontinuity() && positionUs == 0 + && shouldKeepInitialDiscontinuity(startUs, selections) ? enablePositionUs : C.TIME_UNSET; + Assertions.checkState(enablePositionUs == positionUs + || (enablePositionUs >= 0 + && (endUs == C.TIME_END_OF_SOURCE || startUs + enablePositionUs <= endUs))); for (int i = 0; i < streams.length; i++) { if (childStreams[i] == null) { sampleStreams[i] = null; @@ -129,12 +121,12 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb @Override public void discardBuffer(long positionUs, boolean toKeyframe) { - mediaPeriod.discardBuffer(positionUs, toKeyframe); + mediaPeriod.discardBuffer(positionUs + startUs, toKeyframe); } @Override public void reevaluateBuffer(long positionUs) { - mediaPeriod.reevaluateBuffer(positionUs); + mediaPeriod.reevaluateBuffer(positionUs + startUs); } @Override @@ -152,7 +144,7 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb } Assertions.checkState(discontinuityUs >= startUs); Assertions.checkState(endUs == C.TIME_END_OF_SOURCE || discontinuityUs <= endUs); - return discontinuityUs; + return discontinuityUs - startUs; } @Override @@ -162,7 +154,7 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb || (endUs != C.TIME_END_OF_SOURCE && bufferedPositionUs >= endUs)) { return C.TIME_END_OF_SOURCE; } - return bufferedPositionUs; + return Math.max(0, bufferedPositionUs - startUs); } @Override @@ -173,21 +165,23 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb sampleStream.clearSentEos(); } } - long seekUs = mediaPeriod.seekToUs(positionUs); + long offsetPositionUs = positionUs + startUs; + long seekUs = mediaPeriod.seekToUs(offsetPositionUs); Assertions.checkState( - seekUs == positionUs + seekUs == offsetPositionUs || (seekUs >= startUs && (endUs == C.TIME_END_OF_SOURCE || seekUs <= endUs))); - return seekUs; + return seekUs - startUs; } @Override public long getAdjustedSeekPositionUs(long positionUs, SeekParameters seekParameters) { - if (positionUs == startUs) { + if (positionUs == 0) { // Never adjust seeks to the start of the clipped view. - return startUs; + return 0; } - SeekParameters clippedSeekParameters = clipSeekParameters(positionUs, seekParameters); - return mediaPeriod.getAdjustedSeekPositionUs(positionUs, clippedSeekParameters); + long offsetPositionUs = positionUs + startUs; + SeekParameters clippedSeekParameters = clipSeekParameters(offsetPositionUs, seekParameters); + return mediaPeriod.getAdjustedSeekPositionUs(offsetPositionUs, clippedSeekParameters) - startUs; } @Override @@ -197,18 +191,19 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb || (endUs != C.TIME_END_OF_SOURCE && nextLoadPositionUs >= endUs)) { return C.TIME_END_OF_SOURCE; } - return nextLoadPositionUs; + return nextLoadPositionUs - startUs; } @Override public boolean continueLoading(long positionUs) { - return mediaPeriod.continueLoading(positionUs); + return mediaPeriod.continueLoading(positionUs + startUs); } // MediaPeriod.Callback implementation. @Override public void onPrepared(MediaPeriod mediaPeriod) { + Assertions.checkState(startUs != C.TIME_UNSET && endUs != C.TIME_UNSET); callback.onPrepared(this); } @@ -221,20 +216,17 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb return pendingInitialDiscontinuityPositionUs != C.TIME_UNSET; } - private SeekParameters clipSeekParameters(long positionUs, SeekParameters seekParameters) { - long toleranceBeforeUs = - Util.constrainValue( - seekParameters.toleranceBeforeUs, /* min= */ 0, /* max= */ positionUs - startUs); - long toleranceAfterUs = - Util.constrainValue( - seekParameters.toleranceAfterUs, - /* min= */ 0, - /* max= */ endUs == C.TIME_END_OF_SOURCE ? Long.MAX_VALUE : endUs - positionUs); - if (toleranceBeforeUs == seekParameters.toleranceBeforeUs - && toleranceAfterUs == seekParameters.toleranceAfterUs) { + private SeekParameters clipSeekParameters(long offsetPositionUs, SeekParameters seekParameters) { + long toleranceBeforeMs = Math.min(offsetPositionUs - startUs, seekParameters.toleranceBeforeUs); + long toleranceAfterMs = + endUs == C.TIME_END_OF_SOURCE + ? seekParameters.toleranceAfterUs + : Math.min(endUs - offsetPositionUs, seekParameters.toleranceAfterUs); + if (toleranceBeforeMs == seekParameters.toleranceBeforeUs + && toleranceAfterMs == seekParameters.toleranceAfterUs) { return seekParameters; } else { - return new SeekParameters(toleranceBeforeUs, toleranceAfterUs); + return new SeekParameters(toleranceBeforeMs, toleranceAfterMs); } } @@ -318,6 +310,9 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb sentEos = true; return C.RESULT_BUFFER_READ; } + if (result == C.RESULT_BUFFER_READ && !buffer.isEndOfStream()) { + buffer.timeUs -= startUs; + } return result; } @@ -326,7 +321,7 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb if (isPendingInitialDiscontinuity()) { return C.RESULT_NOTHING_READ; } - return childStream.skipData(positionUs); + return childStream.skipData(startUs + positionUs); } } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/ClippingMediaSource.java b/library/core/src/main/java/com/google/android/exoplayer2/source/ClippingMediaSource.java index f633dd8f15..6c62329820 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/ClippingMediaSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/ClippingMediaSource.java @@ -76,20 +76,14 @@ public final class ClippingMediaSource extends CompositeMediaSource { private final long startUs; private final long endUs; private final boolean enableInitialDiscontinuity; - private final boolean allowDynamicClippingUpdates; - private final boolean relativeToDefaultPosition; private final ArrayList mediaPeriods; - private final Timeline.Window window; - private @Nullable Object manifest; - private ClippingTimeline clippingTimeline; private IllegalClippingException clippingError; private long periodStartUs; private long periodEndUs; /** - * Creates a new clipping source that wraps the specified source and provides samples between the - * specified start and end position. + * Creates a new clipping source that wraps the specified source. * * @param mediaSource The single-period source to wrap. * @param startPositionUs The start position within {@code mediaSource}'s window at which to start @@ -101,62 +95,7 @@ public final class ClippingMediaSource extends CompositeMediaSource { * being clipped. */ public ClippingMediaSource(MediaSource mediaSource, long startPositionUs, long endPositionUs) { - this( - mediaSource, - startPositionUs, - endPositionUs, - /* enableInitialDiscontinuity= */ true, - /* allowDynamicClippingUpdates= */ false, - /* relativeToDefaultPosition= */ false); - } - - /** - * Creates a new clipping source that wraps the specified source and provides samples between the - * specified start and end position. - * - * @param mediaSource The single-period source to wrap. - * @param startPositionUs The start position within {@code mediaSource}'s window at which to start - * providing samples, in microseconds. - * @param endPositionUs The end position within {@code mediaSource}'s window at which to stop - * providing samples, in microseconds. Specify {@link C#TIME_END_OF_SOURCE} to provide samples - * from the specified start point up to the end of the source. Specifying a position that - * exceeds the {@code mediaSource}'s duration will also result in the end of the source not - * being clipped. - * @param enableInitialDiscontinuity Whether the initial discontinuity should be enabled. - */ - // TODO: remove this when the new API is public. - @Deprecated - public ClippingMediaSource( - MediaSource mediaSource, - long startPositionUs, - long endPositionUs, - boolean enableInitialDiscontinuity) { - this( - mediaSource, - startPositionUs, - endPositionUs, - enableInitialDiscontinuity, - /* allowDynamicClippingUpdates= */ false, - /* relativeToDefaultPosition= */ false); - } - - /** - * Creates a new clipping source that wraps the specified source and provides samples from the - * default position for the specified duration. - * - * @param mediaSource The single-period source to wrap. - * @param durationUs The duration from the default position in the window in {@code mediaSource}'s - * timeline at which to stop providing samples. Specifying a duration that exceeds the {@code - * mediaSource}'s duration will result in the end of the source not being clipped. - */ - public ClippingMediaSource(MediaSource mediaSource, long durationUs) { - this( - mediaSource, - /* startPositionUs= */ 0, - /* endPositionUs= */ durationUs, - /* enableInitialDiscontinuity= */ true, - /* allowDynamicClippingUpdates= */ false, - /* relativeToDefaultPosition= */ true); + this(mediaSource, startPositionUs, endPositionUs, true); } /** @@ -166,48 +105,27 @@ public final class ClippingMediaSource extends CompositeMediaSource { * enableInitialPositionDiscontinuity} to suppress an initial discontinuity when a period is first * read from. * - *

For live streams, if the clipping positions should move with the live window, pass {@code - * true} to {@code allowDynamicClippingUpdates}. Otherwise, the live stream ends when the playback - * reaches {@code endPositionUs} in the last reported live window at the time a media period was - * created. - * * @param mediaSource The single-period source to wrap. - * @param startPositionUs The start position at which to start providing samples, in microseconds. - * If {@code relativeToDefaultPosition} is {@code false}, this position is relative to the - * start of the window in {@code mediaSource}'s timeline. If {@code relativeToDefaultPosition} - * is {@code true}, this position is relative to the default position in the window in {@code - * mediaSource}'s timeline. - * @param endPositionUs The end position at which to stop providing samples, in microseconds. - * Specify {@link C#TIME_END_OF_SOURCE} to provide samples from the specified start point up - * to the end of the source. Specifying a position that exceeds the {@code mediaSource}'s - * duration will also result in the end of the source not being clipped. If {@code - * relativeToDefaultPosition} is {@code false}, the specified position is relative to the - * start of the window in {@code mediaSource}'s timeline. If {@code relativeToDefaultPosition} - * is {@code true}, this position is relative to the default position in the window in {@code - * mediaSource}'s timeline. + * @param startPositionUs The start position within {@code mediaSource}'s timeline at which to + * start providing samples, in microseconds. + * @param endPositionUs The end position within {@code mediaSource}'s timeline at which to stop + * providing samples, in microseconds. Specify {@link C#TIME_END_OF_SOURCE} to provide samples + * from the specified start point up to the end of the source. Specifying a position that + * exceeds the {@code mediaSource}'s duration will also result in the end of the source not + * being clipped. * @param enableInitialDiscontinuity Whether the initial discontinuity should be enabled. - * @param allowDynamicClippingUpdates Whether the clipping of active media periods moves with a - * live window. If {@code false}, playback ends when it reaches {@code endPositionUs} in the - * last reported live window at the time a media period was created. - * @param relativeToDefaultPosition Whether {@code startPositionUs} and {@code endPositionUs} are - * relative to the default position in the window in {@code mediaSource}'s timeline. */ public ClippingMediaSource( MediaSource mediaSource, long startPositionUs, long endPositionUs, - boolean enableInitialDiscontinuity, - boolean allowDynamicClippingUpdates, - boolean relativeToDefaultPosition) { + boolean enableInitialDiscontinuity) { Assertions.checkArgument(startPositionUs >= 0); this.mediaSource = Assertions.checkNotNull(mediaSource); startUs = startPositionUs; endUs = endPositionUs; this.enableInitialDiscontinuity = enableInitialDiscontinuity; - this.allowDynamicClippingUpdates = allowDynamicClippingUpdates; - this.relativeToDefaultPosition = relativeToDefaultPosition; mediaPeriods = new ArrayList<>(); - window = new Timeline.Window(); } @Override @@ -228,11 +146,9 @@ public final class ClippingMediaSource extends CompositeMediaSource { public MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator) { ClippingMediaPeriod mediaPeriod = new ClippingMediaPeriod( - mediaSource.createPeriod(id, allocator), - enableInitialDiscontinuity, - periodStartUs, - periodEndUs); + mediaSource.createPeriod(id, allocator), enableInitialDiscontinuity); mediaPeriods.add(mediaPeriod); + mediaPeriod.setClipping(periodStartUs, periodEndUs); return mediaPeriod; } @@ -240,16 +156,12 @@ public final class ClippingMediaSource extends CompositeMediaSource { public void releasePeriod(MediaPeriod mediaPeriod) { Assertions.checkState(mediaPeriods.remove(mediaPeriod)); mediaSource.releasePeriod(((ClippingMediaPeriod) mediaPeriod).mediaPeriod); - if (mediaPeriods.isEmpty() && !allowDynamicClippingUpdates) { - refreshClippedTimeline(clippingTimeline.timeline); - } } @Override public void releaseSourceInternal() { super.releaseSourceInternal(); clippingError = null; - clippingTimeline = null; } @Override @@ -258,47 +170,25 @@ public final class ClippingMediaSource extends CompositeMediaSource { if (clippingError != null) { return; } - this.manifest = manifest; - refreshClippedTimeline(timeline); - } - - private void refreshClippedTimeline(Timeline timeline) { - long windowStartUs; - long windowEndUs; - timeline.getWindow(/* windowIndex= */ 0, window); - long windowPositionInPeriodUs = window.getPositionInFirstPeriodUs(); - if (clippingTimeline == null || mediaPeriods.isEmpty() || allowDynamicClippingUpdates) { - windowStartUs = startUs; - windowEndUs = endUs; - if (relativeToDefaultPosition) { - long windowDefaultPositionUs = window.getDefaultPositionUs(); - windowStartUs += windowDefaultPositionUs; - windowEndUs += windowDefaultPositionUs; - } - periodStartUs = windowPositionInPeriodUs + windowStartUs; - periodEndUs = - endUs == C.TIME_END_OF_SOURCE - ? C.TIME_END_OF_SOURCE - : windowPositionInPeriodUs + windowEndUs; - int count = mediaPeriods.size(); - for (int i = 0; i < count; i++) { - mediaPeriods.get(i).updateClipping(periodStartUs, periodEndUs); - } - } else { - // Keep window fixed at previous period position. - windowStartUs = periodStartUs - windowPositionInPeriodUs; - windowEndUs = - endUs == C.TIME_END_OF_SOURCE - ? C.TIME_END_OF_SOURCE - : periodEndUs - windowPositionInPeriodUs; - } + ClippingTimeline clippingTimeline; try { - clippingTimeline = new ClippingTimeline(timeline, windowStartUs, windowEndUs); + clippingTimeline = new ClippingTimeline(timeline, startUs, endUs); } catch (IllegalClippingException e) { clippingError = e; return; } refreshSourceInfo(clippingTimeline, manifest); + long windowPositionInPeriodUs = + timeline + .getWindow(/* windowIndex= */ 0, new Timeline.Window()) + .getPositionInFirstPeriodUs(); + periodStartUs = windowPositionInPeriodUs + startUs; + periodEndUs = + endUs == C.TIME_END_OF_SOURCE ? C.TIME_END_OF_SOURCE : windowPositionInPeriodUs + endUs; + int count = mediaPeriods.size(); + for (int i = 0; i < count; i++) { + mediaPeriods.get(i).setClipping(periodStartUs, periodEndUs); + } } @Override @@ -322,7 +212,6 @@ public final class ClippingMediaSource extends CompositeMediaSource { private final long startUs; private final long endUs; private final long durationUs; - private final boolean isDynamic; /** * Creates a new clipping timeline that wraps the specified timeline. @@ -340,8 +229,7 @@ public final class ClippingMediaSource extends CompositeMediaSource { throw new IllegalClippingException(IllegalClippingException.REASON_INVALID_PERIOD_COUNT); } Window window = timeline.getWindow(0, new Window(), false); - startUs = Math.max(0, startUs); - long resolvedEndUs = endUs == C.TIME_END_OF_SOURCE ? window.durationUs : Math.max(0, endUs); + long resolvedEndUs = endUs == C.TIME_END_OF_SOURCE ? window.durationUs : endUs; if (window.durationUs != C.TIME_UNSET) { if (resolvedEndUs > window.durationUs) { resolvedEndUs = window.durationUs; @@ -356,20 +244,14 @@ public final class ClippingMediaSource extends CompositeMediaSource { this.startUs = startUs; this.endUs = resolvedEndUs; durationUs = resolvedEndUs == C.TIME_UNSET ? C.TIME_UNSET : (resolvedEndUs - startUs); - isDynamic = - window.isDynamic - && (resolvedEndUs == C.TIME_UNSET - || (window.durationUs != C.TIME_UNSET && resolvedEndUs == window.durationUs)); } @Override public Window getWindow( - int windowIndex, Window window, boolean setTag, long defaultPositionProjectionUs) { - timeline.getWindow( - /* windowIndex= */ 0, window, setTag, /* defaultPositionProjectionUs= */ 0); - window.positionInFirstPeriodUs += startUs; + int windowIndex, Window window, boolean setIds, long defaultPositionProjectionUs) { + timeline.getWindow(/* windowIndex= */ 0, window, setIds, defaultPositionProjectionUs); + window.positionInFirstPeriodUs = 0; window.durationUs = durationUs; - window.isDynamic = isDynamic; if (window.defaultPositionUs != C.TIME_UNSET) { window.defaultPositionUs = Math.max(window.defaultPositionUs, startUs); window.defaultPositionUs = endUs == C.TIME_UNSET ? window.defaultPositionUs @@ -389,11 +271,11 @@ public final class ClippingMediaSource extends CompositeMediaSource { @Override public Period getPeriod(int periodIndex, Period period, boolean setIds) { timeline.getPeriod(/* periodIndex= */ 0, period, setIds); - long positionInClippedWindowUs = period.getPositionInWindowUs() - startUs; - long periodDurationUs = - durationUs == C.TIME_UNSET ? C.TIME_UNSET : durationUs - positionInClippedWindowUs; return period.set( - period.id, period.uid, /* windowIndex= */ 0, periodDurationUs, positionInClippedWindowUs); + period.id, period.uid, /* windowIndex= */ 0, durationUs, /* positionInWindowUs= */ 0); } + } + } + diff --git a/library/core/src/test/java/com/google/android/exoplayer2/source/ClippingMediaSourceTest.java b/library/core/src/test/java/com/google/android/exoplayer2/source/ClippingMediaSourceTest.java index e853529ae6..883d41eea5 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/source/ClippingMediaSourceTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/source/ClippingMediaSourceTest.java @@ -99,7 +99,7 @@ public final class ClippingMediaSourceTest { assertThat(clippedTimeline.getWindow(0, window).getDurationUs()) .isEqualTo(TEST_PERIOD_DURATION_US - TEST_CLIP_AMOUNT_US); assertThat(clippedTimeline.getPeriod(0, period).getDurationUs()) - .isEqualTo(TEST_PERIOD_DURATION_US); + .isEqualTo(TEST_PERIOD_DURATION_US - TEST_CLIP_AMOUNT_US); } @Test @@ -128,7 +128,7 @@ public final class ClippingMediaSourceTest { assertThat(clippedTimeline.getWindow(0, window).getDurationUs()) .isEqualTo(TEST_PERIOD_DURATION_US - TEST_CLIP_AMOUNT_US * 3); assertThat(clippedTimeline.getPeriod(0, period).getDurationUs()) - .isEqualTo(TEST_PERIOD_DURATION_US - TEST_CLIP_AMOUNT_US * 2); + .isEqualTo(TEST_PERIOD_DURATION_US - TEST_CLIP_AMOUNT_US * 3); } @Test @@ -171,7 +171,7 @@ public final class ClippingMediaSourceTest { assertThat(clippedTimeline.getWindow(0, window).getDurationUs()) .isEqualTo(TEST_PERIOD_DURATION_US - TEST_CLIP_AMOUNT_US * 3); assertThat(clippedTimeline.getPeriod(0, period).getDurationUs()) - .isEqualTo(TEST_PERIOD_DURATION_US - TEST_CLIP_AMOUNT_US * 2); + .isEqualTo(TEST_PERIOD_DURATION_US - TEST_CLIP_AMOUNT_US * 3); } @Test