System designTroubleshooting

nvarguscamerasrc captures the desktop screen: fix the device index

nvarguscamerasrc captures the desktop screen because no sensor frame reached the window: wrong node or unbound driver. Enumerate, test raw, fix the overlay.

LumaSpec Vision10 min read Share on LinkedIn

On this page 9 sections
  1. 01What a desktop picture actually tells you
  2. 02Why /dev/video0 proves nothing
  3. 03The four likely causes, in order
  4. 04Four checks, about a minute each
  5. 05The fix: bind the sensor, then rerun the original pipeline
  6. 06The numbers behind the caps string
  7. 07When the right fix is a different link
  8. 08Keep the fault from coming back
  9. 09Questions

You run the capture pipeline, a window opens, and the picture on screen is your desktop, pixel for pixel. That is not a capture of your session; it is a display window that never received a single camera frame, with the desktop showing through behind it. On an embedded board with a CSI camera, this symptom has one of two roots: the pipeline opened a /dev/video node that is not your sensor, or the sensor's driver never bound, leaving a raw node the capture element cannot stream through. This guide gives you the checks that separate the two, the fix for each, and a decision rule for when a USB3 board camera beats more driver work. Everything here runs from a terminal on the board, in minutes.

What a desktop picture actually tells you

An empty window and a successful capture look identical from across the room. The difference is mechanical: a working pipeline pushes sensor frames into that window one after another. A pipeline that never started leaves the window's surface empty, and the desktop behind it shows through. Read the symptom literally: no sensor frame reached the display. Nothing in the chain captured your screen, and nothing on your screen is at fault.

nvarguscamerasrc is not a generic V4L2 reader. It negotiates with the board's image-processing stack, and that stack only offers stream modes for a sensor whose driver is bound and named in the device tree. A sensor without that entry still leaves a plain V4L2 node on the list — ideal for a raw v4l2src readout, invisible to the ISP-side element. That asymmetry explains the strangest part of this fault: the node exists, a raw readout can even work, and the original pipeline still fails. When a board has no ISP path at all, CSI camera with no ISP: what raw sensor output means explains what the raw node can and cannot give you.

Why /dev/video0 proves nothing

Boot creates the door before anyone checks the room. The board's video-input hardware registers its node as the kernel comes up; USB cameras claim nodes in the order they enumerate. So index 0 has no fixed meaning: it may be the video-input node with no sensor behind it, or a USB camera you plugged in for development. A pipeline that hard-codes the index opens whatever claimed that slot on this boot.

v4l2-ctl --list-devices settles it in one command. Read the heading above each node in its output; that heading is the driver that owns the node.

Listing shows the node under Meaning What the node delivers
The sensor driver's name, for example imx219 The sensor driver bound and probed Raw sensor frames
The video-input platform driver, no sensor name A registered node with no bound sensor Nothing: the empty door
A USB video-class driver A USB camera That camera's frames

Newer boards split the same problem one layer deeper: the CSI link can reach the video-input (VI) block and still deliver no data when the lane or sensor configuration is wrong. The write-up on why a CSI link fails to deliver camera data to the VI walks that case on a current-generation board.

The four likely causes, in order

  1. The pipeline opened the wrong node. A hard-coded index resolves to whatever claimed that slot at this boot. This cause ranks first because its test is one command and its fix is one line: resolve nodes by driver name, never by number.
  2. The sensor driver never bound. The overlay for this module is missing, wrong or disabled, the connector is switched off in the device tree, or the cable is not fully seated. The node exists; the stack has no sensor to offer; every capture request times out.
  3. The capture element is unavailable on this image. gst-inspect-1.0 -b prints the element blacklist. An element on that list cannot be instantiated, so no pipeline string can work until the imaging stack installs cleanly.
  4. The caps string names a mode the driver does not list. A width of 3820 against a sensor whose array is 3280 pixels wide intersects no mode and stops the pipeline at negotiation — even on a perfectly healthy stack. This cause fails loudly with an error, so if your window still shows the desktop, return to causes 1 and 2.

Work the list in order. Each check below takes about a minute.

