From 69d6f84159072bcaf465bae4ca9b52e59fa690ef Mon Sep 17 00:00:00 2001 From: tonihei Date: Mon, 1 Nov 2021 13:18:48 +0000 Subject: [PATCH] Throw pending clipping errors created during period preparation. Currently, clipping errors are never thrown if we already have a MediaPeriod. This may happen for example for ProgressiveMediaSource where we need to create a MediaPeriod before knowing whether clipping is supported. Playback will still fail, but with unrelated assertion errors that are hard to understand for users. Fix this by setting the pending error on the ClippingMediaPeriod. #minor-release Issue: Issue: google/ExoPlayer#9580 PiperOrigin-RevId: 406809737 --- .../exoplayer2/source/ClippingMediaPeriod.java | 18 ++++++++++++++++++ .../exoplayer2/source/ClippingMediaSource.java | 5 +++++ 2 files changed, 23 insertions(+) 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 464bf497fe..10cc75de32 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 @@ -21,6 +21,7 @@ import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.FormatHolder; import com.google.android.exoplayer2.SeekParameters; import com.google.android.exoplayer2.decoder.DecoderInputBuffer; +import com.google.android.exoplayer2.source.ClippingMediaSource.IllegalClippingException; import com.google.android.exoplayer2.trackselection.ExoTrackSelection; import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.MimeTypes; @@ -42,6 +43,7 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb private long pendingInitialDiscontinuityPositionUs; /* package */ long startUs; /* package */ long endUs; + @Nullable private IllegalClippingException clippingError; /** * Creates a new clipping media period that provides a clipped view of the specified {@link @@ -78,6 +80,16 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb this.endUs = endUs; } + /** + * Sets a clipping error detected by the media source so that it can be thrown as a period error + * at the next opportunity. + * + * @param clippingError The clipping error. + */ + public void setClippingError(IllegalClippingException clippingError) { + this.clippingError = clippingError; + } + @Override public void prepare(MediaPeriod.Callback callback, long positionUs) { this.callback = callback; @@ -86,6 +98,9 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb @Override public void maybeThrowPrepareError() throws IOException { + if (clippingError != null) { + throw clippingError; + } mediaPeriod.maybeThrowPrepareError(); } @@ -218,6 +233,9 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb @Override public void onPrepared(MediaPeriod mediaPeriod) { + if (clippingError != null) { + return; + } Assertions.checkNotNull(callback).onPrepared(this); } 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 f86b81760d..ab62cca0c5 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 @@ -276,6 +276,11 @@ public final class ClippingMediaSource extends CompositeMediaSource { clippingTimeline = new ClippingTimeline(timeline, windowStartUs, windowEndUs); } catch (IllegalClippingException e) { clippingError = e; + // The clipping error won't be propagated while we have existing MediaPeriods. Setting the + // error at the MediaPeriods ensures it will be thrown as soon as possible. + for (int i = 0; i < mediaPeriods.size(); i++) { + mediaPeriods.get(i).setClippingError(clippingError); + } return; } refreshSourceInfo(clippingTimeline);