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
This commit is contained in:
tonihei 2021-11-01 13:18:48 +00:00 committed by Ian Baker
parent 15e2a13ea3
commit 7b84d6b051
2 changed files with 23 additions and 0 deletions

View File

@ -26,6 +26,7 @@ import androidx.media3.common.util.Util;
import androidx.media3.decoder.DecoderInputBuffer;
import androidx.media3.exoplayer.FormatHolder;
import androidx.media3.exoplayer.SeekParameters;
import androidx.media3.exoplayer.source.ClippingMediaSource.IllegalClippingException;
import androidx.media3.exoplayer.trackselection.ExoTrackSelection;
import java.io.IOException;
import org.checkerframework.checker.nullness.compatqual.NullableType;
@ -45,6 +46,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
@ -81,6 +83,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;
@ -89,6 +101,9 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb
@Override
public void maybeThrowPrepareError() throws IOException {
if (clippingError != null) {
throw clippingError;
}
mediaPeriod.maybeThrowPrepareError();
}
@ -221,6 +236,9 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb
@Override
public void onPrepared(MediaPeriod mediaPeriod) {
if (clippingError != null) {
return;
}
Assertions.checkNotNull(callback).onPrepared(this);
}

View File

@ -278,6 +278,11 @@ public final class ClippingMediaSource extends CompositeMediaSource<Void> {
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);