Repository navigation
Conversation
c_sync, the C++ wrapper and the threaded examples needed pthreads-win32 on Windows, and configuring failed without it (OpenKinect#655, OpenKinect#647, OpenKinect#561). Add platform/windows/pthread/pthread.h, a header-only subset of POSIX threads built on native SRW locks, condition variables and _beginthreadex. It covers exactly the calls the tree uses: create, join, mutex init/lock/trylock/unlock/destroy, and cond init/wait/signal/broadcast/destroy, including the static initialisers. It needs no import library. FindThreads.cmake still prefers a real pthreads-win32 when one is installed. Otherwise it points THREADS_PTHREADS_INCLUDE_DIR at the subset and leaves CMAKE_THREAD_LIBS_INIT empty, so no CMakeLists or source file has to change.
- With MSVC, the static freenectstatic and freenect_sync_static libraries were written to freenect.lib and freenect_sync.lib, which are also the import libraries of freenect.dll and freenect_sync.dll. Whichever linked last won, and parallel builds failed with LNK1104. On MSVC the static libraries are now freenect_static.lib and freenect_sync_static.lib; other platforms keep their names. - Findlibusb-1.0.cmake also accepts the library name libusb-1.0, which vcpkg and the official Windows binaries ship (libusb-1.0.lib). Before, CMake could not find libusb on Windows without -DLIBUSB_1_LIBRARY (OpenKinect#647). - regtest opened its image files with "w", which is text mode on Windows, so every 0x0A byte became 0x0D 0x0A and all four images were corrupt. It now uses "wb".
With WinUSB, Microsoft's in-box driver, libfreenect streams from user mode on Windows 11 with Memory integrity enabled, where the Kinect for Windows SDK's kernel driver is blocked. This needs libusb 1.0.26 or newer: WinUSB isochronous support arrived in 1.0.23, and 1.0.24 and 1.0.25 had a Windows isochronous regression. - fnusb_start_iso() returned 0 even when no transfer could be submitted, as happens with a libusb0 driver, so streams stayed silently black. It now frees everything and returns the libusb error when nothing is in flight, warns when only some transfers start, and explains LIBUSB_ERROR_NOT_SUPPORTED (wrong driver, or Windows older than 8.1) and LIBUSB_ERROR_ACCESS. - iso_callback() passed every packet to the stream parser without checking the packet's own status. Packets that failed or were never filled were parsed as data, causing "Invalid magic" errors and resyncs that also discarded good frames. They are now passed on as empty, so the parser counts them as lost through the sequence numbers. This applies to all platforms. - fnusb_stop_iso() skips transfers that were never allocated, and waits at most 3 s (in 100 ms steps) for cancellations instead of forever. Transfers still outstanding after that are leaked rather than freed while libusb may still own them. - Windows keeps 16 transfers of 32 packets in flight (64 ms per stream, up from 32 ms). PKTS_PER_XFER % 8 == 0, which WinUSB requires, and PKTS_PER_XFER * NUM_XFERS <= 1000 are now compile-time checks. - freenect_init() logs the libusb version and warns on Windows below 1.0.26. - LIBFREENECT_USBDK=1 opts in to libusb's UsbDk backend on Windows. Hardware test on Windows 11, Xbox 360 Kinect (1414), libusb 1.0.30: camtest streams depth and video; with the failed-packet change, video went from 7.4% to 0% of frames missing.
In a hardware test on Windows 11 (WinUSB, Xbox 1414 with audios.bin), the audio isochronous streams reported LIBUSB_TRANSFER_STALL. The outstanding transfers were never completed by the kernel, so the process could not be terminated, and Windows hung during restart because shutdown waits for that I/O. The machine had to be hard-reset. Until the audio path is understood on Windows, freenect_start_audio() returns -1 there with an explanation, unless LIBFREENECT_WINDOWS_AUDIO_UNSAFE=1 is set. The check runs before anything is allocated or submitted. Camera, motor, LED, accelerometer and the firmware upload are unaffected, and stopped cleanly in the same tests. Also: if the audio OUT stream fails to start, stop the IN stream that was already started. micview checks the result of freenect_start_audio() and exits instead of running without audio.
In a hardware test on Windows 11 (Xbox 1414), the camera failed to initialise with "send_cmd: Bad cmd 03 != 16" and kept failing on every run. send_cmd() took the first reply the camera returned and failed hard if its cmd or tag did not match; the camera's actual reply was left unread and returned for the next command, so from then on every command read the previous command's reply. - Before sending, discard replies that are already waiting (up to 8), with a warning. - After sending, skip replies whose cmd or tag does not match and keep waiting for the matching one (at most 8, then fail). - Give up after 2 s of wall-clock time (GetTickCount64 or CLOCK_MONOTONIC) instead of polling forever. Counting polls does not work: on Windows each 1 ms sleep lasts about 15 ms. - A failing IN transfer returns its own error code instead of the OUT transfer's result. Tested against a simulated camera channel (the real flags.c with fnusb_control stubbed): a stale cmd 0003 reply before cmd 0016, a channel that stays one reply out of step, a late unrelated reply, and a camera that never answers, which times out after 2000 ms. On the Kinect, camtest started reliably in repeated runs afterwards.
On Windows 11 with Memory integrity enabled, the Kinect for Windows SDK camera driver is blocked, and Zadig is a manual, per-device step. freenect-driver-install binds every Kinect v1 function libfreenect drives to Microsoft's in-box WinUSB driver in one command. It uses only documented Windows APIs and adds no third-party dependency. --install (Administrator): - Writes %ProgramData%\libfreenect\driver\libfreenect-kinect.inf, which references only the in-box winusb.inf (Include/Needs WINUSB.NT), so no binaries or co-installers are shipped. - Builds a catalog for it with the CryptCAT API. The member is hashed with SHA-1, because the driver store looks package files up by their SHA-1 hash and rejects a SHA-256-only catalog with ERROR_FILE_HASH_NOT_IN_CATALOG. The catalog signature is SHA-256. - Creates a self-signed code-signing certificate, signs the catalog with it, and deletes the private key immediately, so the certificate that is trusted can never sign anything else. - Adds the certificate to the local machine Root and TrustedPublisher stores, stages the package with SetupCopyOEMInf, and installs it on every present Kinect function (UpdateDriverForPlugAndPlayDevices, non-interactive). Functions that appear later, such as the camera and audio of the Xbox 1414 once the motor has a driver, pick it up from the driver store automatically. --uninstall removes the Kinect device nodes, then every package (recognised by its catalog name) and certificate the tool added, and rescans, so no device is left bound to a deleted package. --list shows the Kinect functions, their drivers and every device on the Kinect's hub, with problem codes, and needs no elevation. --package-only DIR builds and signs a package without changing the system. Bound: camera 02AE/02BF, motor 02B0/02AF, audio controller 02AD/02BE, and only interfaces 0 and 1 of 02BB/02C3, so the microphone-array interfaces keep usbaudio.sys. CMake option BUILD_DRIVER_INSTALLER, on by default on Windows. The README's Windows section now describes the tool, libusb >= 1.0.26, and WinUSB instead of libusbK via Zadig. Hardware test on Windows 11 with Memory integrity on, Xbox 1414: --install, --list, --uninstall and reinstalling all work, and the camera, motor and audio functions end up on WinUSB.
upload_firmware() searched only POSIX locations. On Windows it now also searches %LOCALAPPDATA%\libfreenect, the directory of the executable, and %ProgramData%\libfreenect; the existing locations keep their order. The search is a plain list of directories, which also fixes two leaks (the firmware buffer was never freed, and the FILE was not closed for an empty file). A missing file returns -ENOENT and says where to put it. freenect-fwloader uploads the firmware to every connected Kinect whose audio controller is still in its bootloader, using only the public API (opening a device with FREENECT_DEVICE_AUDIO uploads and waits for re-enumeration). --firmware FILE uses a specific image. Hardware test on Windows 11, Xbox 1414: the firmware uploads and launches; a second run finds it already running.
tiltdemo looped forever with no handler, so Ctrl+C killed it in the
middle of USB transfers. wavrecord caught only SIGINT and never stopped
audio or closed the device. On Windows, signal() never sees the console
window being closed.
examples/console_exit.h gives the console examples one shutdown path:
- POSIX: SIGINT, SIGTERM, SIGHUP and SIGQUIT request exit.
- Windows: SetConsoleCtrlHandler for Ctrl+C, Ctrl+Break, window close,
logoff and shutdown; for the last three, the handler holds the
process for up to 4 s until main() has stopped the streams and closed
the device.
- fn_sleep_ms() sleeps in 100 ms steps and returns early on exit.
camtest and wavrecord poll with freenect_process_events_timeout()
(100 ms). wavrecord stops audio and closes the device before
freenect_shutdown(). tiltdemo calls freenect_sync_stop() on exit.
camtest accepts an optional run time in seconds ("freenect-camtest 20")
and then prints the depth and video frame rates.
Hardware test on Windows 11, Xbox 1414: camtest and tiltdemo stop on
Ctrl+C and when their window is closed.
platform/windows/inf ships libusb0 (libusb-win32) driver packages from 2010. libusb0 cannot do the isochronous transfers that video and depth need with current libusb, and its catalogs are not accepted on current Windows. freenect-driver-install replaces them. platform/windows/libusb10emu is a libusb-1.0 emulation on top of libusb-win32 that no CMakeLists.txt refers to. platform/windows/README.TXT described it and is replaced by platform/windows/README.md.
The workflow builds the library, the C sync and C++ wrappers and all examples, including the OpenGL viewers, on: - Windows x64 and ARM64 with MSVC, with libusb and freeglut from vcpkg; - Ubuntu 24.04 on x86_64 and arm64; - macOS on Apple Silicon. Smoke tests that need no Kinect: freenect-fwloader must report that no Kinect is present. On Windows x64, freenect-driver-install --list must work, and --package-only must produce a catalog signed by the package certificate with its key destroyed. The Windows jobs upload their binaries as artifacts (OpenKinect#622). vcpkg.json declares libusb, and freeglut for the examples behind the "examples" feature, so a Windows build needs only the vcpkg toolchain file (OpenKinect#660).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The Kinect for Windows SDK's camera driver (
kinectcamera.sys) no longer loads on Windows 11 with Memory integrity (core isolation) enabled, so the Kinect v1 has no working driver there. This PR makes libfreenect the replacement:winusb.sys, and everything else runs in user mode through libusb.Tested on Windows 11 with Memory integrity on, with an Xbox 360 Kinect (model 1414). Results are under "Testing" below.
Changes, one commit each
FindThreads.cmakestill prefers the real library.freenect.lib,freenect_sync.lib). That also fixes LNK1104 in parallel builds.Findlibusb-1.0.cmakenow findslibusb-1.0.lib, as shipped by vcpkg and the official binaries (Libfreenect Solution Build Error-Windows #647).regtestwrites its images in binary mode; text mode corrupted them on Windows.fnusb_start_iso()reports failure instead of streaming silently black.fnusb_stop_iso()can't wait forever.LIBFREENECT_USBDK=1).LIBFREENECT_WINDOWS_AUDIO_UNSAFE=1is set. In testing, stalled audio isochronous transfers were never completed by the kernel, which left the process unkillable and hung Windows shutdown. Camera, motor, LED and accelerometer are unaffected.send_cmdresynchronises the camera command channel (all platforms).freenect-driver-install.winusb.inf, builds and signs its catalog with a one-off local certificate whose private key is destroyed immediately, trusts that certificate, and installs the package.--list,--uninstalland--package-onlyare included.usbaudio.sys.freenect-fwloaderuploads it to every connected Kinect. This also fixes two leaks inupload_firmware().SetConsoleCtrlHandler.camtestalso accepts a run time in seconds and prints frame rates.platform/windows/inf(libusb0 packages) and the unusedlibusbemulayer. This commit is separate in case you'd rather keep them.Every commit builds on its own with MSVC.
Testing
Hardware: Windows 11, Memory integrity on, Xbox 360 Kinect (1414) with its power adapter, libusb 1.0.30, MSVC 2026.
freenect-driver-install --install/--list--uninstall, then--installagain without repluggingfreenect-camtest 20freenect-tiltdemofreenect-regtestfreenect-fwloaderThe
send_cmdrecovery was also tested against a simulated camera command channel: a stale reply, a channel one reply out of step, a late unrelated reply, and a camera that never answers.CI is green on all jobs in the fork.
Known limitations
freenect-driver-installdownload Microsoft's audio firmware (UAC.BIN) from Microsoft's official Kinect Runtime installer on the user's machine, verify it, and load it. That turns the mics into a standard USB Audio device handled by Windows' own audio driver, and nothing of Microsoft's is redistributed.Notes for reviewers
--installadds a locally generated certificate to the machine's Trusted Root and Trusted Publishers stores, as Zadig and libwdi do. Windows requires the driver package to be signed by a trusted publisher. The private key is destroyed right after the catalog is signed, so that certificate can't sign anything else, and--uninstallremoves it.send_cmdresynchronises;