Version
Media3 1.9.0
More version details
Environment:
- media3-ui-compose 1.9.0
- Jetpack Compose
- Surface type: SURFACE_TYPE_TEXTURE_VIEW
- Device: low-end devices reproduce more frequently
Summary:
When using PlayerSurface with TextureView, we intermittently hit
ERROR_CODE_FAILED_RUNTIME_CHECK (1004) with IllegalArgumentException from
MediaCodec.setOutputSurface(). This seems to happen when the surface is
replaced/invalidated during rapid attach/detach.
Observed logs (verbatim):
2026-01-15 15:22:13.250 ... onPlayerErrorChanged: ERROR_CODE_FAILED_RUNTIME_CHECK, message: Unexpected runtime error
2026-01-15 15:22:13.250 ... onPlayerError: ERROR_CODE_FAILED_RUNTIME_CHECK
2026-01-15 15:22:13.250 ... - errorCode: 1004
2026-01-15 15:22:13.250 ... - message: Unexpected runtime error
2026-01-15 15:22:13.250 ... - cause: java.lang.IllegalArgumentException
Stacktrace excerpt (verbatim):
java.lang.IllegalArgumentException
at android.media.MediaCodec.native_setSurface(Native Method)
at android.media.MediaCodec.setOutputSurface(MediaCodec.java:1954)
at androidx.media3.exoplayer.mediacodec.SynchronousMediaCodecAdapter.setOutputSurface(SynchronousMediaCodecAdapter.java:193)
at androidx.media3.exoplayer.video.MediaCodecVideoRenderer.setOutputSurfaceV23(MediaCodecVideoRenderer.java:2405)
at androidx.media3.exoplayer.video.MediaCodecVideoRenderer.setOutputSurface(MediaCodecVideoRenderer.java:2393)
at androidx.media3.exoplayer.video.MediaCodecVideoRenderer.setOutput(MediaCodecVideoRenderer.java:1267)
at androidx.media3.exoplayer.video.MediaCodecVideoRenderer.handleMessage(MediaCodecVideoRenderer.java:1175)
at androidx.media3.exoplayer.RendererHolder.setVideoOutput(RendererHolder.java:817)
at androidx.media3.exoplayer.ExoPlayerImplInternal.setVideoOutputInternal(ExoPlayerImplInternal.java:1910)
at androidx.media3.exoplayer.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:739)
Repro steps:
- Use PlayerSurface in Compose with SURFACE_TYPE_TEXTURE_VIEW
- Show videos in a scrolling list (fast scroll triggers frequent attach/detach)
- Observe intermittent IllegalArgumentException in setOutputSurface
Code sample:
@Composable
fun VideoPlayerContent(...) {
PlayerSurface(
player = player,
surfaceType = SURFACE_TYPE_TEXTURE_VIEW,
modifier = Modifier.fillMaxSize()
)
}
Analysis:
We inspected PlayerSurfaceKt.class (1.9.0) and found:
- DisposableEffect onDispose only removes Player.Listener (no clearVideoSurface/stop)
- AndroidView is used but there is no onRelease hook to clear player before view detaches
- clearVideoView happens via LaunchedEffect (not ordered before view removal)
This can cause MediaCodec.setOutputSurface to receive an invalid or already-destroyed surface.
Expected:
PlayerSurface should guarantee that player is cleared/stopped before the underlying TextureView surface is replaced/detached, or provide a hook to enforce this order.
Potential fix ideas:
- Provide onRelease/onDispose hook to clear surface before AndroidView detaches
- Ensure clearVideoView is called synchronously before view removal
- Allow custom SurfaceTextureListener or a “defer release” option for TextureView
Devices that reproduce the issue
Samsung Galaxy S8 running Android 9
Devices that do not reproduce the issue
Samsung Galaxy S24+ running Android 16
Reproducible in the demo app?
No
Reproduction steps
Repro steps:
- Use PlayerSurface in Compose with SURFACE_TYPE_TEXTURE_VIEW
- Show videos in a scrolling list (fast scroll triggers frequent attach/detach)
- Observe intermittent IllegalArgumentException in setOutputSurface
Expected result
Expected:
PlayerSurface should guarantee that player is cleared/stopped before the underlying TextureView surface is replaced/detached, or provide a hook to enforce this order.
Actual result
When using PlayerSurface with TextureView, we intermittently hit
ERROR_CODE_FAILED_RUNTIME_CHECK (1004) with IllegalArgumentException from
MediaCodec.setOutputSurface(). This seems to happen when the surface is
replaced/invalidated during rapid attach/detach.
And the video did not play.
Observed logs (verbatim):
2026-01-15 15:22:13.250 ... onPlayerErrorChanged: ERROR_CODE_FAILED_RUNTIME_CHECK, message: Unexpected runtime error
2026-01-15 15:22:13.250 ... onPlayerError: ERROR_CODE_FAILED_RUNTIME_CHECK
2026-01-15 15:22:13.250 ... - errorCode: 1004
2026-01-15 15:22:13.250 ... - message: Unexpected runtime error
2026-01-15 15:22:13.250 ... - cause: java.lang.IllegalArgumentException
Stacktrace excerpt (verbatim):
java.lang.IllegalArgumentException
at android.media.MediaCodec.native_setSurface(Native Method)
at android.media.MediaCodec.setOutputSurface(MediaCodec.java:1954)
at androidx.media3.exoplayer.mediacodec.SynchronousMediaCodecAdapter.setOutputSurface(SynchronousMediaCodecAdapter.java:193)
at androidx.media3.exoplayer.video.MediaCodecVideoRenderer.setOutputSurfaceV23(MediaCodecVideoRenderer.java:2405)
at androidx.media3.exoplayer.video.MediaCodecVideoRenderer.setOutputSurface(MediaCodecVideoRenderer.java:2393)
at androidx.media3.exoplayer.video.MediaCodecVideoRenderer.setOutput(MediaCodecVideoRenderer.java:1267)
at androidx.media3.exoplayer.video.MediaCodecVideoRenderer.handleMessage(MediaCodecVideoRenderer.java:1175)
at androidx.media3.exoplayer.RendererHolder.setVideoOutput(RendererHolder.java:817)
at androidx.media3.exoplayer.ExoPlayerImplInternal.setVideoOutputInternal(ExoPlayerImplInternal.java:1910)
at androidx.media3.exoplayer.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:739)
Media
Not applicable.
Repro by any video url
Bug Report
Version
Media3 1.9.0
More version details
Environment:
Summary:
When using PlayerSurface with TextureView, we intermittently hit
ERROR_CODE_FAILED_RUNTIME_CHECK (1004) with IllegalArgumentException from
MediaCodec.setOutputSurface(). This seems to happen when the surface is
replaced/invalidated during rapid attach/detach.
Observed logs (verbatim):
Stacktrace excerpt (verbatim):
Repro steps:
Code sample:
Analysis:
We inspected PlayerSurfaceKt.class (1.9.0) and found:
This can cause MediaCodec.setOutputSurface to receive an invalid or already-destroyed surface.
Expected:
PlayerSurface should guarantee that player is cleared/stopped before the underlying TextureView surface is replaced/detached, or provide a hook to enforce this order.
Potential fix ideas:
Devices that reproduce the issue
Samsung Galaxy S8 running Android 9
Devices that do not reproduce the issue
Samsung Galaxy S24+ running Android 16
Reproducible in the demo app?
No
Reproduction steps
Repro steps:
Expected result
Expected:
PlayerSurface should guarantee that player is cleared/stopped before the underlying TextureView surface is replaced/detached, or provide a hook to enforce this order.
Actual result
When using PlayerSurface with TextureView, we intermittently hit
ERROR_CODE_FAILED_RUNTIME_CHECK (1004) with IllegalArgumentException from
MediaCodec.setOutputSurface(). This seems to happen when the surface is
replaced/invalidated during rapid attach/detach.
And the video did not play.
Observed logs (verbatim):
Stacktrace excerpt (verbatim):
Media
Not applicable.
Repro by any video url
Bug Report
adb bugreportto android-media-github@google.com after filing this issue.