System designTroubleshooting

Camera preview flickers on embedded GPU boards: match the render path

A preview that flickers only on an embedded GPU board is a rendering fault, not a camera-link fault: check the frame counter, then run the viewer on Mesa.

LumaSpec Vision8 min read Share on LinkedIn

On this page 8 sections
  1. 01Why does the preview flicker in continuous mode while single shots look fine?
  2. 02How do you prove the camera link is healthy first?
  3. 03Which OpenGL stack is the viewer using right now?
  4. 04How do you force the viewer onto Mesa with a nested X server?
  5. 05How do you verify the fix worked?
  6. 06What if the flicker persists inside the nested display?
  7. 07How do you keep the next station from hitting this?
  8. 08Questions

Your camera previews cleanly on a laptop, but on the embedded ARM board that will run the station the live preview flickers the moment you switch to continuous acquisition. Single shots look fine and the frame counter keeps climbing. This guide walks the bench diagnosis: prove the acquisition path first, then move the viewer's rendering from the SoC vendor's GPU driver onto the open-source Mesa stack with a nested X server. The commands take about ten minutes. You will finish knowing whether the fault sits in the display path or the capture path, and what to do in each case.

Why does the preview flicker in continuous mode while single shots look fine?

Because the fault is in the drawing path, not the camera: boards whose SoC vendor supplies a GPU driver install two OpenGL stacks, that driver and Mesa, and the viewer binds the vendor one, which tears when the preview redraws at a camera's full 30 fps.

In continuous mode the viewer's OpenGL widget repaints for every incoming frame, dozens of times a second. A single-shot acquisition repaints once, so the same defect stays invisible until you go live. The camera keeps streaming either way: the frame counter climbs and frames save correctly while the window tears.

A laptop carries one OpenGL stack, usually a mature desktop driver, so the same viewer on the same cable previews steadily there. Boards where Mesa is the only OpenGL implementation behave too. That asymmetry — steady on one host, flickering on another — is the signature of a render-path fault, and it is what the fix below targets.

Any camera reaches the same widget, whatever its interface:

Area scan camerasHikrobot MV-CU020-90GC 2.5 MP Area Scan Camera, GigE, GMAX4002, ColorMV-CU020-90GC
Sensor format
1/1.7"
Lens mount
C-mount
$309.00View part
Area scan camerasHikrobot MV-CS200-10UM 20 MP Area Scan Camera, USB3.0, IMX183, 2nd Gen., MonoMV-CS200-10UM
Sensor format
1"
Lens mount
C-mount
$759.00View part

Swap the host before you touch any setting: the same camera on the same cable showing a clean continuous preview on a laptop clears camera, cable, power and SDK in one move, and it takes five minutes.

On the board itself, open the viewer's statistics pane while it flickers and watch the frame counter. If the counter holds the commanded rate, sensor and link are delivering and only the picture on screen is failing. Put a number on it with the camera's own figures.

The LS-CMR-0166 prints 4000 × 3000 pixels and 30 fps. Count what the link must sustain for 8-bit mono at one byte per pixel:

bytes per frame = width × height × bytes per pixel sustained rate = bytes per frame × frame rate

4,000 px × 3,000 px × 1 B = 12,000,000 B, about 12 MB per frame. At 30 fps the link carries 12 MB × 30 = 360 MB/s. A counter holding 30 fps while the window flickers means the USB3 path is delivering 360 MB/s of pixels, and the flicker cannot live on the capture side.

Area scan cameras12 MP USB3 area scan camera, IMX226, 1/1.7" rolling shutter, 30 fps, 4000 × 3000 resolution (LS-CMR-0166)LS-CMR-0166
Sensor format
1/1.7"
Interface
USB3
Resolution
12 MP
Shutter
Rolling
$560.00View partBuild a system with it

Keep one known-good lead for the swap so a marginal cable never masquerades as a render fault — a 3 m USB3.0 high-flex camera cable does that job. Spare camera data cables settle any remaining doubt in one more swap.

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

Which OpenGL stack is the viewer using right now?

On these boards, both: the vendor GPU driver and Mesa, the open-source implementation of OpenGL, sit installed side by side, and the display server hands the viewer the vendor stack by default.

You cannot simply toggle the viewer onto Mesa while the vendor driver is loaded; the stacks are not mixed per application on this class of board. So the fix is not a settings change but a second display. It also explains a pattern worth knowing: ARM boards that ship Mesa alone preview steadily, and the trouble appears only where the vendor driver is present too.

How do you force the viewer onto Mesa with a nested X server?

