3D visionTroubleshooting

Depth and color stream timeouts: the USB bandwidth check

A depth and color stream that delivers one frame then times out is usually a USB bandwidth problem. Here is the arithmetic, the lsusb check and the fix.

LumaSpec Vision10 min read Share on LinkedIn

On this page 8 sections
  1. 01Why does the stream deliver one frame and then time out?
  2. 02How much USB bandwidth does a depth and color stream need?
  3. 03How do I check which USB bus the camera landed on?
  4. 04Can a USB 2 bus carry the pair if I slow it down?
  5. 05What is the fix: port, cable or powered hub?
  6. 06When should I stop fighting USB and change the link?
  7. 07How do I keep this off the next build?
  8. 08Questions

A depth camera that renders one frame, writes one video frame and then throws a five-second frame-timeout error is not a broken camera — it is a bandwidth budget that does not close. Depth and color enabled together is the usual trigger: the pair costs more than a USB 2 link carries, and on many laptops and bench PCs the port you picked is wired to a 2.0 bus or shares its controller with other devices. If you integrate USB depth cameras on Linux or Windows hosts, the arithmetic below decides the case, the lsusb and usb-devices checks show which bus the camera really enumerated on, and the fix follows in order: port, cable, powered hub — plus the point where a different interface is the better answer for a machine build.

Why does the stream deliver one frame and then time out?

The pair you enabled — 640 × 480 depth plus 640 × 480 color at 30 fps — needs about 46 MB/s of payload, more than a USB 2 link sustains in practice, so the camera hands you the first buffered frames and then the five-second wait expires.

The signature is worth learning once. The first frame renders, the video writers create their files, and then the capture call raises an error in the shape of Frame didn't arrive within 5000 — and a viewer application fails the same way on the same port. The kernel log tells the rest: dmesg repeats lines in the form usb 3-7: Failed to query (GET_CUR) UVC control 1 on unit 3: -32, where 3-7 is bus 3, port 7, and -32 is the kernel's stalled-pipe status. That is what a starved link looks like from the driver's side.

Rank the causes in this order:

  1. The camera enumerated on a USB 2 bus — a 480 Mbit/s root hub — because the port is 2.0-only or the connector is wired to the 2.0 companion of a 3.x controller.
  2. A charge-only or 2.0-rated cable forces 480 Mbit/s enumeration even inside a SuperSpeed port.
  3. The camera sits behind a USB 2 hub, which caps the whole segment at 480 Mbit/s.
  4. Other devices share the camera's bus, and their reservations squeeze the video stream.
  5. The capture loop holds the pipeline — the software cause that reproduces even on a perfect port; the frame-timeout fix for one wait call per frame covers that pattern.

Swap the port before you touch the code: it takes ten seconds and decides most cases. If frames stall intermittently rather than dying after the first one, the USB bandwidth stall fix covers that middle ground.

How much USB bandwidth does a depth and color stream need?

Add up every stream you enabled: 640 × 480 × 2 bytes at 30 fps is 18.4 MB/s for depth, 640 × 480 × 3 bytes at 30 fps is 27.6 MB/s for color, and the pair needs 46.1 MB/s before protocol overhead.

payload (MB/s) = width_px × height_px × bytes_per_px × fps / 1,000,000 depth: 640 × 480 × 2 × 30 / 1,000,000 = 18.4 MB/s color: 640 × 480 × 3 × 30 / 1,000,000 = 27.6 MB/s pair: 18.4 + 27.6 = 46.1 MB/s
Stream Bytes per frame Payload at 30 fps
Depth 640 × 480, 2 bytes per pixel 614,400 18.4 MB/s
Color 640 × 480, 3 bytes per pixel 921,600 27.6 MB/s
Pair total 1,536,000 46.1 MB/s
Color 1280 × 720, 3 bytes per pixel 2,764,800 82.9 MB/s

Now set that against the ceilings. A USB 2 bus runs at 480 Mbit/s of line rate — 60 MB/s of raw symbols — but a single isochronous endpoint can be granted at most 1024 bytes × 3 transactions per 125 µs microframe, and 1024 × 3 × 8000 microframes/s = 24.6 MB/s; the bus as a whole sustains roughly 35-40 MB/s of real throughput in practice. USB 3.0's 5 Gbit/s line rate works out to about 500 MB/s of payload after encoding overhead, per the USB 3.0 reference.

