From e33278436f5536df0e2eb2111245c4e7c42d0e18 Mon Sep 17 00:00:00 2001 From: olly Date: Wed, 29 Jun 2016 03:45:24 -0700 Subject: [PATCH] Misc bugfixes. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=126175948 --- .../exoplayer/ExoPlayerImplInternal.java | 6 +--- .../android/exoplayer/MultiSampleSource.java | 19 +++++++--- .../extractor/ExtractorSampleSource.java | 28 ++++++++------- .../android/exoplayer/upstream/Loader.java | 35 +++++++++++++------ 4 files changed, 54 insertions(+), 34 deletions(-) diff --git a/library/src/main/java/com/google/android/exoplayer/ExoPlayerImplInternal.java b/library/src/main/java/com/google/android/exoplayer/ExoPlayerImplInternal.java index 97e0a2d21a..f0abf32c2a 100644 --- a/library/src/main/java/com/google/android/exoplayer/ExoPlayerImplInternal.java +++ b/library/src/main/java/com/google/android/exoplayer/ExoPlayerImplInternal.java @@ -284,10 +284,6 @@ import java.util.ArrayList; } } - private boolean isReadyOrEnded(TrackRenderer renderer) { - return renderer.isReady() || renderer.isEnded(); - } - private void setSourceProviderInternal(SampleSourceProvider sourceProvider) { try { resetInternal(); @@ -399,7 +395,7 @@ import java.util.ArrayList; allRenderersEnded = allRenderersEnded && renderer.isEnded(); // Determine whether the renderer is ready (or ended). If it's not, throw an error that's // preventing the renderer from making progress, if such an error exists. - boolean rendererReadyOrEnded = isReadyOrEnded(renderer); + boolean rendererReadyOrEnded = renderer.isReady() || renderer.isEnded(); if (!rendererReadyOrEnded) { renderer.maybeThrowStreamError(); } diff --git a/library/src/main/java/com/google/android/exoplayer/MultiSampleSource.java b/library/src/main/java/com/google/android/exoplayer/MultiSampleSource.java index df93e5f13c..7b10e6ee9f 100644 --- a/library/src/main/java/com/google/android/exoplayer/MultiSampleSource.java +++ b/library/src/main/java/com/google/android/exoplayer/MultiSampleSource.java @@ -107,13 +107,22 @@ public final class MultiSampleSource implements SampleSource, SampleSource.Callb @Override public long readDiscontinuity() { - for (SampleSource source : enabledSources) { - if (source.readDiscontinuity() != C.UNSET_TIME_US) { - // Children are not allowed to report discontinuities. + long positionUs = enabledSources[0].readDiscontinuity(); + if (positionUs != C.UNSET_TIME_US) { + // It must be possible to seek additional sources to the new position. + for (int i = 1; i < enabledSources.length; i++) { + if (enabledSources[i].seekToUs(positionUs) != positionUs) { + throw new IllegalStateException("Children seeked to different positions"); + } + } + } + // Additional sources are not allowed to report discontinuities. + for (int i = 1; i < enabledSources.length; i++) { + if (enabledSources[i].readDiscontinuity() != C.UNSET_TIME_US) { throw new IllegalStateException("Child reported discontinuity"); } } - return C.UNSET_TIME_US; + return positionUs; } @Override @@ -131,8 +140,8 @@ public final class MultiSampleSource implements SampleSource, SampleSource.Callb @Override public long seekToUs(long positionUs) { positionUs = enabledSources[0].seekToUs(positionUs); + // Additional sources must seek to the same position. for (int i = 1; i < enabledSources.length; i++) { - // Additional sources must seek to the same position. if (enabledSources[i].seekToUs(positionUs) != positionUs) { throw new IllegalStateException("Children seeked to different positions"); } diff --git a/library/src/main/java/com/google/android/exoplayer/extractor/ExtractorSampleSource.java b/library/src/main/java/com/google/android/exoplayer/extractor/ExtractorSampleSource.java index b44db49f1c..08b66b5600 100644 --- a/library/src/main/java/com/google/android/exoplayer/extractor/ExtractorSampleSource.java +++ b/library/src/main/java/com/google/android/exoplayer/extractor/ExtractorSampleSource.java @@ -379,7 +379,10 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu loadCondition.open(); } if (seenFirstTrackSelection ? newStreams.length > 0 : positionUs != 0) { - seekToUs(positionUs); + long seekPositionUs = seekToUs(positionUs); + if (seekPositionUs != positionUs) { + notifyReset = true; + } } } seenFirstTrackSelection = true; @@ -422,7 +425,6 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu // Treat all seeks into non-seekable media as being to t=0. positionUs = seekMap.isSeekable() ? positionUs : 0; lastSeekPositionUs = positionUs; - notifyReset = true; // If we're not pending a reset, see if we can seek within the sample queues. boolean seekInsideBuffer = !isPendingReset(); for (int i = 0; seekInsideBuffer && i < sampleQueues.length; i++) { @@ -434,6 +436,7 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu if (!seekInsideBuffer) { restartFrom(positionUs); } + notifyReset = false; return positionUs; } @@ -455,7 +458,15 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu } /* package */ void maybeThrowError() throws IOException { - loader.maybeThrowError(); + int minRetryCount = minLoadableRetryCount; + if (minRetryCount == MIN_RETRY_COUNT_DEFAULT_FOR_MEDIA) { + // We assume on-demand before we're prepared. + minRetryCount = !prepared || length != C.LENGTH_UNBOUNDED + || (seekMap != null && seekMap.getDurationUs() != C.UNSET_TIME_US) + ? DEFAULT_MIN_LOADABLE_RETRY_COUNT_ON_DEMAND + : DEFAULT_MIN_LOADABLE_RETRY_COUNT_LIVE; + } + loader.maybeThrowError(minRetryCount); } /* package */ int readData(int track, FormatHolder formatHolder, DecoderInputBuffer buffer) { @@ -591,16 +602,7 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu pendingResetPositionUs = C.UNSET_TIME_US; } extractedSamplesCountAtStartOfLoad = getExtractedSamplesCount(); - - int minRetryCount = minLoadableRetryCount; - if (minRetryCount == MIN_RETRY_COUNT_DEFAULT_FOR_MEDIA) { - // We assume on-demand before we're prepared. - minRetryCount = !prepared || (length != C.LENGTH_UNBOUNDED - || (seekMap != null && seekMap.getDurationUs() != C.UNSET_TIME_US)) - ? DEFAULT_MIN_LOADABLE_RETRY_COUNT_ON_DEMAND - : DEFAULT_MIN_LOADABLE_RETRY_COUNT_LIVE; - } - loader.startLoading(loadable, this, minRetryCount); + loader.startLoading(loadable, this, 0); } private void configureRetry(ExtractingLoadable loadable) { diff --git a/library/src/main/java/com/google/android/exoplayer/upstream/Loader.java b/library/src/main/java/com/google/android/exoplayer/upstream/Loader.java index 3599fb6b88..f7526ea785 100644 --- a/library/src/main/java/com/google/android/exoplayer/upstream/Loader.java +++ b/library/src/main/java/com/google/android/exoplayer/upstream/Loader.java @@ -154,17 +154,17 @@ public final class Loader { * * @param loadable The {@link Loadable} to load. * @param callback A callback to invoke when the load ends. - * @param minRetryCount The minimum number of times the load must be retried before + * @param defaultMinRetryCount The minimum number of times the load must be retried before * {@link #maybeThrowError()} will propagate an error. * @throws IllegalStateException If the calling thread does not have an associated {@link Looper}. * @return {@link SystemClock#elapsedRealtime} when the load started. */ public long startLoading(T loadable, Callback callback, - int minRetryCount) { + int defaultMinRetryCount) { Looper looper = Looper.myLooper(); Assertions.checkState(looper != null); long startTimeMs = SystemClock.elapsedRealtime(); - new LoadTask<>(looper, loadable, callback, minRetryCount, startTimeMs).start(0); + new LoadTask<>(looper, loadable, callback, defaultMinRetryCount, startTimeMs).start(0); return startTimeMs; } @@ -179,16 +179,29 @@ public final class Loader { /** * If a fatal error has been encountered, or if the current {@link Loadable} has incurred a number - * of errors greater than its minimum number of retries and if the load is currently backed off, - * then an error is thrown. Else does nothing. + * of errors greater than its default minimum number of retries and if the load is currently + * backed off, then an error is thrown. Else does nothing. * * @throws IOException The error. */ public void maybeThrowError() throws IOException { + maybeThrowError(Integer.MIN_VALUE); + } + + /** + * If a fatal error has been encountered, or if the current {@link Loadable} has incurred a number + * of errors greater than the specified minimum number of retries and if the load is currently + * backed off, then an error is thrown. Else does nothing. + * + * @param minRetryCount A minimum retry count that must be exceeded. + * @throws IOException The error. + */ + public void maybeThrowError(int minRetryCount) throws IOException { if (fatalError != null) { throw fatalError; } else if (currentTask != null) { - currentTask.maybeThrowError(); + currentTask.maybeThrowError(minRetryCount == Integer.MIN_VALUE + ? currentTask.defaultMinRetryCount : minRetryCount); } } @@ -220,7 +233,7 @@ public final class Loader { private final T loadable; private final Loader.Callback callback; - private final int minRetryCount; + public final int defaultMinRetryCount; private final long startTimeMs; private IOException currentError; @@ -229,16 +242,16 @@ public final class Loader { private volatile Thread executorThread; private volatile boolean released; - public LoadTask(Looper looper, T loadable, Loader.Callback callback, int minRetryCount, - long startTimeMs) { + public LoadTask(Looper looper, T loadable, Loader.Callback callback, + int defaultMinRetryCount, long startTimeMs) { super(looper); this.loadable = loadable; this.callback = callback; - this.minRetryCount = minRetryCount; + this.defaultMinRetryCount = defaultMinRetryCount; this.startTimeMs = startTimeMs; } - public void maybeThrowError() throws IOException { + public void maybeThrowError(int minRetryCount) throws IOException { if (currentError != null && errorCount > minRetryCount) { throw currentError; }