You connected a USB3 Vision camera, it shows up in the viewer, and pressing play either crashes with an invalid memory access message or leaves a window frame with no image under it. One cause explains nearly every case like this: the camera outputs only Bayer formats, and the pipeline has no element that converts Bayer to RGB. This guide follows the fault in the order you meet it — the not-negotiated (-4) stop in the log, the format list that explains it, the bayer2rgb element that fixes it, and the garbage window that means the fault has moved into the host's conversion libraries. You finish with a working pipeline, a decision on where debayering belongs, and a checklist that separates a camera fault from a software fault in minutes.
Why does the viewer crash or open a window with no image in it?
Because the camera sends raw Bayer and nothing in the pipeline converts it: videoconvert does not debayer, so the stream either fails format negotiation before the first frame or reaches a conversion element that is broken on that host and crashes the viewer.
A Bayer frame carries one intensity value per pixel, with the color defined by that pixel's position under the sensor's filter mosaic. RGB exists only after a demosaic step, and that step is a separate element, never part of videoconvert. In arv-viewer two symptoms appear: an instant crash on play quoting invalid memory access, or the window chrome and its taskbar rendered with nothing beneath. If frames do arrive and look like a dark checkerboard with a color cast, raw Bayer is reaching your sink — how to recognize a raw Bayer stream from an RGB camera shows the patterns.
| What you see | Run this first | What it means | The fix |
|---|---|---|---|
| Crash on play: invalid memory access | arv-tool-0.6 features |
only Bayer formats offered, no debayer in the pipeline | insert bayer2rgb after the source |
Log stops at reason not-negotiated (-4)
|
arv-tool-0.6 features |
the caps at one link have no overlap | the same insertion |
Log floods with arv_camera_get_gain assertions |
arv-tool-0.6, camera attached |
the pipeline never opened a camera | connect, confirm, relaunch |
| Window paints desktop content | synthetic rgb2bayer ! bayer2rgb loop |
conversion library fault on the host | update the conversion stack, or debayer in code |
| Pipeline refuses to build: no element "aravissrc" | run the launcher from the aravis gst directory | the source plugin is not registered | register the plugin or use the bundled launcher |
Why does the log stop with not-negotiated (-4)?
It means two adjacent elements could not agree on a media format: the source offered only Bayer caps, the next element accepted none of them, and the stream thread paused before a frame reached the display.
The log calls it an internal data flow error and appends reason not-negotiated (-4). Nothing in that message names the guilty link, which is why it sends people chasing the camera, the cable and the driver. The answer is already sitting in the camera's format list, one section ahead. The same mechanism — caps with no overlap at a link — breaks pipelines in several other ways, and the camera pipeline format negotiation guide covers the wider family.
How do you list the formats the camera actually offers?
Run arv-tool-0.6 features with the camera connected; when every supported format contains the word Bayer, the sensor has no RGB mode at all and the pipeline must carry a debayer element.
That single output settles the question, and the whole fix hangs on it. Color sensors expose Bayer in 8, 10, 12, 14 or 16 bits per pixel, and the depth you pick matters two sections down. The active format lives in the PixelFormat feature on the camera, and on the GigE side a camera can also boot into a format the consumer does not expect — the GigE pixel format default fix covers that variant. Run the tool with the camera on the cable: with nothing connected it lists nothing, and the query never reaches hardware.
What does the working pipeline look like?
One element longer: put bayer2rgb directly after the camera source and before videoconvert, and the stop disappears, because the Bayer caps now meet an element built to accept them.
Prove the display path first, with no camera in the chain:
gst-launch-1.0 videotestsrc ! videoconvert ! autovideosink
A test card there means the sink and the conversion libraries load. Then the camera pipeline, run from the gst directory of an aravis source tree with the bundled launcher:
./gst-aravis-launch aravissrc ! bayer2rgb ! videoconvert ! autovideosink
Give the element an 8-bit Bayer format at the camera — that is the depth it converts, and the deeper formats belong to the processing path, not the preview. If the pipeline refuses to build with no element "aravissrc", the aravis source plugin is not registered with your GStreamer; that missing-plugin failure has its own diagnosis in the GStreamer missing-plugins walkthrough.
Why does the log fill with arv_camera_get_gain assertion failures?
Those criticals mean the pipeline never opened a camera: the handle is empty, every property query fails the same assertion, and nothing downstream matters until the device is connected and enumerated.
In one documented case the launcher ran with the camera on the bench rather than on the cable, so the gain, exposure and region queries all failed before the stream thread started. Connect the camera, confirm it appears under arv-tool-0.6, and relaunch — the pipeline then ran far enough to reach its real fault. The opposite symptom, properties readable but no frames arriving, is a different break: an Aravis camera that reads properties but streams no video covers it.
Why does the window paint garbage instead of the camera image?
Because the conversion path produced no valid pixels and the window showed whatever bytes already occupied that buffer — the fault is in the host's libraries, and the camera is usually innocent.
When the fixed pipeline opens a window that renders your desktop or terminal instead of the sensor, take the camera out of the chain and test the conversion pair alone:
gst-launch-1.0 videotestsrc ! videoconvert ! rgb2bayer ! bayer2rgb ! videoconvert ! autovideosink
A clean synthetic pattern there, with garbage from the camera, points back at the source; garbage from the loop as well convicts the host. Both crashes in the documented case traced to functions sharing orc, the Optimized Inner Loop Runtime Compiler that accelerates these conversions, on a 2016-era enterprise Linux install with distribution packages. The fix is at the package level: update GStreamer and orc together on that machine, then re-run the loop until the pattern is clean. A preview that stays blank rather than garbage has a neighboring diagnosis in unsupported Bayer pixel format: diagnose a blank preview.
Where should the debayer run: GStreamer or your own code?
In GStreamer when a person watches the preview; in your processing code when software consumes the frames — raw Bayer at 8-bit moves one byte per pixel across the link, and RGB triples that before your algorithm has used any of it.
The arithmetic decides it. The LS-CMR-0166 is a 12 MP USB3 area scan camera with the IMX226 sensor, 1/1.7" rolling shutter, 30 fps and 4000 × 3000 resolution. One frame is 4000 × 3000 = 12,000,000 pixels. At 8-bit Bayer that is 12 MB, and at 30 fps the link carries 12 MB × 30 = 360 MB/s, about 2.9 Gbit/s — comfortable inside the 5 Gbit/s USB3 line rate with room for protocol overhead. Debayered to RGB inside the pipeline first, the same stream needs 36 MB per frame and 36 × 30 = 1080 MB/s, about 8.6 Gbit/s, which that line rate cannot carry at any setting. So the preview converts in GStreamer, and the measurement path takes raw Bayer into code, converting once, at full depth, where the pixels are used.
For packed 10- and 12-bit depth the same rule holds: capture the packed frames and unpack them in your own pipeline — packed Bayer 12-bit conversion to a 16-bit image shows the steps. Browse area scan cameras when you buy for this split of labor. The MV-CH120-11UC is a 12 MP USB3 color camera with the IMX304 sensor, global shutter and a 1.1" sensor format — the same preview-versus-processing decision applies to it unchanged.
- Sensor format
- 1/1.7"
- Interface
- USB3
- Sensor format
- 1.1"
- Lens mount
- C-mount
When is the black image not the pipeline's fault?
When the device was never opened, when the USB link fell back to a slower speed, or when the frame is torn or banded rather than empty — those sit outside GStreamer, at the connection, the cable or the exposure path.
A USB3 camera that silently negotiated USB2 delivers a fraction of its bandwidth and can mimic a broken pipeline: why a USB3 camera negotiates USB2 speed shows the check. The cure is usually the cable. The LS-CBL-0219 is a 3 m USB3.0 camera cable built for drag-chain use; more lengths and connector types sit under camera cables and the accessories finder.
Run arv-camera-test 10s with the camera in place next: it exercises acquisition with no viewer in the way. Torn or banded frames that change as you flex the cable are a hardware fault with their own playbook — the robot vision camera image-corruption field guide works that path end to end.
What order should the checks run in?
In this order, about ten minutes end to end: prove the display, prove the device, read the formats, fix the pipeline, isolate the host, confirm acquisition, then pin the depth you actually need.
-
gst-launch-1.0 videotestsrc ! videoconvert ! autovideosink— a clean test card proves the display path. -
arv-tool-0.6with the camera connected — the device must appear here before any pipeline can open it. -
arv-tool-0.6 features— all-Bayer output settles the debayer question on the spot. -
./gst-aravis-launch aravissrc ! bayer2rgb ! videoconvert ! autovideosink— the fixed pipeline; the window should show the sensor. -
gst-launch-1.0 videotestsrc ! videoconvert ! rgb2bayer ! bayer2rgb ! videoconvert ! autovideosink— garbage here convicts the host libraries, not the camera. -
arv-camera-test 10s— confirms acquisition with the viewer out of the loop. - Leave PixelFormat on an 8-bit Bayer format for previews; move to packed depth only inside the processing code.
With the stream stable, pick the sensor in the camera finder and start the configurator below from the camera step. More integration notes live on the systems topic page, and if the stack keeps fighting you, bring the log to the contact page and we will read it with you.
The configurator matches a camera, lens, light, light controller and cables to each other, step by step, and lists only parts that fit what you already picked.
Questions
Does bayer2rgb convert 10-bit and 12-bit Bayer formats?
bayer2rgb converts 8-bit Bayer; set PixelFormat to an 8-bit Bayer format before the preview pipeline. Color sensors offer Bayer depths of 8, 10, 12, 14 or 16 bits, and a preview that works at 8-bit then goes black after a switch to a packed depth is the element refusing that depth, not a camera fault. Keep packed frames for the processing path and convert them there.
Why did the fake camera fail exactly like the real one?
Because the failing component lived on the host, not in either camera. The viewer's fake device supplies its own frames with no hardware attached, so a crash at the same code path with the cameras disconnected removes them from the suspect list entirely. It is the fastest isolation test available: when the fake device crashes too, stop debugging drivers and cables and work on the conversion elements and their runtime libraries.
How do you read the camera's active pixel format before streaming?
arv-tool control PixelFormat returns the format the camera will send; arv-tool-0.6 features lists everything the sensor offers. Run both with the camera connected, because the tool reports an empty device list with nothing attached. Keep the two outputs in your commissioning notes: together they settle format questions without streaming a single frame.
Is the camera damaged when the window shows a screenshot-like pattern?
No. That pattern is whatever bytes happened to occupy the buffer the window displayed — the conversion path produced no valid pixels, and the sink showed stale memory. Watch the camera's acquisition LED during the test: if it flashes while the window shows garbage, the sensor is exposing on command and the fault sits entirely downstream, in the conversion elements or their runtime libraries.
Why does the pipeline work on one PC and fail on another?
Because the Bayer elements ship as plugins and their runtime libraries differ between installs. On some distributions the Bayer plugin is a separate package, so a pipeline that links on one machine dies with a missing-element error on another; on older enterprise installs the conversion libraries themselves carry faults. Pin the plugin version everywhere you deploy, and keep the synthetic rgb2bayer-to-bayer2rgb loop in your commissioning notes as the ten-second host check.


