TITLE:
Kinect v2 detected on Apple M4 / macOS, but start() fails with LIBUSB_ERROR_TIMEOUT and 0-byte bulk transfer
BODY:
Hi,
I’m trying to get a Kinect v2 working on an Apple Silicon MacBook Pro with an Apple M4 chip.
After extensive testing, I’ve managed to compile and run libfreenect2/Protonect under x86_64/Rosetta. The Kinect is correctly detected and opened, but it consistently fails during Freenect2DeviceImpl::start() with a zero-length bulk transfer followed by LIBUSB_ERROR_TIMEOUT.
Hardware / setup
- MacBook Pro with Apple M4
- Kinect v2 / Xbox NUI Sensor
- Kinect serial:
351859433947
- Kinect external power supply connected
- Tested multiple physical USB ports
- USB connection confirmed as SuperSpeed 5 Gb/s
IOKit reports:
Xbox NUI Sensor
USB Vendor Name = Microsoft
USBSpeed = 4
UsbLinkSpeed = 5000000000
bcdUSB = 768
idVendor = 1118
idProduct = 708
USB Serial Number = 351859433947
UsbHostControllerProtocolRevision = 3.1
So the Kinect is negotiating at 5 Gb/s (USB 3 SuperSpeed), not USB 2.0.
What I have tried
1. openFrameworks + ofxMultiKinectV2
I initially tried using:
- openFrameworks
- ofxMultiKinectV2
- ofxTurboJpeg
- bundled libfreenect2 from ofxMultiKinectV2
- bundled
usb-1.0.0-superspeed.a
The old addon libraries contain x86_64 support:
libfreenect2.a:
Architectures: i386 x86_64
usb-1.0.0-superspeed.a:
Architectures: x86_64 i386
Getting this old project to compile on the M4 required fixing several compatibility issues:
- Missing openFrameworks dependencies / XCFrameworks
- Missing ofxTurboJpeg
- Old compiler settings incompatible with Apple M4 when targeting x86_64
- Two non-void functions in
ofProtonect2.h returning no value
- Old TurboJPEG dylib paths
- Obsolete FMOD Ex and GLUT references/copy steps
- Compatibility issues in the old Xcode project
Eventually the project successfully compiled:
The application runs under Rosetta and detects the Kinect:
Device Count : 1
device serial: 351859433947
However, initialization fails with:
[Error] [protocol::CommandTransaction] bulk transfer failed: LIBUSB_ERROR_TIMEOUT Operation timed out
device serial: 351859433947
device firmware: <unknown>
The application therefore opens but does not receive Kinect data.
2. Modern libfreenect2 test
To rule out openFrameworks and ofxMultiKinectV2, I then cloned libfreenect2 separately and built Protonect.
I specifically wanted to test a modern version of libusb instead of the very old usb-1.0.0-superspeed.a bundled with ofxMultiKinectV2.
Homebrew libusb
Homebrew installed:
libusb 1.0.30
/opt/homebrew/opt/libusb
However, this library is ARM64.
When trying to build libfreenect2 as x86_64, the linker reported:
ld: warning: ignoring file '/opt/homebrew/opt/libusb/lib/libusb-1.0.dylib': found architecture 'arm64', required architecture 'x86_64'
This resulted in all the expected libusb symbols being unavailable.
Building libusb 1.0.30 manually for x86_64
I then cloned libusb v1.0.30 and built it manually for x86_64 using:
CFLAGS="-arch x86_64" \
CXXFLAGS="-arch x86_64" \
LDFLAGS="-arch x86_64" \
./configure \
--prefix="$HOME/Downloads/libusb-x86" \
--disable-shared \
--enable-static
The resulting library is confirmed as:
Non-fat file: /Users/brendancassidy/Downloads/libusb-x86/lib/libusb-1.0.a is architecture: x86_64
Version:
I then configured libfreenect2 to use this x86_64 libusb instead of the ARM64 Homebrew installation.
Because the static libusb build requires macOS frameworks, the initial link failed with missing symbols including:
_IOCreatePlugInInterfaceForService
_IOIteratorNext
_IOKitWaitQuiet
_IONotificationPortCreate
_IOObjectRelease
_IORegistryEntryCreateCFProperty
_IOServiceAddMatchingNotification
_IOServiceAuthorize
_SecTaskCopyValueForEntitlement
_SecTaskCreateFromSelf
I resolved this by linking:
-framework IOKit
-framework CoreFoundation
-framework Security
-lobjc
After that, modern libfreenect2 and Protonect successfully compiled:
[ 92%] Built target freenect2
[100%] Linking CXX executable ../bin/Protonect
[100%] Built target Protonect
3. Protonect test with modern libfreenect2 + libusb 1.0.30 x86_64
I run Protonect through Rosetta using:
arch -x86_64 ./bin/Protonect
The Kinect is correctly enumerated:
[Info] [Freenect2Impl] enumerating devices...
[Info] [Freenect2Impl] 1 usb devices connected
[Info] [Freenect2Impl] found valid Kinect v2 @1:1 with serial 351859433947
[Info] [Freenect2Impl] found 1 devices
OpenCL also initializes successfully:
[Info] [OpenCLDepthPacketProcessorImpl] devices:
[Info] [OpenCLDepthPacketProcessorImpl] 0: Apple M4 (CPU)[Intel]
[Info] [OpenCLDepthPacketProcessorImpl] 1: Apple M4 (GPU)[Apple]
[Info] [OpenCLDepthPacketProcessorImpl] selected device: Apple M4 (GPU)[Apple]
[Info] [OpenCLDepthPacketProcessorImpl] building OpenCL program...
[Info] [OpenCLDepthPacketProcessorImpl] OpenCL program built successfully
The Kinect opens successfully:
[Info] [Freenect2DeviceImpl] opening...
[Info] [Freenect2DeviceImpl] transfer pool sizes rgb: 20*16384 ir: 4*128*33792
[Info] [Freenect2DeviceImpl] opened
However, it fails immediately during start():
[Info] [Freenect2DeviceImpl] starting...
[Error] [protocol::CommandTransaction] bulk transfer too short! expected at least: 1302572 got : 0
[Info] [Freenect2DeviceImpl] closing...
[Error] [protocol::CommandTransaction] bulk transfer failed: LIBUSB_ERROR_TIMEOUT Operation timed out
[Error] [protocol::CommandTransaction] bulk transfer failed: LIBUSB_ERROR_TIMEOUT Operation timed out
[Error] [protocol::CommandTransaction] bulk transfer failed: LIBUSB_ERROR_TIMEOUT Operation timed out
[Info] [Freenect2DeviceImpl] releasing usb interfaces...
[Info] [Freenect2DeviceImpl] deallocating usb transfer pools...
[Info] [Freenect2DeviceImpl] closing usb device...
[Info] [Freenect2DeviceImpl] closed
4. CPU pipeline test
To rule out OpenCL / Apple GPU compatibility, I also ran:
arch -x86_64 ./bin/Protonect cpu
The Kinect is again detected and opened successfully:
[Info] [Freenect2Impl] 1 usb devices connected
[Info] [Freenect2Impl] found valid Kinect v2 @1:2 with serial 351859433947
[Info] [Freenect2Impl] found 1 devices
[Info] [Freenect2DeviceImpl] opening...
[Info] [Freenect2DeviceImpl] transfer pool sizes rgb: 20*16384 ir: 4*128*33792
[Info] [Freenect2DeviceImpl] opened
[Info] [Freenect2DeviceImpl] starting...
But the exact same error occurs:
[Error] [protocol::CommandTransaction] bulk transfer too short! expected at least: 1302572 got : 0
[Info] [Freenect2DeviceImpl] closing...
[Error] [protocol::CommandTransaction] bulk transfer failed: LIBUSB_ERROR_TIMEOUT Operation timed out
[Error] [protocol::CommandTransaction] bulk transfer failed: LIBUSB_ERROR_TIMEOUT Operation timed out
[Error] [protocol::CommandTransaction] bulk transfer failed: LIBUSB_ERROR_TIMEOUT Operation timed out
Therefore, the problem does not appear to be related to OpenCL or GPU processing.
5. libusb debug output
I also enabled detailed libusb logging.
Immediately before the libfreenect2 error I get:
libusbx: debug [darwin_async_io_callback] an async io operation has completed
libusbx: debug [handle_events] poll() returned 1
libusbx: debug [darwin_handle_callback] handling bulk completion with kernel status -536854447
libusbx: warning [darwin_transfer_status] transfer error: timed out
libusbx: debug [sync_transfer_cb] actual_length=0
[Error] [protocol::CommandTransaction] bulk transfer failed: LIBUSB_ERROR_TIMEOUT Operation timed out
So the USB operation reaches the Darwin callback, but completes with a timeout and actual_length=0.
6. USB connection / different ports
I tested multiple physical USB ports on the Mac.
Depending on the port/reconnection, libfreenect2 reports locations such as:
found valid Kinect v2 @3:1
found valid Kinect v2 @1:1
and:
found valid Kinect v2 @1:2
The failure is identical in every case.
IOKit correctly detects the device as:
Xbox NUI Sensor
USB Vendor Name = Microsoft
and reports:
USBSpeed = 4
UsbLinkSpeed = 5000000000
The relevant IOKit information is:
"USBSpeed" = 4
"UsbLinkSpeed" = 5000000000
"idProduct" = 708
"bcdUSB" = 768
"kUSBSerialNumberString" = "351859433947"
"USB Product Name" = "Xbox NUI Sensor"
"USB Vendor Name" = "Microsoft"
"idVendor" = 1118
"USB Serial Number" = "351859433947"
The host controller reports:
UsbHostControllerProtocolRevision = "3.1"
So the Kinect is definitely negotiating at USB 3 SuperSpeed / 5 Gb/s rather than falling back to USB 2.0.
Current state
At this point I believe I have ruled out:
- ofxMultiKinectV2 itself
- the old bundled libusb
- OpenCL / GPU processing
- accidental USB 2.0 negotiation
- one specific physical USB port
- inability to enumerate the Kinect
- inability to open the Kinect
The device can successfully:
- Be enumerated
- Be identified as a Kinect v2
- Return its serial number
- Be opened by libfreenect2
- Allocate its USB transfer pools
The failure consistently occurs during:
Freenect2DeviceImpl::start()
The critical error is:
[Error] [protocol::CommandTransaction] bulk transfer too short! expected at least: 1302572 got : 0
followed by:
[Error] [protocol::CommandTransaction] bulk transfer failed: LIBUSB_ERROR_TIMEOUT Operation timed out
This happens both with the old ofxMultiKinectV2 setup and with a separate modern libfreenect2 build using libusb 1.0.30 compiled specifically for x86_64.
Questions
Has anyone successfully used a Kinect v2 with libfreenect2 on an Apple M4 Mac with a recent version of macOS?
More specifically:
-
Is this a known issue with libusb's Darwin backend / IOUSBHost on Apple Silicon or recent versions of macOS?
-
Could running x86_64 libusb/libfreenect2 through Rosetta cause this kind of USB bulk transfer failure even though device enumeration, serial access and opening all work correctly?
-
Does the expected at least: 1302572 got: 0 transaction correspond to a specific Kinect initialization command that could help identify exactly where communication is failing?
-
Is there a known patch or workaround for modern Apple Silicon USB controllers / IOUSBHost?
-
Would building libfreenect2 and its dependencies natively for ARM64 potentially behave differently at the USB layer?
-
Is there additional libfreenect2/libusb debugging I can enable to see the exact endpoint, command and transaction that is timing out?
-
Is there anything else worth testing before concluding that this is an incompatibility between the Kinect v2 USB protocol and the current Apple Silicon/macOS USB stack?
I’m happy to test patches, instrument CommandTransaction, rebuild libusb/libfreenect2, or provide the complete libusb debug logs.
Any help would be greatly appreciated.
Thanks!
TITLE:
Kinect v2 detected on Apple M4 / macOS, but start() fails with LIBUSB_ERROR_TIMEOUT and 0-byte bulk transfer
BODY:
Hi,
I’m trying to get a Kinect v2 working on an Apple Silicon MacBook Pro with an Apple M4 chip.
After extensive testing, I’ve managed to compile and run libfreenect2/Protonect under x86_64/Rosetta. The Kinect is correctly detected and opened, but it consistently fails during
Freenect2DeviceImpl::start()with a zero-length bulk transfer followed byLIBUSB_ERROR_TIMEOUT.Hardware / setup
351859433947IOKit reports:
So the Kinect is negotiating at 5 Gb/s (USB 3 SuperSpeed), not USB 2.0.
What I have tried
1. openFrameworks + ofxMultiKinectV2
I initially tried using:
usb-1.0.0-superspeed.aThe old addon libraries contain x86_64 support:
Getting this old project to compile on the M4 required fixing several compatibility issues:
ofProtonect2.hreturning no valueEventually the project successfully compiled:
The application runs under Rosetta and detects the Kinect:
However, initialization fails with:
The application therefore opens but does not receive Kinect data.
2. Modern libfreenect2 test
To rule out openFrameworks and ofxMultiKinectV2, I then cloned libfreenect2 separately and built Protonect.
I specifically wanted to test a modern version of libusb instead of the very old
usb-1.0.0-superspeed.abundled with ofxMultiKinectV2.Homebrew libusb
Homebrew installed:
However, this library is ARM64.
When trying to build libfreenect2 as x86_64, the linker reported:
This resulted in all the expected libusb symbols being unavailable.
Building libusb 1.0.30 manually for x86_64
I then cloned libusb v1.0.30 and built it manually for x86_64 using:
The resulting library is confirmed as:
Version:
I then configured libfreenect2 to use this x86_64 libusb instead of the ARM64 Homebrew installation.
Because the static libusb build requires macOS frameworks, the initial link failed with missing symbols including:
I resolved this by linking:
After that, modern libfreenect2 and Protonect successfully compiled:
3. Protonect test with modern libfreenect2 + libusb 1.0.30 x86_64
I run Protonect through Rosetta using:
The Kinect is correctly enumerated:
OpenCL also initializes successfully:
The Kinect opens successfully:
However, it fails immediately during
start():4. CPU pipeline test
To rule out OpenCL / Apple GPU compatibility, I also ran:
The Kinect is again detected and opened successfully:
But the exact same error occurs:
Therefore, the problem does not appear to be related to OpenCL or GPU processing.
5. libusb debug output
I also enabled detailed libusb logging.
Immediately before the libfreenect2 error I get:
So the USB operation reaches the Darwin callback, but completes with a timeout and
actual_length=0.6. USB connection / different ports
I tested multiple physical USB ports on the Mac.
Depending on the port/reconnection, libfreenect2 reports locations such as:
and:
The failure is identical in every case.
IOKit correctly detects the device as:
and reports:
The relevant IOKit information is:
The host controller reports:
So the Kinect is definitely negotiating at USB 3 SuperSpeed / 5 Gb/s rather than falling back to USB 2.0.
Current state
At this point I believe I have ruled out:
The device can successfully:
The failure consistently occurs during:
The critical error is:
followed by:
This happens both with the old ofxMultiKinectV2 setup and with a separate modern libfreenect2 build using libusb 1.0.30 compiled specifically for x86_64.
Questions
Has anyone successfully used a Kinect v2 with libfreenect2 on an Apple M4 Mac with a recent version of macOS?
More specifically:
Is this a known issue with libusb's Darwin backend / IOUSBHost on Apple Silicon or recent versions of macOS?
Could running x86_64 libusb/libfreenect2 through Rosetta cause this kind of USB bulk transfer failure even though device enumeration, serial access and opening all work correctly?
Does the
expected at least: 1302572 got: 0transaction correspond to a specific Kinect initialization command that could help identify exactly where communication is failing?Is there a known patch or workaround for modern Apple Silicon USB controllers / IOUSBHost?
Would building libfreenect2 and its dependencies natively for ARM64 potentially behave differently at the USB layer?
Is there additional libfreenect2/libusb debugging I can enable to see the exact endpoint, command and transaction that is timing out?
Is there anything else worth testing before concluding that this is an incompatibility between the Kinect v2 USB protocol and the current Apple Silicon/macOS USB stack?
I’m happy to test patches, instrument
CommandTransaction, rebuild libusb/libfreenect2, or provide the complete libusb debug logs.Any help would be greatly appreciated.
Thanks!