System designTroubleshooting

v4l2src signal lost not-negotiated: match caps to the sensor format

Fix v4l2src Signal lost and not-negotiated (-4): read the sensor's media-bus format with media-ctl, set the caps it maps to, and isolate faults upstream.

LumaSpec Vision9 min read Share on LinkedIn

On this page 8 sections
  1. 01What the two messages actually say
  2. 02Read the sensor's format with media-ctl
  3. 03Map the media-bus code to the caps fourcc
  4. 04Worked example: YUYV8_1X16/1920x1080@30 sensor against UYVY caps
  5. 05Three causes above the caps, in test order
  6. 06Prevention: derive the caps, never guess them
  7. 07When to leave the media controller behind
  8. 08Questions

The capture node exists, the sensor subdev is bound, and gst-launch still dies about two milliseconds after PLAYING: first a "Signal lost" warning, then "streaming stopped, reason not-negotiated (-4)". That pair means your caps filter and the driver's format list have nothing in common — you asked for UYVY while the sensor pad carries YUYV8_1X16/1920x1080@1/30, which maps to the pixel format YUYV. This guide shows you how to read the sensor's real format with media-ctl, how to turn the media-bus code into the caps string GStreamer accepts, and how to tell the rarer case where the fault sits upstream of negotiation, in the device tree or the CSI link. It is for engineers bringing up CSI and GMSL cameras on embedded Linux capture pipelines.

What the two messages actually say

Keep the messages separate; they come from two layers and mean two things.

The warning, with debug info pointing at gst_v4l2src_query_preferred_size() in gstv4l2src.c, comes from the source's preferred-size probe. While the pipeline moves to PAUSED, v4l2src asks the capture node which format and resolution it would prefer as a default. The driver answered "No input source was detected - video frames invalid", so there was nothing to base a default on.

The error is the fatal one. "streaming stopped, reason not-negotiated (-4)" comes from the base source class when it cannot agree caps with the downstream filter. A caps filter is an intersection test, not a converter: v4l2src never changes what the driver produces, and the videoconvert you placed after the source cannot help, because the source never delivers a buffer to convert. Your filter video/x-raw,format=UYVY,width=1920,height=1080 intersected with the node's offer found no match, so streaming stopped before frame one.

If no stream ever appears — at any caps, filtered or not — that is a different fault class: work through GMSL camera not streaming over the serial link: isolate the fault first. This guide covers the narrower case where the node exists and only negotiation dies.

Read the sensor's format with media-ctl

media-ctl prints the ground truth, read-only, before you change anything:

sudo media-ctl -p -d /dev/media0

Walk the printed topology from sensor to node: the sensor subdev's SOURCE pad feeds the CSI receiver, whose SOURCE pad feeds the vi-output entity — the /dev/video0 node that v4l2src opens. On the sensor pad the driver prints its active format:

fmt:YUYV8_1X16/1920x1080@1/30 field:none colorspace:srgb

Read that as three facts: bus code YUYV8_1X16, resolution 1920x1080, frame interval 1/30 s — 30 fps. It is the format flowing over the CSI-2 bus, a media-bus code rather than the four-character pixel format userspace requests. The V4L2 kernel headers document both layers and the fixed mapping between each media-bus code and its fourcc; your running driver's output is the authoritative reading. If media-ctl shows no format on the sensor pad at all, your problem sits above the caps; jump ahead two sections.

Map the media-bus code to the caps fourcc

Subdev pads carry media-bus codes; the video node exposes fourccs. YUYV8_1X16 — Y, U, Y and V at eight bits each, one 16-bit pixel per clock — corresponds to the fourcc YUYV, which GStreamer spells format=YUYV. UYVY belongs to the bus code UYVY8_1X16, where the U and the first Y swap places. A pad carrying YUYV8_1X16 therefore has no reason to offer UYVY, and a caps string demanding it fails exactly as observed.

Ask the node for its own list; it beats any inference from tables:

v4l2-ctl -d /dev/video0 --list-formats-ext

