Skip to content

Commit be8d7d9

Browse files
YLouWashUfacebook-github-bot
authored andcommitted
{CUDA Decoding} Restore SW decoder fallback in xprsDecoderMaker
Summary: A wheel built with `ENABLE_NVCODEC=ON` segfaults on any machine without an NVIDIA driver. The GitHub CI "Test wheel" job crashes with exit 139 after: Cannot load libcuda.so.1 [XPRS][WARNING]: Loading CUDA functions failed [DecoderFactory][WARNING]: Could not create a decoder for 'H.265'! With no driver, `getNvCodecContext()` throws and `enumDecoders()` catches it, returning a non-OK result -- but the SW `hevc`/`h264` decoders were already collected before the throw, so the list is usable. `xprsDecoderMaker` bailed on the non-OK result and discarded that list, so no decoder was created and the null decoder was dereferenced downstream. Two changes: - Ignore the `enumDecoders()` result and fail only when the decoder list is genuinely empty. This is what fixes the crash. - On decoder `init()` failure, continue to the next decoder instead of returning, so the HW->SW fallback actually runs. Both were reviewed as part of D103253728 but never reached master: the landed commit (`a4556645655d`) contains only its four `arvr/projects/compression/xprs/` files. This file was last modified on 2026-04-29, so ShipIt exported a copy that had never received them. This diff deliberately does not include the hard-coded monochrome HW-decoder skip from the abandoned D110227872. As georges-berenger noted there, whether a given format is decodable is driver and GPU dependent, so a static greyscale check could disable HW decoding for hardware that does support it. That case is already handled correctly by the `cuvidGetDecoderCaps` pre-check in `nvDecoder.cpp`, which queries the driver and falls back to SW when the format is genuinely unsupported. The GPU path is unchanged. Reviewed By: kongchen1992 Differential Revision: D114806413
1 parent 2f4fc9e commit be8d7d9

1 file changed

Lines changed: 6 additions & 2 deletions

File tree

vrs/utils/xprs/XprsDecoder.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,11 @@ unique_ptr<utils::DecoderI> xprsDecoderMaker(
373373
const string& codecFormatName = outputImageSpec.getCodecName();
374374
unique_ptr<VXDecoder> decoder;
375375
xprs::CodecList decoders;
376-
if (xprs::enumDecoders(decoders) != XprsResult::OK) {
376+
// enumDecoders can report a failure while still having collected usable SW
377+
// decoders, e.g. when CUDA init throws on a machine with no NVIDIA driver.
378+
(void)xprs::enumDecoders(decoders);
379+
if (decoders.empty()) {
380+
XR_LOGE("xprs::enumDecoders returned no decoders");
377381
return nullptr;
378382
}
379383
xprs::VideoCodecFormat codecFormat{};
@@ -399,7 +403,7 @@ unique_ptr<utils::DecoderI> xprsDecoderMaker(
399403
dec.implementationName,
400404
codecFormatName,
401405
xprs::getErrorMessage(res));
402-
return nullptr;
406+
continue;
403407
}
404408
decoder = make_unique<VXDecoder>(std::move(xprsDecoder));
405409
if (decoder->decode(encodedFrame, outDecodedFrame, outputImageSpec) == 0) {

0 commit comments

Comments
 (0)