Four checks, about a minute each

  1. Enumerate the nodes. Run v4l2-ctl --list-devices and note which driver owns each node. If the command itself cannot open a node, you have a permissions or absence problem: Linux camera device permissions: video and media node checks covers both.
  2. Read the boot log. Run dmesg and search for the sensor's probe line: the driver's name and the bus address it probed. No line means the driver never loaded; an error line means it loaded and found nothing on the bus. Camera loads the wrong sensor driver: read dmesg, fix the overlay shows how to read that trail, and sensor probes but no video node: fix the devicetree chain takes the case one step further back.
  3. Check the element blacklist. Run gst-inspect-1.0 -b and look for nvarguscamerasrc. It appears on the list: repair the imaging stack first, and camera capture pipeline startup failure: isolate the cause runs the same isolation from the pipeline side.
  4. Read the node raw. Open the sensor's node with a plain v4l2src pipeline at the raw size the driver lists. Frames appear: sensor, cable and driver are good, and the fault lives in the ISP path above them. The readout stays black or errors: the driver bound but the sensor is not streaming, which means clock, lane or power. MIPI sensor detected but streaming fails: power, clocks, device tree splits those three.

The fix: bind the sensor, then rerun the original pipeline

The durable fix is the module vendor's device-tree overlay for your board image — the fragment that names the sensor, its bus address and the connector's port and lane mapping. Install it the way the vendor documents, reboot, and repeat the first two checks: the probe line back in dmesg, the sensor's name over the node in the device listing. Only then rerun the original gst-launch-1.0 nvarguscamerasrc command. The caps string you started with was never the problem.

Settle module-versus-board in one minute: put a module known to work with your image's stock overlay on the same connector. It streams, and the board and image are healthy — the first module needs its own overlay or a re-seat. It fails the same way, and the connector or image needs attention before you blame any module. That swap is exactly how this case class closes: same stack, same connector, second module streams, first one never did.

When the probe appears but frames still do not, suspect the port mapping between overlay and connector: camera device tree overlay CSI mapping troubleshooting walks that mapping. And leave flip-method alone for now; it flips frames that already exist and cannot conjure the missing ones.

The numbers behind the caps string

Your caps deserve a check, not a blind tune. The command requests the sensor's full 3280 × 2464 array at 21 fps in NV12, and the same string streamed once the right module sat on the connector — the string is acquitted. The width of 3820 in some copies of the command cannot match any mode; fix it to 3280.

pixels/frame = 3280 × 2464 = 8,081,920 bytes/frame = 8,081,920 px × 1.5 B/px = 12,122,880 B ≈ 11.6 MiB full payload = 12,122,880 B × 21 fps ≈ 254.6 MB/s ≈ 2.0 Gbit/s display branch = 960 × 616 px × 1.5 B/px × 21 fps ≈ 18.6 MB/s

NV12 stores luma plus a half-size chroma plane: 12 bits per pixel, 1.5 bytes. So one full frame costs about 11.6 MiB, and a 21 fps capture moves roughly 255 MB/s — about 2.0 Gbit/s of payload. That is why the pipeline scales to 960 × 616 before display: the window branch costs 18.6 MB/s instead of 255. Keep capture at the sensor's listed mode and scale after conversion; the driver offers only its listed modes, so dropping resolution at capture discards detail permanently.

A different symptom needs a different page: a gray rectangle instead of a desktop picture means the pipeline ran and the formats did not match — camera preview shows a gray image: fix the format mismatch is that fault.

Put a boundary on driver work. If the module's vendor publishes no overlay for your board image and nobody on your side maintains kernel or device-tree changes, every image update re-breaks the camera. That is a build decision, not a debugging session. A USB3 board-level camera takes the other road: it enumerates with its vendor driver on every boot, no overlay to keep aligned, over a link with roughly 3 Gbit/s of usable payload — 5 Gbit/s line rate after encoding and protocol overhead — enough headroom for the 2.0 Gbit/s full-array stream you just costed. The trade between CSI and USB on an industrial controller is compared in this CSI versus USB camera connection guide.

Board-level options from the catalog for that road:

Board-level camerasHikrobot MV-CB060-10UM-B 6 MP Board Level Camera, USB3, IMX178, Mono, Bare Board, V4MV-CB060-10UM-B
Sensor format
1/1.8"
Interface
USB3
$239.00View part
Board-level cameras3.1 MP USB3 board-level camera, IMX252, 1/1.8" global shutter, 120 fps (LS-BCM-0003)LS-BCM-0003
Sensor format
1/1.8"
Lens mount
C-mount
$690.00View part
Board-level cameras6.3 MP board-level camera, IMX178, 1/1.8" rolling shutter, 18 fps (LS-BCM-0020)LS-BCM-0020
Sensor format
1/1.8"
Lens mount
CS-mount
$290.00View part

If you want bare-board freedom around the sensor, MV-CB060-10UM-B is a 6 MP mono USB3 camera on a 1/1.8" rolling-shutter sensor, shipped as a bare board. For a compact module behind a C-mount:

Board-level camerasUSB3.0 board camera / module, 1.3 MP, Color (LS-BCM-0047)LS-BCM-0047
Sensor format
1/2.7"
Lens mount
C-mount
Interface
USB3
Resolution
Up to 3 MP
$179.00View partBuild a system with it

Shortlisting goes faster with filters: the camera finder sorts by interface, sensor and mount, and board level camera selection for embedded vision machines walks the full decision. Treat any sample module as unproven until the board camera evaluation checklist items pass on your carrier.

Keep the fault from coming back

  • Resolve nodes by driver name, never by index. Enumeration order changes when a USB camera joins the bus; the driver name does not.
  • Log the probe at every boot. Keep the sensor's dmesg line in your boot report; a missing line becomes a five-second diagnosis instead of an hour of pipeline edits.
  • Keep the overlay in your image source control. An overlay applied by hand to one unit fails on the next re-flash.
  • Re-run the raw readout after each image update. The one-minute v4l2src test is a regression test for the whole driver chain.
  • Pass media nodes into containers. A pipeline in Docker needs the media nodes, not just one video device: camera in Docker: pass V4L2 media nodes, not just /dev/video0 lists what to hand through.

If this is a one-off bring-up, the cheapest path is usually the interface that already has a supported driver on your image — browse the board-level cameras or start the camera configurator. For a build decision between CSI and USB3 on your own carrier, send the sensor, the board image and your payload budget through the contact page. More bring-up guides of this kind sit on the systems topic page.

Questions

Why does /dev/video0 exist when the CSI camera is not working?

The board's video-input hardware registers its device node at boot, before and independently of any sensor binding. Node presence says nothing about a bound sensor: without the driver, the node delivers no frames and the ISP-side element cannot attach through it. That is why 'the node is there' and 'the sensor streams' are two separate checks, and why a raw readout can work while the capture element fails.

How do I tell the CSI sensor node from a USB camera node?

Run v4l2-ctl --list-devices and read the group headings: each node is listed under the driver that owns it. A CSI sensor bound to its driver appears under that sensor's name, an example being imx219; a USB camera appears under its USB video-class driver. A node that sits under the platform video-input heading with no sensor name is the empty node — never capture from it by index.

Does a raw v4l2src stream mean the camera is ready for my application?

Only for raw-frame use. A raw pipeline bypasses the ISP: no demosaicing for a color sensor, no auto exposure or white balance, and no hardware scaling, so color work and exposure control move into your software. Inspection pipelines that need corrected color or stable exposure want the ISP path working — which is why the raw stream is a test, rarely the destination.

When is switching from CSI to USB3 the right call?

When the module's vendor publishes no device-tree overlay for your board image and your team does not maintain kernel or device-tree work. A USB3 board-level camera enumerates with its vendor driver on every boot, no overlay to keep aligned with image updates, and roughly 3 Gbit/s of usable payload covers the 2 Gbit/s class of a full-speed 8 MP stream. You trade the thin ribbon for a cable that carries its own supported stack.

It probed, and raw capture streams, but the original pipeline still fails. What now?

The sensor and its driver are fine; the failure has moved to the ISP and daemon layer. Confirm the capture element is not on the element blacklist (gst-inspect-1.0 -b prints it), check that the overlay's port and lane mapping match the connector the camera sits on, and compare the sensor driver version against the image. This is the point where the vendor's bring-up guide, not the pipeline string, holds the fix.