Every row is a fourcc with the resolutions and frame intervals the node supports. v4l2src can deliver nothing outside that list. --get-fmt prints the format currently set. An empty list means the subdev never linked — that belongs to the causes section, not to caps editing.

Worked example: YUYV8_1X16/1920x1080@30 sensor against UYVY caps

The case behind this guide, end to end.

Inputs. From media-ctl -p: sensor pad format YUYV8_1X16/1920x1080@1/30 — bus code YUYV8_1X16, 1920 px by 1080 lines, frame interval 1/30 s. From the gst-launch command: caps video/x-raw,format=UYVY,width=1920,height=1080, framerate unconstrained. From the log: execution ended after 0:00:00.002394991, reason not-negotiated (-4).

Rule in words. Negotiation intersects your caps with the node's advertised list on every field at once — pixel format, width, height and framerate. One mismatched field empties the intersection, and the pipeline dies.

Arithmetic. The requested set is {UYVY, 1920, 1080, any framerate}; the node's set is {YUYV, 1920, 1080, 30/1}. UYVY does not appear in the node's set, so the intersection is empty and the -4 follows before the first buffer. For the record, the rate the working pipeline must sustain — YUYV stores sixteen bits per pixel, hence the factor 2:

bytes/frame = 1920 px x 1080 lines x 2 B/px = 4,147,200 B ≈ 4.1 MB data rate = 4,147,200 B x 30 /s = 124,416,000 B/s ≈ 124 MB/s ≈ 995 Mb/s

Result and decision. Request the fourcc the node advertises, with the mode's own frame interval:

gst-launch-1.0 v4l2src device=/dev/video0 ! \
  'video/x-raw,format=YUYV,width=1920,height=1080,framerate=30/1' ! \
  videoconvert ! fpsdisplaysink video-sink=xvimagesink

If --list-formats-ext lists several fourccs, any of them negotiates; YUYV keeps the capture path free of an extra copy. Threshold: when the list prints no format rows at all, no caps string can succeed — move to the next section.

Three causes above the caps, in test order

When the caps match the printed list and streaming still stops, work down this list.

1. A framerate the mode does not deliver. The pad prints 1/30; caps asking 60/1 fail. Test: compare your framerate field with the pad's interval and with --list-formats-ext. Fix: framerate=30/1.

2. The subdev never linked. Test: --list-formats-ext prints nothing, or media-ctl shows no fmt on the sensor pad. In the case log the sensor subdev did bind, but the CSI host driver also logged a device-link creation failure right beside the bind message. Where the capture framework uses virtual channels, the sensor-mode device-tree node's virtual-channel id must match the vc-id set on the CSI and VI nodes; one mismatch leaves the chain half-built even though the subdev bound. Test: read both ids and compare. Fix: make them equal.

3. Kernel and camera stack out of step. The case ran a mainline kernel version with an early-access camera stack on hardware that release did not yet cover — a driver that binds but cannot create its links is the classic signature. Fix: move to the release the camera stack documents; past that, the SoC vendor's support channel is the legitimate path.

The same "no input source" fault exists on PCIe capture cards, with electrical tests instead of device trees: Frame grabber cannot detect video source: signal checks walks that side.

Prevention: derive the caps, never guess them

Two habits prevent this whole class of failure.

Derive caps from the node, never from memory. media-ctl -p gives the bus code and the mode; --list-formats-ext gives the fourcc list; the caps string combines format, width, height and framerate from that output. In application code, enumerate the node's formats at start-up and build caps from the result instead of hard-coded constants. Where the driver allows reconfiguring, set the subdev pad format first — media-ctl's set-format option does this — then request the fourcc that matches.

One unfiltered run settles it in seconds. Launch v4l2src with no caps filter into fakesink and read what the driver chose.

If even the unfiltered source produces no buffers, stop editing caps: the fault is upstream, in the section above.

The same error string appears on software sources with no media controller anywhere: Appsrc not-negotiated error: fix caps framerate and format handles that variant. Pixel formats also fail more quietly on standard interfaces — a GigE camera delivering monochrome into a color pipeline does not error at all, it just shows no color image. More capture-path debugging lives on the systems topic page.