Link Line rate Payload ceiling
USB 2, one isochronous endpoint 480 Mbit/s bus 24.6 MB/s
USB 2 bus, sustained 480 Mbit/s 35-40 MB/s in practice
USB 3 port 5 Gbit/s about 500 MB/s
GigE link 1 Gbit/s 125 MB/s line rate

The decision writes itself: the 46.1 MB/s pair fails both USB 2 rows and clears a USB 3 port by a factor of ten. The 82.9 MB/s variant fails USB 2 on line rate alone — 82.9 MB/s is 663 Mbit/s of payload before overhead, more than the bus delivers even in theory.

How do I check which USB bus the camera landed on?

Run lsusb, match the line that names your camera, note its bus number, then check that bus's root hub: Linux Foundation 2.0 root hub means a 480 Mbit/s bus, Linux Foundation 3.0 root hub means the 5 Gbit/s controller you want.

# lsusb: find the camera's line, then read the root hub of that bus
Bus 003 Device 001: Linux Foundation 2.0 root hub    # the camera's bus: 480 Mbit/s
Bus 002 Device 001: Linux Foundation 3.0 root hub    # a SuperSpeed bus on the same host

usb-devices answers it for the camera itself: the T: line of the camera's entry prints Spd=480 when the link negotiated high speed, and Spd=5000 or higher on a SuperSpeed link. Read the root-hub serial numbers too. One controller commonly exposes a 2.0 bus and a 3.x bus under the same PCI address, because the 2.0 companion handles non-SuperSpeed traffic — which is how a machine that has USB 3 still strands the camera at 480 Mbit/s on the connector you happened to pick, or on a cable that carries no SuperSpeed pairs.

The kernel log confirms the stall while it happens: lines shaped like usb 3-7: Failed to query (GET_CUR) UVC control 1 on unit 3: -32 name the bus and port (3-7) and end in -32, the stalled-pipe status.

The decision: if Spd=480, test every physical connector on the host — they are wired to different buses, and often only some reach a 3.x controller. After each move, re-run usb-devices before you re-run the capture script, so the bus you fixed is the bus the camera is actually on.

Can a USB 2 bus carry the pair if I slow it down?

Only just, and only slower: at 15 fps the pair costs 23.0 MB/s, which fits under both USB 2 ceilings — 24.6 MB/s per isochronous endpoint and roughly 35-40 MB/s of practical bus throughput — provided nothing else shares that bus.

The halved numbers: depth at 9.2 MB/s (18.4 / 2), color at 13.8 MB/s (27.6 / 2), total 23.0 MB/s (46.1 / 2). Each stream stays under the endpoint cap, so the controller can grant both reservations. Accept that trade for slow processes and static scenes; half the frame rate is half the temporal resolution, and the gap between frames grows.

The fallback dies the moment you return to 30 fps (46.1 MB/s), raise color to 1280 × 720 (82.9 MB/s), or add a second camera. And one hard limit: color at 640 × 480 and 30 fps alone asks 27.6 MB/s from a single endpoint, past the 24.6 MB/s cap, so no setting on the depth stream rescues a 30 fps color mode on USB 2.

What is the fix: port, cable or powered hub?

In order: move the camera to a port that enumerates at 5000 Mbit/s on its own controller, replace the cable with a short certified USB 3.0 data cable, and only then add a powered USB 3 hub when you need more 3.x ports.

  1. Test every physical connector and keep the one where usb-devices reports Spd=5000 or higher for the camera; on a bench, this step alone usually ends the problem.
  2. Replace the cable. Charge-only and 2.0-rated cables enumerate at 480 Mbit/s inside a perfectly good SuperSpeed port, so the port upgrade never reaches the camera.
  3. Past about 5 m, use an active repeater cable that regenerates the signal, and re-check Spd after the swap; the USB cable length limits for 3D cameras walks the distance numbers.
  4. If the host has no free SuperSpeed port, a powered USB 3 hub gives the camera its own wiring and takes its current draw off the host port. Plug the hub into a 3.x port, never into another hub.
  5. Keep other bulk talkers — webcams, external drives, capture dongles — off the camera's controller.

That second point is a parts decision, not a lab finding. For a machine build, LS-CBL-0219 is the shop's 3 m high-flex USB 3.0 camera cable, rated for drag chains.

