You wire the CSI-2 camera to the BBAI-64, run the gst-launch pipeline every quick-start prints, and GStreamer stalls at PAUSED with Device '/dev/video0' is not a capture device. The camera is fine and the ribbon cable is seated. On this board the SoC's own video blocks — display, encoder, ISP, capture — each claim the next free /dev/video number as their drivers probe at boot, and the display block gets there first. video0 belongs to hardware that can never deliver a frame from your sensor. This guide gives you the three-command workflow to enumerate every video node, find the one wired to your sensor through the media controller, verify its capture capability, and point v4l2src at it. It is written for engineers bringing up board-level cameras on embedded Linux, and the same workflow applies on any media-controller SoC.
The fix in one pass
The failure is a wrong device path, and you can correct it in about a minute on the bench:
- Run
v4l2-ctl --list-devices. It groups every/dev/video*,/dev/v4l-subdev*and/dev/media*node under the driver that registered it. - For each candidate video node, run
v4l2-ctl -d /dev/videoN --all. A usable capture node printsVideo Capturein its device caps; an output or metadata node does not. - Run
media-ctl -d /dev/media0 -pand find the entity named after your sensor. The link chain out of that entity ends at the video node you open.
Then substitute that node in the pipeline — v4l2src device=/dev/video2 in the worked example below — and set caps inside the format list the node prints. On the BBAI-64 the CSI capture node commonly sits at video2 or later, because the SoC's display and encoder drivers register before the camera path. If --list-devices shows no group for your sensor's driver at all, the camera never probed and no node choice can fix it: the sensor-probe checklist in media0 with no video0 device node: the sensor driver never probed is the next stop.
Why /dev/video0 is not your camera
V4L2 hands out device numbers in registration order, across the whole SoC, as each driver probes. Nothing reserves numbers per function: the display subsystem, the video encoders, the ISP, the CSI receiver and any USB webcam all take the next free minor in the order they come up. On the BBAI-64 that puts the low numbers on SoC-internal blocks and the camera path higher, commonly at video2 or beyond, and the exact split moves with the kernel build — which is why you enumerate instead of hardcoding a number.
Two more node families sit beside the video nodes. Each sensor registers as a V4L2 subdevice at /dev/v4l-subdevN, and each capture pipeline registers a media controller device at /dev/mediaN describing the graph: which entity feeds which pad, and ultimately which video node carries the frames.
The error text is exact. On the way to PAUSED, v4l2src queries the node's capabilities, and a node without capture capability — an output feeding the display, or a metadata collector — fails with Device '...' is not a capture device. The MESA-LOADER complaint about tidss_dri.so printed above it is the video sink failing to load a display driver; it is not the capture failure, and fixing the node usually leaves it untouched.
Likely causes, in order
| # | Cause | How often | Test | Fix |
|---|---|---|---|---|
| 1 | Pipeline opens an SoC-internal node (display, encoder, metadata) | Most common; the default failure on this board |
v4l2-ctl -d /dev/videoN --all shows no Video Capture
|
Open the node the media graph links to your sensor |
| 2 | Sensor driver never probed | Common with modules outside the board's supported list | No sensor entity in media-ctl -p; no driver group in --list-devices
|
Match connector, lanes, power and I2C address; see CSI camera V4L2 no such device error: enable the interface first |
| 3 | Right node, wrong format | Common once cause 1 is fixed |
v4l2-ctl --list-formats-ext offers RAW10 or RAW12 while the pipeline demands NV12 |
Route through the SoC ISP or request the sensor format; see CSI camera with no ISP: what raw sensor output means |
| 4 | Node held by another process | Occasional after a crash or restart | Open fails with EBUSY
|
Close the holder; see V4L2 device busy after restart: the old node still holds the camera |
| 5 | Image release lacks the capture or ISP stack | Appears after a reflash | Media devices or capture nodes missing entirely | Flash the image release your SDK names as tested |
Work down the table in this order. Causes 1 and 3 together account for nearly every no-video-from-the-CSI-camera report on media-controller boards, and cause 1 is the one the worked example fixes end to end.
Find the capture node step by step
-
v4l2-ctl --list-devicesprints each node grouped by owning driver. Note the group whose name matches the CSI capture driver; ignore the display group. - For each node in the capture group,
v4l2-ctl -d /dev/videoN --allprints the caps. The node you want listsVideo Capture, with or withoutMultiplaned; nodes listing onlyVideo OutputorMetadata Captureare excluded, whatever their number. -
v4l2-ctl -d /dev/videoN --list-formats-extprints the pixel formats and frame sizes. The sensor's RAW formats appear here if this is the CSI node; NV12 appears only after the ISP stage. -
media-ctl -d /dev/media0 -pprints the graph. Find the entity whose name carries the sensor part number and follow the links to the video node;media-ctl -d /dev/media0 -e '<entity name>'prints that entity's own device node. - A sysfs shortcut does the same survey faster:
grep -H . /sys/class/video4linux/video*/nameprints each node with the driver that owns it, and the line matching the capture driver marks your node. - Prove the node streams before touching GStreamer:
v4l2-ctl -d /dev/video2 --stream-mmap --stream-count=1 --stream-to=/tmp/frame.rawwrites one frame, and the file size should equal width × height × bytes per pixel for the selected format. The raw Bayer capture walkthrough runs the same one-frame test on a multi-camera rig.
None of this is board-specific. The same media-ctl then v4l2-ctl sequence — list drivers, check caps, print the graph, follow the sensor entity's links — is the standard bring-up flow for any CSI pipeline on a media-controller SoC, so the commands you learn here carry over to other boards unchanged.
Worked example: the failing gst-launch pipeline on a BBAI-64
Inputs. The pipeline, as run on the board: gst-launch-1.0 v4l2src device=/dev/video0 ! video/x-raw,format=NV12,width=1920,height=1080,framerate=30/1 ! videoconvert ! autovideosink. The failure, from the same run: Device '/dev/video0' is not a capture device. at PAUSED, plus a MESA-LOADER warning about tidss_dri.so. Tools: v4l-utils, so v4l2-ctl and media-ctl are installed. The node outputs below are illustrative shapes; the driver names and exact numbers on your build decide the mapping.
Rule. A node is your capture node only if it passes both checks: its caps include Video Capture, and the media graph links your sensor entity to it. Any node printing only Video Output or Metadata Capture is excluded regardless of its number.
Steps.
-
--list-devicesreports six video nodes, video0 through video5, plus/dev/media0and several subdevs. The display driver's group owns video0 and video1; the CSI capture driver's group owns video2. -
--allon video0 printsVideo Output— excluded.--allon video2 printsVideo Capture Multiplaned, and--list-formats-extlists the sensor's RAW format at 1920×1080, 30 fps. -
media-ctl -pshows the sensor entity linked through the CSI receiver to video2. Both checks pass: video2 is the capture node.
Arithmetic. The NV12 caps promise 1920×1080 at 30 fps, and NV12 stores 12 bits per pixel, so 1.5 bytes per pixel:
That 746 Mbit/s is what NV12 at these caps consumes; a 1 Gbit/s link would run at three quarters of line rate before any protocol overhead, which is worth knowing if you pipe frames off-board later.
Result. Use v4l2src device=/dev/video2, request the RAW format the node lists instead of NV12, and route the SDK's ISP elements ahead of videoconvert and the sink. The pipeline then reaches PLAYING with caps matched to the format list.
Decision. On the BBAI-64, never open video0 blind: open the first node that passes both checks, commonly video2 or later on this board. If a node fails either check, move to the next candidate. The number is never the evidence; the capability line and the graph link are.
Point the pipeline at the right node
Two things change in the command: the device path, and the caps. The CSI node hands you sensor data, not ISP output, so a plain videoconvert cannot turn a packed RAW10 stream into NV12 — the supported route runs through the ISP elements that ship with the SoC vendor's GStreamer plugin set. The MIPI CSI-2 pipeline walkthrough follows the whole path from sensor pad to host memory, stage by stage.
The sensor's own controls do not live on the capture node. Exposure and gain sit on the sensor's subdev node, which is why a control list queried on the video node comes back empty — the v4l2-ctl list-ctrls guide shows how to find the node that carries them.
Two environment checks finish the bring-up. If the open fails with EACCES rather than a capability error, it is device permissions, not node choice: the Linux camera device permissions checklist covers the group membership checks. If acquisition runs inside a container, pass the video node, the media node and the subdev nodes together — media-ctl sees an empty graph when only the video node crosses the boundary, and the Docker V4L2 node guide lists the full set to hand through.
Prevent it on the next bring-up
The second recurring trap is at the pin level: when a boot-time peripheral claims pins, later opens fail with errno 16, EBUSY, which looks like a camera problem and is not. The BBAI-64 walkthrough for the errno 16 device-busy error traces one such case end to end.
When a USB3 board camera is the better choice
CSI bring-up buys the SoC's ISP and a small ribbon cable, but it costs a driver, a device tree and a media graph that must match the image. When the deliverable is a working camera this week, a USB3 board camera moves the driver burden to the module: it registers its own video node in its own --list-devices group, so there is no SoC graph to trace, and the same three checks — capability, formats, one test frame — close the job. Match the sensor to the inspection task rather than to the connector: global shutter for moving parts, a C-mount or M12 mount to fit your optics, a board outline that fits the housing.
The LS-BCM-0003 is a 3.1 MP USB3 board camera with a 1/1.8" IMX252 global-shutter sensor running 120 fps; the MV-CB060-10UM-B is a 6 MP mono bare-board USB3 camera with the same 1/1.8" sensor format.
- Sensor format
- 1/1.8"
- Lens mount
- C-mount
- Sensor format
- 1/1.8"
- Interface
- USB3
Each registers on the host as its own V4L2 device, so the verification commands above work unchanged. Choosing between them starts with the sensor and the lens, not the bus: the board camera selection guide walks that match, and the camera finder filters the board-level range by mount, shutter and interface. If the module pairs the sensor with a USB3 bridge chip, check the pairing before you stream — the USB3 bridge matching guide covers what the link needs.
Compact cameras to build in
120 models · from $179.00Checks before you order
- Sensor driver first. Confirm the sensor part number is in your SoC's supported-camera list before ordering a module; on a media-controller board the driver is the whole integration.
- Output format. A sensor that outputs RAW10 or RAW12 means the frame path runs through the SoC ISP; check the SDK lists ISP support for that format.
- Connector and lanes. Match the module's connector family and data-lane count to the board's CSI header, and confirm the module's power and enable wiring against the board's camera documentation.
- Image release. Have the SDK-matched image written and boot-tested before the module arrives, so a missing driver is never mistaken for a dead camera.
- Tools and test. Install v4l-utils and save the one-frame capture command as a script; it settles node questions in seconds.
- Fallback bus. If the schedule is tight, a USB3 board camera drops the media-graph work entirely, as covered above.
When the graph still shows no sensor after all of this, send your --list-devices and media-ctl -p output through the contact page and we will read it with you. To pick the camera side first, start at the camera configurator; the systems topic page collects the rest of the embedded capture guides.
Questions
Why are there more /dev/video nodes than cameras on the BBAI-64?
Every SoC block that can register a video device takes the next free number at probe: display, encoders, ISP, capture and USB webcams share one numbering sequence. The count and the split move with the kernel build, so a hardcoded number in a script breaks at the next image update. Enumerate with v4l2-ctl --list-devices and pick by capability and media-graph link, never by number.
Can I make my CSI camera become /dev/video0?
You cannot renumber: the kernel assigns the minor number at probe time. The stable option is a udev rule that matches on the video4linux driver attributes and creates a symlink such as /dev/csi-cam pointing at the verified capture node, then open that symlink in your pipeline so image updates that reshuffle the numbering never touch your launch files.
Will any CSI-2 camera module work on the board's two camera ports?
Three things must line up: a kernel driver for the sensor, a physical match of connector and data lanes, and an image that carries the capture and ISP stack for the sensor's output format. If the sensor has no driver in your kernel's tree, expect to build one out of tree before any node appears. Check the board's supported-camera list before ordering a module.
Do the two CSI-2 connectors work at the same time?
Each connector sits behind its own receiver and registers its own media graph, so you can enumerate and test them independently with the same three commands. Whether both stream simultaneously is decided by the SoC capture driver and the image release; the supported multi-camera configuration is documented with the board's camera stack, so check it there rather than assuming both ports run in parallel.
What do I pass into a container so the CSI camera works inside Docker?
Pass more than the video node: give the container the capture /dev/videoN, its /dev/mediaN controller and the /dev/v4l-subdevN nodes, allowed through the device cgroup. With only the video node mounted, media-ctl finds no graph and the sensor controls disappear. The guide on running a CSI camera in containers lists the mount set and the device-cgroup rules.

