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:
- Sensor format
- 1/1.7"
- Lens mount
- C-mount
- Sensor format
- 1"
- Lens mount
- C-mount
How do you prove the camera link is healthy first?
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:
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.
- Sensor format
- 1/1.7"
- Interface
- USB3
- Resolution
- 12 MP
- Shutter
- Rolling
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.
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.
- Install the nested server package:
sudo apt-get install xserver-xephyr
- Start it on a spare display number:
Xephyr -br -ac -noreset -screen 1920x1080 :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:
- Interface
- GigE
- Resolution
- Up to 3 MP
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.