Cables3 m USB3.0 camera cable, high-flex (drag chain) (LS-CBL-0219)LS-CBL-0219$62.00View partBuild a system with it

Change the link when the run is long, the cell gains a second camera, or the host has no free SuperSpeed port: this 46 MB/s pair fits one 1 Gbit/s Ethernet link (125 MB/s line rate) and multiplies five-fold on 5GBASE-T over standard structured cabling.

GigE Vision gives each camera a switched 1 Gbit/s link, so the pair sits at about 37 percent of the wire (46.1 of 125 MB/s) and a second camera takes the next port; the GigE Vision selection guide covers bandwidth, cables and host setup. For machine wiring, LS-CBL-0199 is the shop's 3 m high-flex GigE camera cable, likewise rated for drag chains. Where one gigabit runs out, the 5GBASE-T interface guide scales the same arithmetic five-fold on the structured cabling a machine already has.

Cables3 m GigE camera cable, high-flex (drag chain), screw locks (LS-CBL-0199)LS-CBL-0199$54.00View partBuild a system with it

If the host itself is the constraint — one shared controller, no free SuperSpeed port — a dedicated host with several controllers ends the port lottery, and an industrial mini PC sized for the camera count is the machine-build answer. When you are choosing depth hardware for a fixed cell rather than rescuing a bench setup, start in the 3D sensors category and filter the camera finder by the interface the machine actually has.

How do I keep this off the next build?

Budget bandwidth at design time: compute the payload for every stream and camera, keep one camera per controller, and record the enumeration check — Spd=5000 or higher in usb-devices — as a commissioning step before the machine ships.

The five-minute routine:

  • Compute payload per camera with the formula above: a 640 × 480 pair at 30 fps needs 46.1 MB/s, and a second camera doubles it.
  • Assign one camera per controller; spread multi-camera rigs across 3.x buses instead of one hub, and commission them one stream at a time as the multi-camera FPS test shows.
  • Keep the host's own peripherals off the camera's bus where the hardware allows.
  • Spec the cable in the build documents — length, data rating, drag-chain grade — the same way you spec the mount.
  • Commission with usb-devices: Spd=480 anywhere in a chain fails the build, whatever the software reports.

The bandwidth and power budget for several USB cameras extends this arithmetic to a full rig. If you are speccing the link for a new build, start at the cables category or step into the extras configurator; the applications team answers sizing questions through the contact page.

Questions

Does a USB 3 camera work in a USB 2 port?

It enumerates, but at 480 Mbit/s, and the same arithmetic decides the outcome: all enabled streams together must stay under 24.6 MB/s per isochronous endpoint and roughly 35-40 MB/s per bus. The 640 × 480 depth-plus-color pair at 30 fps needs 46.1 MB/s, so it times out; at 15 fps, at 23.0 MB/s, a dedicated 2.0 bus carries it. Enumeration succeeding with no error logged is exactly why the failure looks like a software bug.

How long can the cable be before I need an active repeater?

Keep passive runs to about 2 m and use a cable sold for data rather than charging; past about 5 m, use an active repeater that regenerates the signal. Every repeater is a hub in the path, and USB allows only a limited hub depth, so chain at most a couple. Whatever you install, re-run usb-devices: Spd=480 instead of Spd=5000 means the run fell back to high speed and the timeout will return.

Do the mouse, keyboard and other devices on the same bus cause this?

Not by themselves. A mouse or keyboard moves kilobytes per second, nothing next to a 35-40 MB/s ceiling. The devices that hurt you are ones with real throughput: webcams, external drives, capture dongles and a second 3D camera, because isochronous video reservations compete on the same controller. Move those to another bus before you blame the cable.

What wait timeout should I set in the capture code once the link is fixed?

Keep a generous timeout for start-up, then drop to about 1 second in the steady loop. At 30 fps a frame is due every 33 ms, so a healthy link delivers roughly 30 frames inside a one-second wait. A five-second wait in the main loop only hides a starved link for minutes at a time instead of telling you immediately.

Should the hub be powered, or can the host port supply the camera?

Prefer a powered hub for a depth camera: the camera draws its current over the same cable that carries the stream, and emitters and onboard processing take real power on top of the data. A powered hub keeps voltage stable on longer or marginal runs and isolates the camera's wiring from the host's. Make sure the hub itself is USB 3 and plugs into a SuperSpeed port, or you have moved the problem rather than solved it.