When to leave the media controller behind

CSI and GMSL bring-up keeps three things in step: sensor driver, device tree and kernel release. A camera on a standard interface removes that coupling. GigE Vision, USB3 Vision and CoaXPress cameras negotiate their pixel format through GenICam against the camera's own format list, and a PCIe card in your industrial PC carries the link — no media controller, no bus-code mapping, no virtual-channel ids.

Frame grabbersHikrobot MV-GE2002P Dual-port PoE NIC, full height V2.0MV-GE2002P
Interface
GigE
Ports
2 ports
$249.00View part
Frame grabbersHikrobot MV-GU2204 MV-GU2200 Series Quad USB3.0 AdaptorMV-GU2204
Interface
USB3
Ports
4 ports
$469.00View part
Frame grabbersHikrobot MV-GT2104 Quad-port copper 10GbE NICMV-GT2104
Interface
10GigE
Ports
4 ports
$1,429.00View part

The MV-GE2002P is a dual-port PoE GigE NIC, full height, for GigE cameras. The MV-GU2204 is a quad USB3.0 adaptor for USB3 cameras. The MV-GT2104 is a quad-port copper 10GbE NIC for 10GigE cameras. For CoaXPress bandwidth the MV-GX1008 is an octo CXP-6 frame grabber.

Frame grabbersHikrobot MV-GX1008 Octo CXP-6 Frame GrabberMV-GX1008
Interface
CoaXPress
$1,949.00View partBuild a system with it

On Camera Link the match list is different — mode, connector and tap configuration — and Camera Link camera and frame grabber compatibility: what must match lists it.

AccessoriesFrame grabbers

CoaXPress, Camera Link and GigE cards

58 models · from $189.00

Next step: pick the card that speaks your camera's interface in the accessories finder, start a build in the system configurator, or reach us through the contact page if you want a second opinion before ordering.

Questions

Why does GStreamer report Signal lost when the video node exists?

The warning comes from v4l2src's preferred-size probe. Moving to PAUSED, the source asks the capture node which format to use as a default, and the driver reports no input source, so video frames are invalid. It is a hint, not the fatal error: the pipeline dies on the next line, streaming stopped, reason not-negotiated (-4), which is the caps intersection failing. Read the error; use the warning as a sign the sensor side never handed the node a usable mode.

Which fourcc matches the YUYV8_1X16 media-bus code?

V4L2_PIX_FMT_YUYV, written format=YUYV in GStreamer caps. Its byte-swapped relative, UYVY, belongs to a different media-bus code, so a pad carrying YUYV8_1X16 has no reason to offer UYVY. Packed two-bus variants such as YUYV8_2X8 map to the same YUYV fourcc. The kernel header documentation carries the full media-bus to fourcc mapping, and your node's --list-formats-ext output always wins over any table inference.

My caps match every field and streaming still stops — what then?

Check whether the subdev ever linked. If --list-formats-ext prints no formats, or media-ctl shows no format on the sensor pad, the chain is incomplete upstream. Look in the kernel log for a device-link creation failure from the CSI host driver beside the bind message, compare the virtual-channel id in the sensor-mode device-tree node against the vc-id on the CSI and VI nodes, and confirm the kernel matches the release the camera stack documents.

Can I just drop the caps filter to make the error go away?

For diagnosis, yes: an unfiltered v4l2src into fakesink with gst-launch -v shows which format the driver picks, and those fields belong in your filter. For the shipping pipeline, keep the explicit matching caps string. Unfiltered, you accept whatever default the driver chooses, which can differ between driver releases and may not be the resolution or interval your downstream stages assume.

Does this apply to GigE and USB3 machine-vision cameras on Linux?

Rarely. GigE Vision and USB3 Vision cameras expose a plain capture node or a GenICam-based API, and pixel format negotiation runs against the camera's own format list. There is no sensor subdev, CSI receiver or media-bus code in that path, so the media-controller mapping covered here does not arise; a not-negotiated (-4) there points at application-side caps instead.