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
parent 23de0be4c9
commit 69d6f84159
2 changed files with 23 additions and 0 deletions

View File

@ -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);
}

View File

@ -276,6 +276,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);