mirror of
https://github.com/samsonjs/media.git
synced 2026-04-01 10:35:48 +00:00
Remove ExoPlaybackException.TYPE_OUT_OF_MEMORY
Catching OOM errors is bad practise unless there is a specific known
cause that tried to allocate a large amount of memory. Without this
known cause with a large allocation, the source of the error is
likely somewhere else in the app and every random small further
allocation may lead to additional OOM errors (for example b/145134199).
We have three known causes in ExoPlayer:
1. Source allocations based on unexpected values in streams. This is
caught on the loader thread and reported as an
UnexpectedLoaderException.
2. Output buffer allocations by non-MediaCodec decoders. These are
caught in SimpleDecoder on the decoder thread and reported as
UnexpectedDecodeException.
3. Input buffer allocations by non-MediaCodc decoders in their
constructors. These are currently caught on a higher-level and
reported as ExoPlaybackException.TYPE_OUT_OF_MEMORY.
For consistency and to prevent catching OOM errors without known cause
we can remove the generic TYPE_OUT_OF_MEMORY and catch the specific
exception where it occurs to report it as an
ExoPlaybackException.TYPE_RENDERER. This also has the added advantage
that the format metadata is added to the exception.
PiperOrigin-RevId: 351326688
This commit is contained in:
parent
b8b9a6411d
commit
c63f3d92ba
6 changed files with 14 additions and 48 deletions
|
|
@ -42,6 +42,7 @@
|
|||
creating subtitle media sources from
|
||||
`MediaItem.playbackProperties.subtitles`
|
||||
([#8430](https://github.com/google/ExoPlayer/issues/8430)).
|
||||
* Remove `ExoPlaybackException.OutOfMemoryError`.
|
||||
* Extractors:
|
||||
* Populate codecs string for H.264/AVC in MP4, Matroska and FLV streams to
|
||||
allow decoder capability checks based on codec profile/level
|
||||
|
|
|
|||
|
|
@ -34,20 +34,12 @@ public final class ExoPlaybackException extends Exception {
|
|||
|
||||
/**
|
||||
* The type of source that produced the error. One of {@link #TYPE_SOURCE}, {@link #TYPE_RENDERER}
|
||||
* {@link #TYPE_UNEXPECTED}, {@link #TYPE_REMOTE}, {@link #TYPE_OUT_OF_MEMORY} or {@link
|
||||
* #TYPE_TIMEOUT}. Note that new types may be added in the future and error handling should handle
|
||||
* unknown type values.
|
||||
* {@link #TYPE_UNEXPECTED}, {@link #TYPE_REMOTE} or {@link #TYPE_TIMEOUT}. Note that new types
|
||||
* may be added in the future and error handling should handle unknown type values.
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({
|
||||
TYPE_SOURCE,
|
||||
TYPE_RENDERER,
|
||||
TYPE_UNEXPECTED,
|
||||
TYPE_REMOTE,
|
||||
TYPE_OUT_OF_MEMORY,
|
||||
TYPE_TIMEOUT
|
||||
})
|
||||
@IntDef({TYPE_SOURCE, TYPE_RENDERER, TYPE_UNEXPECTED, TYPE_REMOTE, TYPE_TIMEOUT})
|
||||
public @interface Type {}
|
||||
/**
|
||||
* The error occurred loading data from a {@code MediaSource}.
|
||||
|
|
@ -75,10 +67,9 @@ public final class ExoPlaybackException extends Exception {
|
|||
* <p>Call {@link #getMessage()} to retrieve the message associated with the error.
|
||||
*/
|
||||
public static final int TYPE_REMOTE = 3;
|
||||
/** The error was an {@link OutOfMemoryError}. */
|
||||
public static final int TYPE_OUT_OF_MEMORY = 4;
|
||||
|
||||
/** The error was a {@link TimeoutException}. */
|
||||
public static final int TYPE_TIMEOUT = 5;
|
||||
public static final int TYPE_TIMEOUT = 4;
|
||||
|
||||
/** The {@link Type} of the playback failure. */
|
||||
@Type public final int type;
|
||||
|
|
@ -175,7 +166,7 @@ public final class ExoPlaybackException extends Exception {
|
|||
* @return The created instance.
|
||||
*/
|
||||
public static ExoPlaybackException createForRenderer(
|
||||
Exception cause,
|
||||
Throwable cause,
|
||||
String rendererName,
|
||||
int rendererIndex,
|
||||
@Nullable Format rendererFormat,
|
||||
|
|
@ -202,7 +193,7 @@ public final class ExoPlaybackException extends Exception {
|
|||
* @return The created instance.
|
||||
*/
|
||||
public static ExoPlaybackException createForRenderer(
|
||||
Exception cause,
|
||||
Throwable cause,
|
||||
String rendererName,
|
||||
int rendererIndex,
|
||||
@Nullable Format rendererFormat,
|
||||
|
|
@ -240,16 +231,6 @@ public final class ExoPlaybackException extends Exception {
|
|||
return new ExoPlaybackException(TYPE_REMOTE, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of type {@link #TYPE_OUT_OF_MEMORY}.
|
||||
*
|
||||
* @param cause The cause of the failure.
|
||||
* @return The created instance.
|
||||
*/
|
||||
public static ExoPlaybackException createForOutOfMemory(OutOfMemoryError cause) {
|
||||
return new ExoPlaybackException(TYPE_OUT_OF_MEMORY, cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of type {@link #TYPE_TIMEOUT}.
|
||||
*
|
||||
|
|
@ -382,16 +363,6 @@ public final class ExoPlaybackException extends Exception {
|
|||
return (RuntimeException) Assertions.checkNotNull(cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the underlying error when {@link #type} is {@link #TYPE_OUT_OF_MEMORY}.
|
||||
*
|
||||
* @throws IllegalStateException If {@link #type} is not {@link #TYPE_OUT_OF_MEMORY}.
|
||||
*/
|
||||
public OutOfMemoryError getOutOfMemoryError() {
|
||||
Assertions.checkState(type == TYPE_OUT_OF_MEMORY);
|
||||
return (OutOfMemoryError) Assertions.checkNotNull(cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the underlying error when {@link #type} is {@link #TYPE_TIMEOUT}.
|
||||
*
|
||||
|
|
@ -451,9 +422,6 @@ public final class ExoPlaybackException extends Exception {
|
|||
case TYPE_REMOTE:
|
||||
message = "Remote error";
|
||||
break;
|
||||
case TYPE_OUT_OF_MEMORY:
|
||||
message = "Out of memory error";
|
||||
break;
|
||||
case TYPE_TIMEOUT:
|
||||
message = "Timeout error";
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -340,7 +340,7 @@ public abstract class BaseRenderer implements Renderer, RendererCapabilities {
|
|||
* @param format The current format used by the renderer. May be null.
|
||||
*/
|
||||
protected final ExoPlaybackException createRendererException(
|
||||
Exception cause, @Nullable Format format) {
|
||||
Throwable cause, @Nullable Format format) {
|
||||
return createRendererException(cause, format, /* isRecoverable= */ false);
|
||||
}
|
||||
|
||||
|
|
@ -353,7 +353,7 @@ public abstract class BaseRenderer implements Renderer, RendererCapabilities {
|
|||
* @param isRecoverable If the error is recoverable by disabling and re-enabling the renderer.
|
||||
*/
|
||||
protected final ExoPlaybackException createRendererException(
|
||||
Exception cause, @Nullable Format format, boolean isRecoverable) {
|
||||
Throwable cause, @Nullable Format format, boolean isRecoverable) {
|
||||
@C.FormatSupport int formatSupport = C.FORMAT_HANDLED;
|
||||
if (format != null && !throwRendererExceptionIsExecuting) {
|
||||
// Prevent recursive re-entry from subclass supportsFormat implementations.
|
||||
|
|
|
|||
|
|
@ -582,11 +582,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||
stopInternal(/* forceResetRenderers= */ false, /* acknowledgeStop= */ false);
|
||||
playbackInfo = playbackInfo.copyWithPlaybackError(error);
|
||||
maybeNotifyPlaybackInfoChanged();
|
||||
} catch (RuntimeException | OutOfMemoryError e) {
|
||||
ExoPlaybackException error =
|
||||
e instanceof OutOfMemoryError
|
||||
? ExoPlaybackException.createForOutOfMemory((OutOfMemoryError) e)
|
||||
: ExoPlaybackException.createForUnexpected((RuntimeException) e);
|
||||
} catch (RuntimeException e) {
|
||||
ExoPlaybackException error = ExoPlaybackException.createForUnexpected(e);
|
||||
Log.e(TAG, "Playback error", error);
|
||||
stopInternal(/* forceResetRenderers= */ true, /* acknowledgeStop= */ false);
|
||||
playbackInfo = playbackInfo.copyWithPlaybackError(error);
|
||||
|
|
|
|||
|
|
@ -619,7 +619,7 @@ public abstract class DecoderAudioRenderer<
|
|||
eventDispatcher.decoderInitialized(decoder.getName(), codecInitializedTimestamp,
|
||||
codecInitializedTimestamp - codecInitializingTimestamp);
|
||||
decoderCounters.decoderInitCount++;
|
||||
} catch (DecoderException e) {
|
||||
} catch (DecoderException | OutOfMemoryError e) {
|
||||
throw createRendererException(e, inputFormat);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -707,7 +707,7 @@ public abstract class DecoderVideoRenderer extends BaseRenderer {
|
|||
decoderInitializedTimestamp,
|
||||
decoderInitializedTimestamp - decoderInitializingTimestamp);
|
||||
decoderCounters.decoderInitCount++;
|
||||
} catch (DecoderException e) {
|
||||
} catch (DecoderException | OutOfMemoryError e) {
|
||||
throw createRendererException(e, inputFormat);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue