Allow renderer retry for audio track offload initialization failure

If render error occurs due to AudioTrack initialization failure in offload mode, then ExoPlayer should allow retry as subsequent attempt will be with DefaultAudioSink disabling offload.

PiperOrigin-RevId: 609304897
(cherry picked from commit 9046f2edb62f3dd9bc735405d2a58a98abd87064)
This commit is contained in:
michaelkatz 2024-02-22 02:56:45 -08:00 committed by SheenaChhabra
parent 2ae79959ef
commit ed71172ade
4 changed files with 18 additions and 3 deletions

View File

@ -5,11 +5,14 @@
* ExoPlayer: * ExoPlayer:
* Fix issue where `PreloadMediaPeriod` cannot retain the streams when it * Fix issue where `PreloadMediaPeriod` cannot retain the streams when it
is preloaded again. is preloaded again.
* Effect:
* Improved PQ to SDR tone-mapping by converting color spaces.
* Transformer: * Transformer:
* Add workaround for exception thrown due to `MediaMuxer` not supporting * Add workaround for exception thrown due to `MediaMuxer` not supporting
negative presentation timestamps before API 30. negative presentation timestamps before API 30.
* Audio:
* Allow renderer recovery by disabling offload if audio track fails to
initialize in offload mode.
* Effect:
* Improved PQ to SDR tone-mapping by converting color spaces.
* UI: * UI:
* Fallback to include audio track language name if `Locale` cannot * Fallback to include audio track language name if `Locale` cannot
identify a display name identify a display name

View File

@ -224,6 +224,9 @@ public class PlaybackException extends Exception implements Bundleable {
/** Caused by an AudioTrack write operation failure in offload mode. */ /** Caused by an AudioTrack write operation failure in offload mode. */
@UnstableApi public static final int ERROR_CODE_AUDIO_TRACK_OFFLOAD_WRITE_FAILED = 5003; @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). // DRM errors (6xxx).
/** Caused by an unspecified error related to DRM protection. */ /** 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"; return "ERROR_CODE_AUDIO_TRACK_WRITE_FAILED";
case ERROR_CODE_AUDIO_TRACK_OFFLOAD_WRITE_FAILED: case ERROR_CODE_AUDIO_TRACK_OFFLOAD_WRITE_FAILED:
return "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: case ERROR_CODE_DRM_UNSPECIFIED:
return "ERROR_CODE_DRM_UNSPECIFIED"; return "ERROR_CODE_DRM_UNSPECIFIED";
case ERROR_CODE_DRM_SCHEME_UNSUPPORTED: case ERROR_CODE_DRM_SCHEME_UNSUPPORTED:

View File

@ -622,6 +622,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
} }
if (e.isRecoverable if (e.isRecoverable
&& (pendingRecoverableRendererError == null && (pendingRecoverableRendererError == null
|| e.errorCode == PlaybackException.ERROR_CODE_AUDIO_TRACK_OFFLOAD_INIT_FAILED
|| e.errorCode == PlaybackException.ERROR_CODE_AUDIO_TRACK_OFFLOAD_WRITE_FAILED)) { || e.errorCode == PlaybackException.ERROR_CODE_AUDIO_TRACK_OFFLOAD_WRITE_FAILED)) {
// If pendingRecoverableRendererError != null and error was // If pendingRecoverableRendererError != null and error was
// ERROR_CODE_AUDIO_TRACK_OFFLOAD_WRITE_FAILED then upon retry, renderer will attempt with // ERROR_CODE_AUDIO_TRACK_OFFLOAD_WRITE_FAILED then upon retry, renderer will attempt with

View File

@ -743,7 +743,13 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
fullyConsumed = audioSink.handleBuffer(buffer, bufferPresentationTimeUs, sampleCount); fullyConsumed = audioSink.handleBuffer(buffer, bufferPresentationTimeUs, sampleCount);
} catch (InitializationException e) { } catch (InitializationException e) {
throw createRendererException( 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) { } catch (WriteException e) {
throw createRendererException( throw createRendererException(
e, e,