[Unity] OVROverlay External Surface: ExoPlayer disconnect from the surface internally.
So I am working with OVROverlay and I have been able to attach ExoPlayer video feed on to OVROverlay surface.
now here is the problem when trying to toggle OVROverlay's shape in realtime:
overlay.enabled = false;
overlay.currentOverlayShape = (overlay.currentOverlayShape == OVROverlay.OverlayShape.Quad) ? OVROverlay.OverlayShape.Cylinder : OVROverlay.OverlayShape.Quad;
overlay.enabled = true;Without toggling overlay enabled state, the UI doesn't update at all. This isn't a problem with Unity's VideoPlayer with RenderTexture. RenderTexture can even apply custom shader on per frame in real time while toggling shape.
But with ExoPlayer, I get such error:
2026-05-13 17:08:36.139 27844 28234 Error Surface queueBuffer: error queuing buffer, -19
2026-05-13 17:08:36.139 27844 28234 Error ACodec queueBuffer failed in onOutputBufferDrained: -19
2026-05-13 17:08:36.139 27844 28234 Error ACodec signalError(omxError 0x80001001, internalError -19)
2026-05-13 17:08:36.139 27844 28233 Error MediaCodec Codec reported err 0xffffffed/NO_INIT, actionCode 0, while in state 6/STARTED
2026-05-13 17:08:36.139 27844 28233 Debug MediaCodec flushMediametrics
2026-05-13 17:08:36.139 27844 28233 Debug MediaCodec updateMediametrics(0xb40000758bcd2000) ttff: 502ms, ttff_os: 31680455ms, init: 163ms ,configure: 7ms, start: 46ms, decode: 31680239ms, rendering: 227ms
2026-05-13 17:08:36.140 27844 28233 Debug SurfaceUtils disconnecting from surface 0xb40000758bcef010, reason disconnectFromSurface
2026-05-13 17:08:36.140 27844 28233 Error Surface freeAllBuffers: 8 buffers were freed while being dequeued!
2026-05-13 17:08:36.157 27844 28226 Error ExoPlayerImplInternal Playback error
2026-05-13 17:08:36.157 27844 28226 Error ExoPlayerImplInternal androidx.media3.exoplayer.ExoPlaybackException: MediaCodecVideoRenderer error, index=0, format=Format(1, null, video/mp4, video/avc, avc1.640020, 2246746, und, [1920, 540, 23.976025, ColorInfo(BT709, Limited range, SDR SMPTE 170M, false, 8bit Luma, 8bit Chroma)], [-1, -1]), format_supported=YES
2026-05-13 17:08:36.157 27844 28226 Error ExoPlayerImplInternal at androidx.media3.exoplayer.BaseRenderer.createRendererException(BaseRenderer.java:558)
2026-05-13 17:08:36.157 27844 28226 Error ExoPlayerImplInternal at androidx.media3.exoplayer.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:982)
2026-05-13 17:08:36.157 27844 28226 Error ExoPlayerImplInternal at androidx.media3.exoplayer.video.MediaCodecVideoRenderer.render(MediaCodecVideoRenderer.java:1431)
2026-05-13 17:08:36.157 27844 28226 Error ExoPlayerImplInternal at androidx.media3.exoplayer.RendererHolder.render(RendererHolder.java:392)
2026-05-13 17:08:36.157 27844 28226 Error ExoPlayerImplInternal at androidx.media3.exoplayer.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:1388)
2026-05-13 17:08:36.157 27844 28226 Error ExoPlayerImplInternal at androidx.media3.exoplayer.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:711)
2026-05-13 17:08:36.157 27844 28226 Error ExoPlayerImplInternal at android.os.Handler.dispatchMessage(Handler.java:102)
2026-05-13 17:08:36.157 27844 28226 Error ExoPlayerImplInternal at android.os.Looper.loopOnce(Looper.java:218)
2026-05-13 17:08:36.157 27844 28226 Error ExoPlayerImplInternal at android.os.Looper.loop(Looper.java:310)
2026-05-13 17:08:36.157 27844 28226 Error ExoPlayerImplInternal at android.os.HandlerThread.run(HandlerThread.java:67)
2026-05-13 17:08:36.157 27844 28226 Error ExoPlayerImplInternal Caused by: androidx.media3.exoplayer.video.MediaCodecVideoDecoderException: Decoder failed: OMX.qcom.video.decoder.avc
2026-05-13 17:08:36.157 27844 28226 Error ExoPlayerImplInternal at androidx.media3.exoplayer.video.MediaCodecVideoRenderer.createDecoderException(MediaCodecVideoRenderer.java:2665)
2026-05-13 17:08:36.157 27844 28226 Error ExoPlayerImplInternal at androidx.media3.exoplayer.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:976)
2026-05-13 17:08:36.157 27844 28226 Error ExoPlayerImplInternal ... 8 more
2026-05-13 17:08:36.157 27844 28226 Error ExoPlayerImplInternal Caused by: android.media.MediaCodec$CodecException: Error 0xffffffed
2026-05-13 17:08:36.157 27844 28226 Info Surface Surface::setFrameRate is deprecated, setFrameRate hint is dropped as destination is not SurfaceFlinger
2026-05-13 17:08:36.157 27844 28233 Error MediaCodec flush() is valid only at Executing states; currently at Released state
2026-05-13 17:08:36.160 27844 28226 Error ExoPlayerImplInternal Disable failed.
2026-05-13 17:08:36.160 27844 28226 Error ExoPlayerImplInternal java.lang.IllegalStateException: flush() is valid only at Executing states; currently at Released state
2026-05-13 17:08:36.160 27844 28226 Error ExoPlayerImplInternal
2026-05-13 17:08:36.160 27844 28226 Error ExoPlayerImplInternal at android.media.MediaCodec.native_flush(Native Method)
2026-05-13 17:08:36.160 27844 28226 Error ExoPlayerImplInternal at android.media.MediaCodec.flush(MediaCodec.java:2504)
2026-05-13 17:08:36.160 27844 28226 Error ExoPlayerImplInternal at androidx.media3.exoplayer.mediacodec.AsynchronousMediaCodecAdapter.flush(AsynchronousMediaCodecAdapter.java:278)
2026-05-13 17:08:36.160 27844 28226 Error ExoPlayerImplInternal at androidx.media3.exoplayer.mediacodec.MediaCodecRenderer.flushCodec(MediaCodecRenderer.java:1077)
2026-05-13 17:08:36.160 27844 28226 Error ExoPlayerImplInternal at androidx.media3.exoplayer.mediacodec.MediaCodecRenderer.flushOrReleaseCodec(MediaCodecRenderer.java:1020)
2026-05-13 17:08:36.160 27844 28226 Error ExoPlayerImplInternal at androidx.media3.exoplayer.mediacodec.MediaCodecRenderer.onDisabled(MediaCodecRenderer.java:833)
2026-05-13 17:08:36.160 27844 28226 Error ExoPlayerImplInternal at androidx.media3.exoplayer.video.MediaCodecVideoRenderer.onDisabled(MediaCodecVideoRenderer.java:1196)
2026-05-13 17:08:36.160 27844 28226 Error ExoPlayerImplInternal at androidx.media3.exoplayer.BaseRenderer.disable(BaseRenderer.java:253)
2026-05-13 17:08:36.160 27844 28226 Error ExoPlayerImplInternal at androidx.media3.exoplayer.RendererHolder.disableRenderer(RendererHolder.java:674)
2026-05-13 17:08:36.160 27844 28226 Error ExoPlayerImplInternal at androidx.media3.exoplayer.RendererHolder.disable(RendererHolder.java:568)
2026-05-13 17:08:36.160 27844 28226 Error ExoPlayerImplInternal at androidx.media3.exoplayer.ExoPlayerImplInternal.disableRenderer(ExoPlayerImplInternal.java:2253)
2026-05-13 17:08:36.160 27844 28226 Error ExoPlayerImplInternal at androidx.media3.exoplayer.ExoPlayerImplInternal.disableRenderers(ExoPlayerImplInternal.java:2246)
2026-05-13 17:08:36.160 27844 28226 Error ExoPlayerImplInternal at androidx.media3.exoplayer.ExoPlayerImplInternal.resetInternal(ExoPlayerImplInternal.java:1979)
2026-05-13 17:08:36.160 27844 28226 Error ExoPlayerImplInternal at androidx.media3.exoplayer.ExoPlayerImplInternal.stopInternal(ExoPlayerImplInternal.java:1933)
2026-05-13 17:08:36.160 27844 28226 Error ExoPlayerImplInternal at androidx.media3.exoplayer.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:890)
2026-05-13 17:08:36.160 27844 28226 Error ExoPlayerImplInternal at android.os.Handler.dispatchMessage(Handler.java:102)
2026-05-13 17:08:36.160 27844 28226 Error ExoPlayerImplInternal at android.os.Looper.loopOnce(Looper.java:218)
2026-05-13 17:08:36.160 27844 28226 Error ExoPlayerImplInternal at android.os.Looper.loop(Looper.java:310)
2026-05-13 17:08:36.160 27844 28226 Error ExoPlayerImplInternal at android.os.HandlerThread.run(HandlerThread.java:67)
2026-05-13 17:08:36.167 27844 28222 Info System.out Player error: MediaCodecVideoRenderer error, index=0, format=Format(1, null, video/mp4, video/avc, avc1.640020, 2246746, und, [1920, 540, 23.976025, ColorInfo(BT709, Limited range, SDR SMPTE 170M, false, 8bit Luma, 8bit Chroma)], [-1, -1]), format_supported=YES | errorCode: 4003
2026-05-13 17:08:36.177 27844 28234 Error Surface getSlotFromBufferLocked: unknown buffer: 0xb40000758ba7da20I have discussed this with different LLMs, and one recommend to set video surface to null in Android side (which didn't work at all)
Another recommendation was to release Exoplayer completely before disabling OVROverlay and then playing again after enabling OVROverlay (This is even worse user experience so I didn't bother to test it out).
So is there a way to handle this case?
Also while I am at it, let me know if I can add a shader like I do with VideoPlayer:
Graphics.Blit(sourceRT, processedRT, mat);
Thank you.
The solution is actually pretty simple, we need to attach the new surface coming from OVROverlay when it is enabled back to ExoPlayer:
await JNIBridge.Instance.DetachSurface(); //call your android JNI function to clear Exoplayer surface. //good time to also Dispose any reference to Surface AndroidJavaObject after ExoPlayer has cleared the video surface await Awaitable.EndOfFrameAsync(); overlay.enabled = false; overlay.currentOverlayShape = (overlay.currentOverlayShape == OVROverlay.OverlayShape.Quad) ? OVROverlay.OverlayShape.Cylinder : OVROverlay.OverlayShape.Quad; overlay.externalSurfaceObjectCreated = null; //optional: clean up any existing listener overlay.externalSurfaceObject = IntPtr.Zero; //optional: fresh start. overlay.externalSurfaceObjectCreated = async () => { await JNIBridge.Instance.AttachSurface(overlay.externalSurfaceObject); //call your android JNI function to set new surface to Exoplayer await Awaitable.EndOfFrameAsync(); }; overlay.enabled = true; //this is where externalSurfaceObjectCreated callback will be triggered await Awaitable.EndOfFrameAsync();