Summary
Camera.setMode({ depth: ... }) causes the Chromium USB utility process to crash on Linux. The same code works on macOS Chromium. Root cause is a missing dev.selectAlternateInterface(...) call after dev.claimInterface(...) in the camera worker.
Environment
- OS: Fedora Asahi (Apple Silicon)
- Browser: Chromium (Linux)
- Device: Xbox 360 Kinect, vid
045e pid 02ae
@webnect/driver: 0.1.1
- Host pre-reqs already in place:
gspca_kinect blacklisted/unloaded, libfreenect-style udev rules granting user access to vid 045e. The device opens cleanly — no Access denied.
Symptom
chromium-browser.log excerpt at the moment Camera.setMode runs:
USB: usb_device_handle_usbfs.cc:168 Low-level transfer error: Invalid argument (22)
crashpad/snapshot/elf/elf_dynamic_array_reader.h:64 tag not found
crashpad/snapshot/elf/elf_dynamic_array_reader.h:64 tag not found
crashpad/snapshot/elf/elf_dynamic_array_reader.h:64 tag not found
crashpad/snapshot/elf/elf_dynamic_array_reader.h:64 tag not found
EINVAL from usbfs on URB submission, then crashpad fires ~25 ms later — the iso transfer takes down the USB process before the JS-side isochronousTransferIn() rejection can surface.
Same code paths on macOS Chromium stream depth frames without issue.
Root cause
In src/camera/worker/worker.ts, getDevice does:
if (!iface.claimed) {
await dev.claimInterface(usbInterface);
}
return dev;
…and the caller goes straight into dev.isochronousTransferIn(...) via UnderlyingIsochronousTransferSource. Grep across src/ confirms there is zero selectAlternateInterface / alternateSetting usage anywhere in the driver.
macOS's IOUSBLib is permissive about this — it'll accept an iso transfer with the interface in its default alt setting. Linux's usbfs requires an explicit SET_INTERFACE ioctl to reserve iso bandwidth for the endpoint; without it the URB submission returns EINVAL and the Chromium USB utility process crashes (this isn't a graceful JS-level rejection on Linux — it kills the worker process).
Suggested fix
Add an explicit alt-setting selection after the claim:
if (!iface.claimed) {
await dev.claimInterface(usbInterface);
}
await dev.selectAlternateInterface(usbInterface, 0);
return dev;
libfreenect src/cameras.c calls libusb_set_interface_alt_setting(udev->cam, 0, 0) for the camera interface, so alt 0 is the right starting point. Worth verifying against the device's USB descriptor in case the iso endpoints actually live on a different alt — if so, use that one.
Notes
macOS users won't observe a regression after this fix lands; it's a no-op on platforms that already tolerate the missing call.
Summary
Camera.setMode({ depth: ... })causes the Chromium USB utility process to crash on Linux. The same code works on macOS Chromium. Root cause is a missingdev.selectAlternateInterface(...)call afterdev.claimInterface(...)in the camera worker.Environment
045epid02ae@webnect/driver: 0.1.1gspca_kinectblacklisted/unloaded, libfreenect-style udev rules granting user access to vid045e. The device opens cleanly — noAccess denied.Symptom
chromium-browser.logexcerpt at the momentCamera.setModeruns:EINVALfromusbfson URB submission, then crashpad fires ~25 ms later — the iso transfer takes down the USB process before the JS-sideisochronousTransferIn()rejection can surface.Same code paths on macOS Chromium stream depth frames without issue.
Root cause
In
src/camera/worker/worker.ts,getDevicedoes:…and the caller goes straight into
dev.isochronousTransferIn(...)viaUnderlyingIsochronousTransferSource. Grep acrosssrc/confirms there is zeroselectAlternateInterface/alternateSettingusage anywhere in the driver.macOS's IOUSBLib is permissive about this — it'll accept an iso transfer with the interface in its default alt setting. Linux's
usbfsrequires an explicitSET_INTERFACEioctl to reserve iso bandwidth for the endpoint; without it the URB submission returnsEINVALand the Chromium USB utility process crashes (this isn't a graceful JS-level rejection on Linux — it kills the worker process).Suggested fix
Add an explicit alt-setting selection after the claim:
libfreenect
src/cameras.ccallslibusb_set_interface_alt_setting(udev->cam, 0, 0)for the camera interface, so alt0is the right starting point. Worth verifying against the device's USB descriptor in case the iso endpoints actually live on a different alt — if so, use that one.Notes
macOS users won't observe a regression after this fix lands; it's a no-op on platforms that already tolerate the missing call.