Depth and infrared arrive frame after frame, then the moment the script enables color, every frame-wait dies with a timeout raised at 5000 ms — and it only happens inside a virtual machine. That combination is rarely a code bug; it is the link. Color is the heaviest stream a depth camera produces, a laptop hypervisor frequently hands the camera a USB 2 connection without telling you, and USB 2 cannot carry depth and color together at 30 fps. This guide gives you the payload arithmetic, a three-test diagnosis that separates cable from port from hypervisor, and the fix for each case: a whole USB 3 controller passed to the guest, a lighter stream format when USB 2 is unavoidable, or native hardware once the project leaves the bench.
Why does color time out while depth streams fine?
Because depth plus color at 640×480 and 30 fps needs about 369 Mbps of payload while a healthy USB 2 link carries roughly 280–320 Mbps in practice, and any single USB 2 video endpoint tops out near 197 Mbps — a ceiling the color stream alone already exceeds.
The pipeline is doing its job: it asks the driver for a synchronized depth-color pair, the color endpoint never gets scheduled onto the wire, and after five seconds the wait raises. Depth keeps flowing the whole time, which is why the fault looks like a color-specific bug in your code. It is a capacity problem, and capacity problems have arithmetic answers. The table below is the whole diagnosis in one place.
| Stream | Pixel format | Bytes per pixel | 640 × 480 at 30 fps |
|---|---|---|---|
| Depth | 16-bit depth | 2 | 147 Mbps |
| Color | 24-bit RGB | 3 | 221 Mbps |
| Infrared | 8-bit gray | 1 | 74 Mbps |
How much bandwidth do my streams actually need?
Multiply width × height × bytes per pixel × frame rate × 8: at 640×480 and 30 fps that is 147 Mbps for 16-bit depth, 221 Mbps for 24-bit color and 74 Mbps for 8-bit infrared, and the depth-color pair at 369 Mbps oversubscribes any USB 2 link.
Two corrections turn a line rate into a usable budget. USB 2's 480 Mbps is signaling, not payload: transaction overhead and bit-stuffing leave roughly 280–320 Mbps of measured throughput on a healthy controller. And a video stream delivered as isochronous traffic — the delivery style USB 2 video uses — is capped per endpoint at 1024 bytes × 3 transactions × 8000 microframes per second = 24.6 MB/s, about 197 Mbps, however idle the rest of the bus looks. Run the formula with your own resolution and frame rate; halving fps halves every row.
If your budget comes out comfortable and color still times out, the fault is in delivery rather than capacity: the depth and color stream timeout bandwidth check walks that branch. The same budget decides frame rate once streams do flow — see why a USB hub drops camera frame rate.
Why does a USB 2 link carry depth but refuse color?
Depth alone is 147 Mbps, comfortably under the ~197 Mbps per-endpoint ceiling, and infrared adds only 74 Mbps, so both fit; 24-bit color is 221 Mbps, which is over the ceiling before depth claims a single microframe.
That asymmetry reproduces every symptom in the classic report. Depth-only streams. Depth plus infrared streams. Color shows up in the camera maker's viewer because most viewers fall back to the camera's compressed color format on a slow link, and the compressed picture fits; the same viewer times out the moment a script names an uncompressed 24-bit format. Nothing is wrong with the color sensor or the driver. Put both uncompressed streams on one USB 2 wire and the color endpoint has no bandwidth left to be scheduled into.
If your timeout also fires on depth alone, or fires while frames clearly do arrive, that is a different failure: the frame didn't arrive within timeout fix covers the code pattern, and it is worth ruling out before you touch hardware.
Is it the cable, the port or the hypervisor?
Diagnose in this order and stop at the first test that changes the outcome: read the negotiated USB speed in the SDK's device panel, swap in a known USB 3 cable of 1–2 m straight into a host port, then run color-only on bare metal outside the VM.
- Read the negotiated speed. The SDK's device information panel or the viewer's info page prints the USB type the camera enumerated at. USB 2.x there predicts every symptom in this guide; USB 3.x sends you to the format and passthrough checks instead.
- Swap the cable. Use a cable sold as USB 3 or full-featured USB-C, 1–2 m, straight into a host port. Charge-only USB-C cables carry no SuperSpeed pairs at all, and a cable that enumerates at USB 3 today and USB 2 tomorrow is worn or noncompliant. How length and data rate interact is covered in USB-C cable timeouts on a USB3 camera.
- Remove the hub. A powered hub renegotiates its own upstream link and hands many cameras a USB 2 downstream port; the depth camera that refuses to stream through a hub is the same physics one layer down.
- Test bare metal. Boot the same machine into native Linux from a live USB stick and stream color-only. If color flows there and times out only in the guest, the hypervisor's USB handling is the remaining suspect.
Work the list in order: cable first, then port or hub, then passthrough. A failed color sensor is the least likely cause by a wide margin — it is a separate sensor that has either enumerated or not, and your device panel answered that in test 1.
How do I get a USB 3 link inside the virtual machine?
Attach the entire USB controller to the guest rather than the camera as a single device: with the platform's IOMMU feature enabled, the hypervisor hands the guest a real host controller and the camera enumerates at USB 3 with no scheduler in the frame path.
Per-device passthrough is the default in desktop hypervisors, and it is the fragile path for video: every isochronous transfer crosses the virtual host controller, and streaming devices are exactly where hypervisor support threads report dropouts and distortion. Controller-level passthrough is what the enterprise documentation prescribes when a USB video device will not initialize or stream in a guest. Enable IOMMU in the firmware set-up, assign the whole controller to the guest, and the camera then enumerates on real silicon at full speed.
Keep the wire short once the controller is passed through. Passive USB 3 copper holds its SuperSpeed pairs for about 3 m; beyond that, errors climb and links renegotiate downward, which quietly returns you to the USB 2 budget. The USB cable length limits for 3D cameras guide maps where each length stops working. For the desk bench, this is the part that ends the problem for good:
The LS-CBL-0219 is a 3 m USB3.0 camera cable with high-flex, drag-chain construction. Three metres sits well inside passive copper's reliable reach, and the drag-chain build survives the move from bench to cell.
What can I change if the link stays on USB 2?
Cut the payload until it fits the 197 Mbps endpoint ceiling and the ~300 Mbps bus: request the camera's compressed color format instead of raw 24-bit frames, or drop the frame rate to 15 fps, which halves every stream to 184 Mbps combined.
Compressed color does the same job with the frame rate untouched. Motion-JPEG-class formats move the same view in a fifth to a tenth of the raw payload in practice; the stream's format argument selects it, and most viewers request it automatically on a slow link, which is why the viewer picture arrived while your script's did not. The cost is compression softening around edges — acceptable for preview, detection and geometry, rarely acceptable for color measurement. If the task needs no color at all, the 8-bit infrared stream at 74 Mbps is spare capacity for edge-based work.
When should I leave the VM for real hardware?
Move the camera to native Linux on a small dedicated controller as soon as the project is heading for a production cell: bare metal removes the hypervisor from the frame path entirely, and a GigE depth camera removes the 3 m cable ceiling along with the bandwidth fight.
A virtual machine on a laptop is a fine algorithm bench and a poor imaging platform: virtual scheduling adds jitter, USB behavior varies between hypervisor builds, and you are debugging two operating systems' views of one wire. A fanless industrial mini PC running the vision OS natively deletes this entire problem class — the camera enumerates directly on real hardware, at real speed.
GigE changes the distance math as well as the bandwidth math: a GigE camera holds 100 m on one cable run, so mounting distance stops being a budget item at all. Pick the interface the cell can wire, then match the cable to it:
- Type
- Camera data cables
- Length
- 15 m
The LS-CBL-0117 is a 15 m RJ45 camera data cable with a locking stud.
On the camera side, the 3D sensors category groups laser profilers, stereo and structured-light units, and the camera finder filters them by type. For a fixed-mount measurement cell, this is the class of camera to look at first:
- Type
- Stereo / structured light
The MV-DPS200P-02 is a projected structured-light 3D camera.
What do I check before ordering the fix?
Confirm three things before anything ships: the negotiated speed today, the cable's USB 3 rating and length, and your platform's controller-passthrough support — then buy once instead of iterating through three cables that all enumerate at USB 2.
On the bench today
- Negotiated USB speed in the SDK's device panel — the one value every later step depends on; USB 2.x explains the whole symptom.
- Stream budget for your resolution, format and frame rate — if depth plus color exceeds about 197 Mbps per endpoint, no cable rescues it.
- Color-only probe — enables color without depth and separates a failed endpoint from a shared-budget failure.
Cable and port
- USB 3-rated cable, 1–2 m, straight into a host port — charge-only USB-C cables look identical and carry none of the data.
- No hub in the path until the camera streams at speed; add it back only with the speed re-checked.
Virtual machine
- IOMMU enabled in firmware and the whole controller assigned to the guest — per-device passthrough is the path that drops video.
- The guest sees its own host controller, not just a device — otherwise every frame still crosses the virtual scheduler.
If USB 2 is final
- Compressed color format or 15 fps — one of the two always fits; the uncompressed 24-bit pair never does.
Once the negotiated speed reads USB 3 in the guest, enable color in the same script that streamed depth before — the wait that raised at 5000 ms stops raising. Pick the camera and cable together in the system configurator, send awkward numbers through the contact page, or browse more link-level fixes on the systems topic page.
Questions
Does a USB 2 link also break the infrared stream?
No. An 8-bit infrared stream at 640×480 and 30 fps is 640 × 480 × 1 byte × 30 × 8 = 74 Mbps, and 16-bit depth beside it stays at 147 Mbps, so both endpoints fit individually under the roughly 197 Mbps USB 2 ceiling and the pair fits the bus budget. That is exactly why depth-plus-infrared runs on the same link where color fails: infrared is one byte per pixel, color is three.
Can I fix this by raising the frame-wait timeout above 5000 ms?
No. The 5 s limit is the library's default wait, but the color frames are never delivered at all, so a longer wait only produces the same error later. Raise timeouts when frames arrive slowly; leave them alone when a whole stream is missing. Fix the link or the stream budget, and the default 5 s wait is generous again.
How do I confirm which USB speed the camera negotiated?
Open your camera SDK's device information panel or the viewer's info page: it prints the negotiated USB type, 2.x or 3.x, for the connected camera. Firmware-update tools give the same answer indirectly, because most refuse to flash over USB 2 and say so in a warning. Check this first; every later step depends on which link you actually have.
Can a USB-C cable be USB 2 only?
Yes, and it is the most common cause of a camera stuck at USB 2. Charge-only and USB 2-only USB-C cables have no SuperSpeed pairs inside, so no port, driver setting or reboot can make them carry USB 3 data. Use a cable sold as USB 3 or full-featured USB-C, ideally 1–2 m, then re-check the negotiated speed.
Do exposure time and gain change the bandwidth I need?
No. The payload is width × height × bytes per pixel × frame rate; exposure and gain change how many photons each pixel collects, not how many bytes it produces. The settings that move the budget are resolution, pixel format, compression and frame rate. If your streams are over budget, change one of those four.


