-
Notifications
You must be signed in to change notification settings - Fork 769
CodecException when ExoPlayer was paused in background #3148
Description
Issue Summary
We are experiencing a critical playback issue affecting our production application that uses ExoPlayer to play long-formed Widevine-protected DASH assets (both streaming and downloaded content). Approximately 150,000 playback sessions daily are failing with a PlaybackException error code 4003, which originates from a CodecException in the c2.android.aac.decoder component.
Pattern Identified
More than 85% of these 4003 errors occur under a specific condition—when ExoPlayer has been in a paused state (READY_TO_PLAY with playWhenReady=false) for more than 20 seconds while the application is running in the background.
We’ve been trying to reproduce in house, but no luck to repro to find the root cause. We would like to understand better on the potential root cause, suggestion from Google on how to collect information, and what we can do to mitigate the impact.
Environment Details
Media 3 version: 1.8.0
Affected Devices: The issue affects a wide range of Android devices across all market segments, including:
- US flagship devices (Samsung Galaxy series, Google Pixel series)
- International flagship devices (Xiaomi and others)
- Budget phones and tablets of various manufacturers
This broad device distribution suggests the issue is not hardware-specific.
Reproduction Attempts
Demo App Testing: We have been unable to reproduce this issue in the ExoPlayer demo application.
Internal Testing: Despite extensive efforts to replicate the problem in our development environment, we have not been successful in reproducing it internally. All our data and metrics are derived from our production application's telemetry.
Production Use Case (90% of occurrences):
- User plays a downloaded Widevine-protected DASH asset in ExoPlayer, then pauses playback (or loads the asset without initiating playback)
- Application moves to background state (we do not have data on battery saving mode status or memory pressure conditions)
- After 20-200 seconds of inactivity, the error occurs
Expected vs. Actual Behavior
Expected: When ExoPlayer is paused in the background, it should either maintain its state gracefully or, if the system needs to reclaim resources, the entire application should be terminated. The player should not enter an error state due to resource reclamation.
Actual: ExoPlayer throws a 4003 error with the following typical stack trace:
java.lang.Exception: PlayerErrorReason(playerErrorType=OTHER, message=DecodingFailed(4003) - CodecException[errorCode=-2147483648, diagnosticInfo=android.media.MediaCodec.error_neg_-2147483648, isRecoverable=false, isTransient=false], detail=null, errorInfo=androidx.media3.exoplayer.ExoPlaybackException: MediaCodecAudioRenderer error, index=0, format=Format(0, null, audio/mp4, audio/mp4a-latm, mp4a.40.42, 36468, und, [-1, -1, -1.0, null], [2, 44100]), format_supported=YES, errorCode=4003, errorSource=WidevineL1StreamingPlayerXHE),
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(Unknown Source:11)
at kotlinx.coroutines.DispatchedTask.run(Unknown Source:128)
at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(Unknown Source:3)
at kotlinx.coroutines.scheduling.TaskImpl.run(Unknown Source:2)
at kotlinx.coroutines.scheduling.CoroutineScheduler.S(Unknown Source:0)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.b(Unknown Source:33)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.m(Unknown Source:28)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(Unknown Source:0)
Caused by: androidx.media3.exoplayer.ExoPlaybackException: MediaCodecAudioRenderer error, index=0, format=Format(0, null, audio/mp4, audio/mp4a-latm, mp4a.40.42, 36468, und, [-1, -1, -1.0, null], [2, 44100]), format_supported=YES
at androidx.media3.exoplayer.BaseRenderer.n0(Unknown Source:45)
at androidx.media3.exoplayer.mediacodec.MediaCodecRenderer.h(Unknown Source:180)
at androidx.media3.exoplayer.RendererHolder.I(Unknown Source:10)
at androidx.media3.exoplayer.ExoPlayerImplInternal.D(Unknown Source:104)
at androidx.media3.exoplayer.ExoPlayerImplInternal.handleMessage(Unknown Source:369)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loopOnce(Looper.java:222)
at android.os.Looper.loop(Looper.java:314)
at android.os.HandlerThread.run(HandlerThread.java:67)
Caused by: androidx.media3.exoplayer.mediacodec.MediaCodecDecoderException: Decoder failed: c2.android.aac.decoder
at androidx.media3.exoplayer.mediacodec.MediaCodecRenderer.W0(Unknown Source:2)
at androidx.media3.exoplayer.mediacodec.MediaCodecRenderer.h(Unknown Source:163)
... 7 more
Caused by: android.media.MediaCodec$CodecException:
at android.media.MediaCodec.native_queueSecureInputBuffer(Native Method)
at android.media.MediaCodec.queueSecureInputBuffer(MediaCodec.java:3105)
at androidx.media3.exoplayer.mediacodec.AsynchronousMediaCodecBufferEnqueuer.l(Unknown Source:10)
at androidx.media3.exoplayer.mediacodec.AsynchronousMediaCodecBufferEnqueuer.i(Unknown Source:62)
at androidx.media3.exoplayer.mediacodec.AsynchronousMediaCodecBufferEnqueuer.d(Unknown Source:0)
at androidx.media3.exoplayer.mediacodec.AsynchronousMediaCodecBufferEnqueuer$1.handleMessage(Unknown Source:2)
at android.os.Handler.dispatchMessage(Handler.java:106)
... 3 more
Media Content
The specific media content does not appear to be a factor, as the same assets play successfully when there is no background pause period.
Assistance Requested
Given our inability to reproduce this issue in controlled environments, we are seeking expertise on the following:
- Root Cause Analysis: What are the potential underlying causes for this codec failure pattern, particularly in relation to background state management and resource handling?
- Diagnostic Data Collection: What specific diagnostic information, logs, or telemetry would be most valuable for investigating this issue? Are there additional instrumentation points we should implement in our production application?
- Mitigation Strategies: What approaches would you recommend to reduce the impact on our users? Specifically, we have observed that when users manually reload the same asset with a fresh ExoPlayer instance after encountering this error, playback typically succeeds. Would it be safe and advisable to implement automatic recovery by reinitializing the ExoPlayer instance when we detect a 4003 error from a paused state?
- Best Practices: Are there recommended patterns for managing ExoPlayer lifecycle and codec resources when applications transition to background states for extended periods?