From 82b72c93584edba745748db608758db55eb41daa Mon Sep 17 00:00:00 2001 From: byungh Date: Tue, 27 Mar 2018 09:48:34 -0700 Subject: [PATCH] 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 move the time frame of the clipped period to start at 0. This causes problems when we are already playing this period and the renderer position does no longer match the stream positions. This change keeps the time frame of the clipped media period as it is and instead specifies the offset of the window in the period. *** ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=190628272 --- .../android/exoplayer2/MediaPeriodHolder.java | 9 +- .../source/ClippingMediaPeriod.java | 97 +++++++++---------- .../source/ClippingMediaSource.java | 20 ++-- .../source/ClippingMediaSourceTest.java | 6 +- 4 files changed, 62 insertions(+), 70 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 c888afdd14f..43036b154b9 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 @@ -81,12 +81,9 @@ public MediaPeriodHolder( 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 67616cb6c90..98bd7daaecc 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 @@ -43,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; } @@ -80,7 +79,7 @@ public void updateClipping(long startUs, long endUs) { @Override public void prepare(MediaPeriod.Callback callback, long positionUs) { this.callback = callback; - mediaPeriod.prepare(this, positionUs); + mediaPeriod.prepare(this, startUs + positionUs); } @Override @@ -102,19 +101,13 @@ public long selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamF 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; @@ -128,12 +121,12 @@ && shouldKeepInitialDiscontinuity(startUs, selections) @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 @@ -151,7 +144,7 @@ public long readDiscontinuity() { } Assertions.checkState(discontinuityUs >= startUs); Assertions.checkState(endUs == C.TIME_END_OF_SOURCE || discontinuityUs <= endUs); - return discontinuityUs; + return discontinuityUs - startUs; } @Override @@ -161,7 +154,7 @@ public long getBufferedPositionUs() { || (endUs != C.TIME_END_OF_SOURCE && bufferedPositionUs >= endUs)) { return C.TIME_END_OF_SOURCE; } - return bufferedPositionUs; + return Math.max(0, bufferedPositionUs - startUs); } @Override @@ -172,21 +165,23 @@ public long seekToUs(long positionUs) { 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 @@ -196,18 +191,19 @@ public long getNextLoadPositionUs() { || (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); } @@ -220,17 +216,17 @@ public void onContinueLoadingRequested(MediaPeriod source) { return pendingInitialDiscontinuityPositionUs != C.TIME_UNSET; } - private SeekParameters clipSeekParameters(long positionUs, SeekParameters seekParameters) { - long toleranceBeforeUs = Math.min(positionUs - startUs, seekParameters.toleranceBeforeUs); - long 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 - positionUs, seekParameters.toleranceAfterUs); - if (toleranceBeforeUs == seekParameters.toleranceBeforeUs - && toleranceAfterUs == 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); } } @@ -314,6 +310,9 @@ && getBufferedPositionUs() == C.TIME_END_OF_SOURCE))) { sentEos = true; return C.RESULT_BUFFER_READ; } + if (result == C.RESULT_BUFFER_READ && !buffer.isEndOfStream()) { + buffer.timeUs -= startUs; + } return result; } @@ -322,7 +321,7 @@ public int skipData(long positionUs) { 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 7c5e0e52efc..08719098c57 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 @@ -141,13 +141,10 @@ public void maybeThrowSourceInfoRefreshError() throws IOException { @Override public MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator) { - ClippingMediaPeriod mediaPeriod = - new ClippingMediaPeriod( - mediaSource.createPeriod(id, allocator), - enableInitialDiscontinuity, - periodStartUs, - periodEndUs); + ClippingMediaPeriod mediaPeriod = new ClippingMediaPeriod( + mediaSource.createPeriod(id, allocator), enableInitialDiscontinuity); mediaPeriods.add(mediaPeriod); + mediaPeriod.setClipping(periodStartUs, periodEndUs); return mediaPeriod; } @@ -186,7 +183,7 @@ protected void onChildSourceInfoRefreshed( 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).updateClipping(periodStartUs, periodEndUs); + mediaPeriods.get(i).setClipping(periodStartUs, periodEndUs); } } @@ -249,7 +246,7 @@ public ClippingTimeline(Timeline timeline, long startUs, long endUs) public Window getWindow(int windowIndex, Window window, boolean setIds, long defaultPositionProjectionUs) { timeline.getWindow(/* windowIndex= */ 0, window, setIds, defaultPositionProjectionUs); - window.positionInFirstPeriodUs += startUs; + window.positionInFirstPeriodUs = 0; window.durationUs = durationUs; if (window.defaultPositionUs != C.TIME_UNSET) { window.defaultPositionUs = Math.max(window.defaultPositionUs, startUs); @@ -270,11 +267,10 @@ public Window getWindow(int windowIndex, Window window, boolean setIds, @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 60282d582c7..1e135403ad1 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 void testClippingStart() throws IOException { 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 void testClippingStartAndEndInitial() throws IOException { 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 void testClippingStartAndEnd() throws IOException { 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