diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 77199435ca..d77693b562 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -17,6 +17,8 @@ * Track Selection: * Extractors: * Audio: + * Allow renderer recovery by disabling offload if audio track fails to + initialize in offload mode. * Video: * Text: * Metadata: diff --git a/libraries/common/src/main/java/androidx/media3/common/PlaybackException.java b/libraries/common/src/main/java/androidx/media3/common/PlaybackException.java index 8ebf665d39..5cdd8082f7 100644 --- a/libraries/common/src/main/java/androidx/media3/common/PlaybackException.java +++ b/libraries/common/src/main/java/androidx/media3/common/PlaybackException.java @@ -224,6 +224,9 @@ public class PlaybackException extends Exception implements Bundleable { /** Caused by an AudioTrack write operation failure in offload mode. */ @UnstableApi public static final int ERROR_CODE_AUDIO_TRACK_OFFLOAD_WRITE_FAILED = 5003; + /** Caused by an AudioTrack write operation failure in offload mode. */ + @UnstableApi public static final int ERROR_CODE_AUDIO_TRACK_OFFLOAD_INIT_FAILED = 5004; + // DRM errors (6xxx). /** Caused by an unspecified error related to DRM protection. */ @@ -330,6 +333,8 @@ public class PlaybackException extends Exception implements Bundleable { return "ERROR_CODE_AUDIO_TRACK_WRITE_FAILED"; case ERROR_CODE_AUDIO_TRACK_OFFLOAD_WRITE_FAILED: return "ERROR_CODE_AUDIO_TRACK_OFFLOAD_WRITE_FAILED"; + case ERROR_CODE_AUDIO_TRACK_OFFLOAD_INIT_FAILED: + return "ERROR_CODE_AUDIO_TRACK_OFFLOAD_INIT_FAILED"; case ERROR_CODE_DRM_UNSPECIFIED: return "ERROR_CODE_DRM_UNSPECIFIED"; case ERROR_CODE_DRM_SCHEME_UNSUPPORTED: diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayerImplInternal.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayerImplInternal.java index 6d472853a8..f010a96606 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayerImplInternal.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayerImplInternal.java @@ -622,6 +622,7 @@ import java.util.concurrent.atomic.AtomicBoolean; } if (e.isRecoverable && (pendingRecoverableRendererError == null + || e.errorCode == PlaybackException.ERROR_CODE_AUDIO_TRACK_OFFLOAD_INIT_FAILED || e.errorCode == PlaybackException.ERROR_CODE_AUDIO_TRACK_OFFLOAD_WRITE_FAILED)) { // If pendingRecoverableRendererError != null and error was // ERROR_CODE_AUDIO_TRACK_OFFLOAD_WRITE_FAILED then upon retry, renderer will attempt with diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/MediaCodecAudioRenderer.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/MediaCodecAudioRenderer.java index 4a861e45e5..0c0765ea49 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/MediaCodecAudioRenderer.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/MediaCodecAudioRenderer.java @@ -743,7 +743,13 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media fullyConsumed = audioSink.handleBuffer(buffer, bufferPresentationTimeUs, sampleCount); } catch (InitializationException e) { throw createRendererException( - e, inputFormat, e.isRecoverable, PlaybackException.ERROR_CODE_AUDIO_TRACK_INIT_FAILED); + e, + inputFormat, + e.isRecoverable, + isBypassEnabled() + && getConfiguration().offloadModePreferred != AudioSink.OFFLOAD_MODE_DISABLED + ? PlaybackException.ERROR_CODE_AUDIO_TRACK_OFFLOAD_INIT_FAILED + : PlaybackException.ERROR_CODE_AUDIO_TRACK_INIT_FAILED); } catch (WriteException e) { throw createRendererException( e,