Run a nested X11 server as display :1 at 1920 × 1080 and launch the viewer with DISPLAY pointing at that display: the viewer loads Mesa for its rendering while the rest of the desktop keeps the vendor driver.

  1. Install the nested server package:
sudo apt-get install xserver-xephyr
  1. Start it on a spare display number:
Xephyr -br -ac -noreset -screen 1920x1080 :1 &
  1. Launch the viewer inside it, replacing the placeholder with the launch command your camera vendor publishes for the viewer:
DISPLAY=:1 <viewer-launch-command>

A window opens inside the Xephyr window, and the preview in it renders through Mesa. The -screen 1920x1080 argument sets the emulated display size, :1 is the new display number — the desktop usually owns :0 — and DISPLAY=:1 points only that one process at it. Nothing on the camera side changes: same exposure, same trigger, same frame rate.

How do you verify the fix worked?

Two checks, in this order: the frame counter must hold the commanded rate — 30 fps in the worked example — with the preview steady, and a raw frame saved while the preview runs must open clean.

If both pass, the fault was the render path. The saved frame carries the most weight, because it is the product of the camera path alone with no drawing involved: a clean file under a flickering window is the clearest proof that acquisition is intact.

What if the flicker persists inside the nested display?

Then, and only then, move to the capture side: work the causes in probability order — capture buffering, USB memory limits, then cable and link — because the nested display has just cleared the render path.

For a USB camera, flicker that survives the render fix points at buffering on the capture side; USB camera flickering on Linux: check capture buffering walks that fix. A counter sagging below the commanded rate points at the USB3 path, and USB3 camera low frame rate and latency covers the memory and exposure settings involved. Horizontal streaks on a GigE camera are a link symptom rather than a rendering one: see GigE camera streaked frames on an embedded board.

A small share of cases trace to synchronization between the viewer's render widget and image ingest on embedded ARM, and no per-application render switch touches those. Even then the nested display does its job as a diagnostic: it separates rendering from capture cleanly enough to route you to the capture-side fixes above, and saved frames stay the ground truth.

How do you keep the next station from hitting this?

Commission the preview on the target board, never on a laptop, and write the nested-display launch line into the station's start-up notes so the fix outlives the person who found it.

When you choose the host, check its graphics stack as part of acceptance: choosing an ARM board for USB3 camera acquisition lists the board-side checks that belong in that pass. If the station needs inspection decisions rather than a person watching a preview, a vision sensor removes the PC render loop entirely:

Smart cameras & vision sensors1.6 MP smart camera, 60 fps, 16 mm lens, white light (polarized, transparent light) (LS-SMC-0063)LS-SMC-0063
Interface
GigE
Resolution
Up to 3 MP
$1,110.00View part

Smart cameras trade a full viewer's flexibility for a set-up that cannot develop this class of fault, because the inspection runs on the device and the results go out over Ethernet. For stations that keep an area scan camera and a host, the camera finder and the configurator put camera, interface and cable choices in one place, and our team answers host-compatibility questions through the contact page.

Questions

Does a flickering preview mean my captured frames are bad?

No. The preview is a rendering of frames the camera already delivered, and a render-path fault corrupts nothing. Save a raw frame while the window flickers and open it: a clean file under a flickering preview is the signature of this fault. If the saved frames show the same tearing or dropped regions, move to the capture-side checks instead.

Can I switch the whole board to Mesa instead of using a nested display?

Not per application. On boards that ship the vendor GPU driver alongside Mesa, the two stacks do not mix while the vendor driver is loaded, and there is no supported toggle that moves a single viewer onto Mesa. The nested X server is the clean way to give the viewer its own display and its own stack without rebuilding the desktop the rest of the system depends on.

Does the nested-display workaround cost capture performance?

It costs CPU on the display side, not on the camera path. Rendering through Mesa moves the drawing work from the GPU onto CPU cores, so a 1920 × 1080 preview will use more processor than before. Exposure, trigger and frame rate are untouched, because they live in the camera and the capture library, not in the window that draws them.

Do GigE cameras flicker the same way on these boards?

Yes, when the cause is the render path, because the viewer's OpenGL widget is the same whatever feeds it. A GigE link carries roughly 100 MB/s in practice on a 1 Gbit/s connection, far below what stresses the host, so a steady frame counter under a flickering window is just as diagnostic there. The nested-display fix is identical for both interfaces.

What if the frame counter stutters too, not just the picture?

That moves the fault to the capture side. A counter below the commanded rate means frames are not arriving, whatever the window looks like. Start with capture buffering, then the USB memory limit for USB3 cameras, then the cable and link. The capture-side flicker guide and the USB3 frame-rate guide on this site walk those settings with their exact parameters.