From 4f640bc62e713ba13ff97fdc543824665156a17a Mon Sep 17 00:00:00 2001 From: tonihei Date: Wed, 2 Oct 2019 16:43:26 +0100 Subject: [PATCH] Add SequencableLoader.isLoading This method allows the player to figure out whether we still have an ongoing load even if LoadControl.shouldContinueLoading returns false. PiperOrigin-RevId: 272445577 --- RELEASENOTES.md | 1 + .../android/exoplayer2/source/ClippingMediaPeriod.java | 5 +++++ .../exoplayer2/source/CompositeSequenceableLoader.java | 9 +++++++++ .../android/exoplayer2/source/MaskingMediaPeriod.java | 5 +++++ .../google/android/exoplayer2/source/MediaPeriod.java | 3 +++ .../android/exoplayer2/source/MergingMediaPeriod.java | 5 +++++ .../exoplayer2/source/ProgressiveMediaPeriod.java | 5 +++++ .../android/exoplayer2/source/SequenceableLoader.java | 3 +++ .../android/exoplayer2/source/SilenceMediaSource.java | 5 +++++ .../exoplayer2/source/SingleSampleMediaPeriod.java | 5 +++++ .../exoplayer2/source/chunk/ChunkSampleStream.java | 5 +++++ .../android/exoplayer2/util/ConditionVariable.java | 4 ++++ .../source/CompositeSequenceableLoaderTest.java | 5 +++++ .../android/exoplayer2/source/dash/DashMediaPeriod.java | 5 +++++ .../android/exoplayer2/source/hls/HlsMediaPeriod.java | 5 +++++ .../exoplayer2/source/hls/HlsSampleStreamWrapper.java | 5 +++++ .../exoplayer2/source/smoothstreaming/SsMediaPeriod.java | 5 +++++ .../exoplayer2/testutil/FakeAdaptiveMediaPeriod.java | 5 +++++ .../android/exoplayer2/testutil/FakeMediaPeriod.java | 5 +++++ 19 files changed, 90 insertions(+) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 83997fe3c7..2c46c34d21 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -91,6 +91,7 @@ ([#6476](https://github.com/google/ExoPlayer/issues/6476)). * Fail more explicitly when local-file Uris contain invalid parts (e.g. fragment) ([#6470](https://github.com/google/ExoPlayer/issues/6470)). +* Add `MediaPeriod.isLoading` to improve `Player.isLoading` state. ### 2.10.5 (2019-09-20) ### 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 d57dccd8fe..8aafb9a0e5 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 @@ -211,6 +211,11 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb return mediaPeriod.continueLoading(positionUs); } + @Override + public boolean isLoading() { + return mediaPeriod.isLoading(); + } + // MediaPeriod.Callback implementation. @Override diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/CompositeSequenceableLoader.java b/library/core/src/main/java/com/google/android/exoplayer2/source/CompositeSequenceableLoader.java index c41933b48b..b583705170 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/CompositeSequenceableLoader.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/CompositeSequenceableLoader.java @@ -83,4 +83,13 @@ public class CompositeSequenceableLoader implements SequenceableLoader { return madeProgress; } + @Override + public boolean isLoading() { + for (SequenceableLoader loader : loaders) { + if (loader.isLoading()) { + return true; + } + } + return false; + } } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/MaskingMediaPeriod.java b/library/core/src/main/java/com/google/android/exoplayer2/source/MaskingMediaPeriod.java index 344c4989eb..17ac6c0667 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/MaskingMediaPeriod.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/MaskingMediaPeriod.java @@ -211,6 +211,11 @@ public final class MaskingMediaPeriod implements MediaPeriod, MediaPeriod.Callba return mediaPeriod != null && mediaPeriod.continueLoading(positionUs); } + @Override + public boolean isLoading() { + return mediaPeriod != null && mediaPeriod.isLoading(); + } + @Override public void onContinueLoadingRequested(MediaPeriod source) { castNonNull(callback).onContinueLoadingRequested(this); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/MediaPeriod.java b/library/core/src/main/java/com/google/android/exoplayer2/source/MediaPeriod.java index 3f306c0c8a..2e2cf9caba 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/MediaPeriod.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/MediaPeriod.java @@ -231,6 +231,9 @@ public interface MediaPeriod extends SequenceableLoader { @Override boolean continueLoading(long positionUs); + /** Returns whether the media period is currently loading. */ + boolean isLoading(); + /** * Re-evaluates the buffer given the playback position. * diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/MergingMediaPeriod.java b/library/core/src/main/java/com/google/android/exoplayer2/source/MergingMediaPeriod.java index cafc052f34..afa25d6fce 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/MergingMediaPeriod.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/MergingMediaPeriod.java @@ -169,6 +169,11 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; } } + @Override + public boolean isLoading() { + return compositeSequenceableLoader.isLoading(); + } + @Override public long getNextLoadPositionUs() { return compositeSequenceableLoader.getNextLoadPositionUs(); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/ProgressiveMediaPeriod.java b/library/core/src/main/java/com/google/android/exoplayer2/source/ProgressiveMediaPeriod.java index 4af5bafdda..7ffc0faee6 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/ProgressiveMediaPeriod.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/ProgressiveMediaPeriod.java @@ -358,6 +358,11 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; return continuedLoading; } + @Override + public boolean isLoading() { + return loader.isLoading() && loadCondition.isOpen(); + } + @Override public long getNextLoadPositionUs() { return enabledTrackCount == 0 ? C.TIME_END_OF_SOURCE : getBufferedPositionUs(); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/SequenceableLoader.java b/library/core/src/main/java/com/google/android/exoplayer2/source/SequenceableLoader.java index 182f0f17cc..189c13ef0f 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/SequenceableLoader.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/SequenceableLoader.java @@ -60,6 +60,9 @@ public interface SequenceableLoader { */ boolean continueLoading(long positionUs); + /** Returns whether the loader is currently loading. */ + boolean isLoading(); + /** * Re-evaluates the buffer given the playback position. * diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/SilenceMediaSource.java b/library/core/src/main/java/com/google/android/exoplayer2/source/SilenceMediaSource.java index a950a95457..abaf33633e 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/SilenceMediaSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/SilenceMediaSource.java @@ -172,6 +172,11 @@ public final class SilenceMediaSource extends BaseMediaSource { return false; } + @Override + public boolean isLoading() { + return false; + } + @Override public void reevaluateBuffer(long positionUs) {} diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/SingleSampleMediaPeriod.java b/library/core/src/main/java/com/google/android/exoplayer2/source/SingleSampleMediaPeriod.java index 8d41fbc73f..a5d8266ef6 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/SingleSampleMediaPeriod.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/SingleSampleMediaPeriod.java @@ -172,6 +172,11 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; return true; } + @Override + public boolean isLoading() { + return loader.isLoading(); + } + @Override public long readDiscontinuity() { if (!notifiedReadingStarted) { diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkSampleStream.java b/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkSampleStream.java index 6817f294b2..61e2868725 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkSampleStream.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkSampleStream.java @@ -577,6 +577,11 @@ public class ChunkSampleStream implements SampleStream, S return true; } + @Override + public boolean isLoading() { + return loader.isLoading(); + } + @Override public long getNextLoadPositionUs() { if (isPendingReset()) { diff --git a/library/core/src/main/java/com/google/android/exoplayer2/util/ConditionVariable.java b/library/core/src/main/java/com/google/android/exoplayer2/util/ConditionVariable.java index 058a5d6dd2..c035c62a7e 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/util/ConditionVariable.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/util/ConditionVariable.java @@ -76,4 +76,8 @@ public final class ConditionVariable { return isOpen; } + /** Returns whether the condition is opened. */ + public synchronized boolean isOpen() { + return isOpen; + } } diff --git a/library/core/src/test/java/com/google/android/exoplayer2/source/CompositeSequenceableLoaderTest.java b/library/core/src/test/java/com/google/android/exoplayer2/source/CompositeSequenceableLoaderTest.java index 4a881d53b4..c996aadddb 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/source/CompositeSequenceableLoaderTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/source/CompositeSequenceableLoaderTest.java @@ -261,6 +261,11 @@ public final class CompositeSequenceableLoaderTest { return loaded; } + @Override + public boolean isLoading() { + return nextChunkDurationUs != 0; + } + @Override public void reevaluateBuffer(long positionUs) { // Do nothing. diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaPeriod.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaPeriod.java index d62474cb1b..bb8226e172 100644 --- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaPeriod.java +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaPeriod.java @@ -297,6 +297,11 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; return compositeSequenceableLoader.continueLoading(positionUs); } + @Override + public boolean isLoading() { + return compositeSequenceableLoader.isLoading(); + } + @Override public long getNextLoadPositionUs() { return compositeSequenceableLoader.getNextLoadPositionUs(); diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaPeriod.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaPeriod.java index 7d47cc43c6..b0b4c04b48 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaPeriod.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaPeriod.java @@ -359,6 +359,11 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper } } + @Override + public boolean isLoading() { + return compositeSequenceableLoader.isLoading(); + } + @Override public long getNextLoadPositionUs() { return compositeSequenceableLoader.getNextLoadPositionUs(); diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java index b87f83c336..58c275664b 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java @@ -663,6 +663,11 @@ import java.util.Set; return true; } + @Override + public boolean isLoading() { + return loader.isLoading(); + } + @Override public void reevaluateBuffer(long positionUs) { // Do nothing. diff --git a/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/SsMediaPeriod.java b/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/SsMediaPeriod.java index b3d950959a..42ac82e553 100644 --- a/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/SsMediaPeriod.java +++ b/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/SsMediaPeriod.java @@ -184,6 +184,11 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; return compositeSequenceableLoader.continueLoading(positionUs); } + @Override + public boolean isLoading() { + return compositeSequenceableLoader.isLoading(); + } + @Override public long getNextLoadPositionUs() { return compositeSequenceableLoader.getNextLoadPositionUs(); diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeAdaptiveMediaPeriod.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeAdaptiveMediaPeriod.java index 6d141fe04a..9c6fdc85cd 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeAdaptiveMediaPeriod.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeAdaptiveMediaPeriod.java @@ -138,6 +138,11 @@ public class FakeAdaptiveMediaPeriod extends FakeMediaPeriod return sequenceableLoader.continueLoading(positionUs); } + @Override + public boolean isLoading() { + return sequenceableLoader.isLoading(); + } + @Override protected SampleStream createSampleStream(TrackSelection trackSelection) { FakeChunkSource chunkSource = diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeMediaPeriod.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeMediaPeriod.java index d524d381fa..bcc96ef47e 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeMediaPeriod.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeMediaPeriod.java @@ -217,6 +217,11 @@ public class FakeMediaPeriod implements MediaPeriod { return false; } + @Override + public boolean isLoading() { + return false; + } + protected SampleStream createSampleStream(TrackSelection selection) { return new FakeSampleStream( selection.getSelectedFormat(), eventDispatcher, /* shouldOutputSample= */ true);