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
{CUDA Decoding} Fix SW fallback bugs in xprsDecoderMaker, downgrade CUDA error logs, add XPRS_DISABLE_HW_DECODE
Summary:
First diff in the GPU-accelerated H.265 decoding stack for projectaria-tools (see plan v11 at ~/gdrive/plans/2026-04-03-gpu-accelerated-h265-decoding-pat-v11.md and tech design at https://docs.google.com/document/d/1TMeLy0TqvAdlYo0IY3Qm4BrzE8i035z9MzYvGl_CzeM by Lou Yang). Cleans up two latent bugs in `xprsDecoderMaker` that prevent SW fallback on non-GPU machines, and reduces log spam users see when CUDA is unavailable.
**Known limitation: NVDEC does not support small grayscale H.265 streams.** On Aria Gen2 recordings, the 200x200 eye-tracking and 512x512 SLAM cameras (encoded as grayscale H.265) produce `CUDA_ERROR_NOT_SUPPORTED` from `cuvidCreateDecoder` and fall back to the SW decoder. Only the 2016x1512 RGB camera stream uses the GPU path. The SW fallback machinery in this diff is what makes that graceful — without it, those streams would hard-fail. End-to-end on a 581 MB Aria Gen2 recording (RTX 5080, 580.159.03 driver), GPU vs CPU decode of the RGB stream measured 197.4 FPS vs 16.8 FPS (11.7x speedup, 300 frames). The aria_rerun_viewer load time on the same recording dropped from ~47s (CPU) to ~10s (GPU).
Bug 1 (line 386 of arvr/libraries/vrs/utils/xprs/XprsDecoder.cpp): when an HW decoder's `init()` returns non-OK, the function returned `nullptr` instead of trying the next decoder in the preferred list. This kills the SW fallback path entirely. Fix: log at WARN and `continue` to the next decoder.
Bug 2 (line 363 of the same file): when `xprs::enumDecoders()` returned non-OK, the function bailed out even though the function intentionally collects whatever decoders it managed to enumerate before any throw. On a non-GPU machine the HW decoder loop throws during CUDA init, but SW decoders were already collected. Fix: ignore the result code and only fail if the resulting list is empty.
Log noise: also downgrades all `XR_LOGE` to `XR_LOGW` in `getNvCodecContext()` (cudaContextProvider.cpp) and the catch handler in `enumDecoders`/`enumDecodersByFormat` (xprsDecApi.cpp). On a non-GPU machine these fired every VRS file open even though callers handle the throw and fall back gracefully.
Adds `XPRS_DISABLE_HW_DECODE` env var: setting it to any value forces CPU-only decoding by skipping all HW decoders during enumeration. Useful for deterministic results, working around GPU memory pressure, or comparing HW-vs-SW output. Read once into a static at first call, so the value is fixed for the process lifetime — runtime mutation has no effect.
Same env var skip + same catch-handler downgrade is applied to both `enumDecoders` and `enumDecodersByFormat` (parallel functions with identical structure).
Reviewed By: PiotrBrzyski
Differential Revision: D103253728
0 commit comments