You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Media player video playback crashes the whole client on Quest within roughly a second of the first decoded frame reaching the present path — a SIGSEGV (null-pointer dereference) inside the Adreno driver's vkCmdExecuteCommands, raised on Unity's Vulkan submission thread. Audio decode is unaffected (5.1 audio was validated on the same hardware with video presentation disabled — see #921).
This makes all media player video unusable on Android/Quest today. As far as we can tell the Android Vulkan present path had never been exercised on device before this test session, so it isn't a regression — it's the first real run of that leg.
Steps to Reproduce
Build the client for Android (arm64, Vulkan) and sideload it on a Quest headset.
In-world, load any working video stream in the media player (reproduced with H.264 + AAC over rtspt://; the transport doesn't appear to matter — the crash follows the first decoded frames reaching the Vulkan present).
The app hard-crashes within ~1 second of playback starting.
The expected behavior
The stream plays: video renders to the media player screen and the app keeps running.
Screenshots
N/A — the failure is a native crash; the tombstone is under Log Files.
Build Info
Local developer build (sideloaded, so no in-app "Copy Build Info" available):
Unity 6000.5.2f1, IL2CPP arm64, Vulkan, XR
Platform: Quest Pro (seacliff), Android 14 / UP1A.231005.007.A1
Plugin log up to the crash (adb logcat -s basis_media) — decode is healthy, then the process dies as frames reach the present:
I basis_media: audio output format: 48000 Hz, 6 ch, pcm-encoding 0
I basis_media: demux run ended: delta_aus=82 total_aus=82 attempt=1/6
Tombstone:
Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x15c in tid (Vulkan Submissi)
Cause: null pointer dereference
backtrace:
#00 pc 000c6418 /vendor/lib64/hw/vulkan.adreno.so
(qglinternal::vkCmdExecuteCommands(VkCommandBuffer_T*, unsigned int, VkCommandBuffer_T* const*)+1192)
#01-#05 libunity.so
Note the crash is not in the plugin's frames — Unity's own primary command buffer blows up while executing its recorded secondary command buffers, after the plugin's render event has run.
Declaring the render event with ConfigureEvent(kUnityVulkanRenderPass_EnsureOutside) does not help — identical tombstone (same PC offset, same fault address). The outside-render-pass precondition alone is insufficient.
A diagnostic build that drops every decoded frame before any Vulkan work does not crash and plays audio indefinitely. That isolates the trigger to exactly the commands the present path records: a pipeline barrier plus its own render pass and draw, recorded into Unity's command buffer via IUnityGraphicsVulkan::CommandRecordingState.
Conclusion: recording a foreign render pass into Unity's command buffers corrupts the Adreno driver's command-buffer state on this stack (Unity 6000.5 + XR, where Unity records its passes into secondary command buffers), and the corruption detonates later at vkCmdExecuteCommands. Whether that's a driver bug or a violated implicit contract of the recording-state API is academic for us — recording into Unity's command buffer is the thing that has to go.
Planned fix (implementation underway on a branch stacked on #921; PR to follow once device-validated):
The YCbCr→RGBA resolve records into a plugin-owned command buffer (one per import-ring slot) and is submitted on the graphics queue directly from the render event, configured with kUnityVulkanGraphicsQueueAccess_Allow so Unity holds its own queue users off the queue during the callback.
A fence per slot replaces Unity's safeFrameNumber for reclaiming imported AHardwareBuffers.
The Unity RenderTexture's VkImage is obtained with AccessTexture(ObserveOnly) — no barriers recorded on our behalf. No layout coordination is needed: the resolve render pass already takes the attachment from UNDEFINED (full-frame overwrite every draw) and returns it in SHADER_READ_ONLY, the layout Unity samples it in.
Raising this ahead of that PR for visibility, and in case anyone has seen this driver behaviour elsewhere or knows of constraints on GraphicsQueueAccess_Allow under the Quest XR stack that would change the approach.
Describe the bug?
Media player video playback crashes the whole client on Quest within roughly a second of the first decoded frame reaching the present path — a SIGSEGV (null-pointer dereference) inside the Adreno driver's
vkCmdExecuteCommands, raised on Unity's Vulkan submission thread. Audio decode is unaffected (5.1 audio was validated on the same hardware with video presentation disabled — see #921).This makes all media player video unusable on Android/Quest today. As far as we can tell the Android Vulkan present path had never been exercised on device before this test session, so it isn't a regression — it's the first real run of that leg.
Steps to Reproduce
rtspt://; the transport doesn't appear to matter — the crash follows the first decoded frames reaching the Vulkan present).The expected behavior
The stream plays: video renders to the media player screen and the app keeps running.
Screenshots
N/A — the failure is a native crash; the tombstone is under Log Files.
Build Info
Local developer build (sideloaded, so no in-app "Copy Build Info" available):
seacliff), Android 14 / UP1A.231005.007.A1com.basis.mediaplayernative plugin arm64-v8a,developerbranch + fix(mediaplayer): decode discrete multichannel AAC on Android #921's changes (crash reproduces identically without them)Log Files
Plugin log up to the crash (
adb logcat -s basis_media) — decode is healthy, then the process dies as frames reach the present:Tombstone:
Note the crash is not in the plugin's frames — Unity's own primary command buffer blows up while executing its recorded secondary command buffers, after the plugin's render event has run.
Additional Context
Evidence chain from the device session:
ConfigureEvent(kUnityVulkanRenderPass_EnsureOutside)does not help — identical tombstone (same PC offset, same fault address). The outside-render-pass precondition alone is insufficient.IUnityGraphicsVulkan::CommandRecordingState.Conclusion: recording a foreign render pass into Unity's command buffers corrupts the Adreno driver's command-buffer state on this stack (Unity 6000.5 + XR, where Unity records its passes into secondary command buffers), and the corruption detonates later at
vkCmdExecuteCommands. Whether that's a driver bug or a violated implicit contract of the recording-state API is academic for us — recording into Unity's command buffer is the thing that has to go.Planned fix (implementation underway on a branch stacked on #921; PR to follow once device-validated):
kUnityVulkanGraphicsQueueAccess_Allowso Unity holds its own queue users off the queue during the callback.safeFrameNumberfor reclaiming importedAHardwareBuffers.VkImageis obtained withAccessTexture(ObserveOnly)— no barriers recorded on our behalf. No layout coordination is needed: the resolve render pass already takes the attachment fromUNDEFINED(full-frame overwrite every draw) and returns it inSHADER_READ_ONLY, the layout Unity samples it in.Raising this ahead of that PR for visibility, and in case anyone has seen this driver behaviour elsewhere or knows of constraints on
GraphicsQueueAccess_Allowunder the Quest XR stack that would change the approach.