Add error code for codec reclaim

This allows apps to better detect when the platform
reclaims a codec. This requires adding the error code
to MediaCodecDecoderException.

PiperOrigin-RevId: 633588914
This commit is contained in:
tonihei 2024-05-14 08:10:05 -07:00 committed by Copybara-Service
parent 4cbe963b86
commit 2175c432d7
5 changed files with 32 additions and 7 deletions

View File

@ -27,6 +27,9 @@
* Fix bug where silence skipping at the end of items can trigger a
playback exception.
* Add `clear` to `PreloadMediaSource` to discard the preloading period.
* Add new error code
`PlaybackException.ERROR_CODE_DECODING_RESOURCES_RECLAIMED` that is used
when codec resources are reclaimed for higher priority tasks.
* Transformer:
* Work around a decoder bug where the number of audio channels was capped
at stereo when handling PCM input.

View File

@ -212,6 +212,10 @@ public class PlaybackException extends Exception implements Bundleable {
/** Caused by trying to decode content whose format is not supported. */
public static final int ERROR_CODE_DECODING_FORMAT_UNSUPPORTED = 4005;
// TODO: b/322943860 - Stabilize error code and add to IntDef
/** Caused by higher priority task reclaiming resources needed for decoding. */
@UnstableApi public static final int ERROR_CODE_DECODING_RESOURCES_RECLAIMED = 4006;
// AudioTrack errors (5xxx).
/** Caused by an AudioTrack initialization failure. */
@ -327,6 +331,8 @@ public class PlaybackException extends Exception implements Bundleable {
return "ERROR_CODE_DECODING_FORMAT_EXCEEDS_CAPABILITIES";
case ERROR_CODE_DECODING_FORMAT_UNSUPPORTED:
return "ERROR_CODE_DECODING_FORMAT_UNSUPPORTED";
case ERROR_CODE_DECODING_RESOURCES_RECLAIMED:
return "ERROR_CODE_DECODING_RESOURCES_RECLAIMED";
case ERROR_CODE_AUDIO_TRACK_INIT_FAILED:
return "ERROR_CODE_AUDIO_TRACK_INIT_FAILED";
case ERROR_CODE_AUDIO_TRACK_WRITE_FAILED:

View File

@ -800,8 +800,7 @@ public final class MediaMetricsListener
int subErrorCode = Util.getErrorCodeFromPlatformDiagnosticsInfo(diagnosticsInfo);
return new ErrorInfo(PlaybackErrorEvent.ERROR_DECODER_INIT_FAILED, subErrorCode);
} else if (cause instanceof MediaCodecDecoderException) {
@Nullable String diagnosticsInfo = ((MediaCodecDecoderException) cause).diagnosticInfo;
int subErrorCode = Util.getErrorCodeFromPlatformDiagnosticsInfo(diagnosticsInfo);
int subErrorCode = ((MediaCodecDecoderException) cause).errorCode;
return new ErrorInfo(PlaybackErrorEvent.ERROR_DECODING_FAILED, subErrorCode);
} else if (cause instanceof OutOfMemoryError) {
return new ErrorInfo(PlaybackErrorEvent.ERROR_DECODING_FAILED, /* subErrorCode= */ 0);

View File

@ -32,10 +32,17 @@ public class MediaCodecDecoderException extends DecoderException {
/** An optional developer-readable diagnostic information string. May be null. */
@Nullable public final String diagnosticInfo;
/** An optional error code reported by the codec. May be 0 if no error code could be obtained. */
public final int errorCode;
public MediaCodecDecoderException(Throwable cause, @Nullable MediaCodecInfo codecInfo) {
super("Decoder failed: " + (codecInfo == null ? null : codecInfo.name), cause);
this.codecInfo = codecInfo;
diagnosticInfo = Util.SDK_INT >= 21 ? getDiagnosticInfoV21(cause) : null;
errorCode =
Util.SDK_INT >= 23
? getErrorCodeV23(cause)
: Util.getErrorCodeFromPlatformDiagnosticsInfo(diagnosticInfo);
}
@RequiresApi(21)
@ -46,4 +53,12 @@ public class MediaCodecDecoderException extends DecoderException {
}
return null;
}
@RequiresApi(23)
private static int getErrorCodeV23(Throwable cause) {
if (cause instanceof MediaCodec.CodecException) {
return ((MediaCodec.CodecException) cause).getErrorCode();
}
return 0;
}
}

View File

@ -847,11 +847,13 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
if (isRecoverable) {
releaseCodec();
}
throw createRendererException(
createDecoderException(e, getCodecInfo()),
inputFormat,
isRecoverable,
PlaybackException.ERROR_CODE_DECODING_FAILED);
MediaCodecDecoderException exception = createDecoderException(e, getCodecInfo());
@PlaybackException.ErrorCode
int errorCode =
exception.errorCode == CodecException.ERROR_RECLAIMED
? PlaybackException.ERROR_CODE_DECODING_RESOURCES_RECLAIMED
: PlaybackException.ERROR_CODE_DECODING_FAILED;
throw createRendererException(exception, inputFormat, isRecoverable, errorCode);
}
throw e;
}