System designTroubleshooting

Stop and start camera streaming without crashing paired sensors

Why stop and start streaming crashes a paired camera rig, the ~2 fps restart floor, and how to discard frames at the host instead of stopping the sensors.

LumaSpec Vision10 min read Share on LinkedIn

On this page 10 sections
  1. 01What the crash looks like
  2. 02Why a synchronized pair fails on restart
  3. 03Separate the causes in minutes
  4. 04The fix: keep streaming and discard frames at the host
  5. 05Gate the flow on the device when the link is the bottleneck
  6. 06When stop and start is safe
  7. 07Recovery when the device has already died
  8. 08Build the rig so every sensor can run alone
  9. 09Prevention checklist
  10. 10Questions

Stop works. Start works once. On the second stop-and-start of a synchronized two-sensor camera head, one sensor never comes back, the other delivers a handful of frames and freezes, and the next stop command returns a fatal error from the device's MIPI receive path. If you run a stereo head, a synchronized mono pair, or any multi-sensor device addressed as one pipeline, this page gives you the cause, three tests that separate the failure modes, and the fix: keep the pair streaming from power-up to shutdown and discard the frames you don't need at the host. Reserve a true stop and start for a single, independently timed sensor running near its frame-rate floor.

What the crash looks like

The sequence repeats reliably enough to recognize on sight. Both sensors display on the first start. The first stop succeeds. On a restart — usually the first, sometimes the second — one sensor produces nothing while the other emits a few frames and then freezes. The next stop command triggers a critical error logged by the device from PlgSrcMipi with code 1130, followed by the host warning "Device crashed, but no crash dump could be extracted." At that point the device is finished for the session: no stop, start or pipeline command brings it back, and the only recovery is closing it and re-enumerating, or removing power.

The camera crash when stopping acquisition: isolate the cause guide covers the wider family of stop-time crashes; the pair-specific version has the narrower cause list below.

Why a synchronized pair fails on restart

Three causes cover this failure, ordered by how often each turns out to be the one.

1. The pair loses its shared frame timing. The two sensors' timing relationship is established once, when the pipeline starts. Vendor guidance treats streaming stop and start as sensor-dependent — it does not work flawlessly on every sensor — and a synchronized pair is the worst case. A restart has to land both sensors back in phase on a timing relationship they share: one sensor waits for the shared timing and never recovers it, the other free-runs briefly, and the MIPI receive path ends in a state it treats as fatal.

2. The restart runs above the sensor's frame-rate floor. Vendor guidance puts the dependable restart point at a sensor's minimum frame rate. Issued near the top of the range, the restart has to land inside a frame boundary a few tens of milliseconds wide, on two sensors at once.

3. The control commands race. When one control stream feeds both sensors, the stop reaches one sensor before the other — and the same happens on start. Different trigger, same end state.

Separate the causes in minutes

Run the tests in this order; each takes a bench minute and points at a different fix.

Likely cause Test Result that confirms it
Pair out of phase After a failed restart, poll both frame queues for 5 s One queue stays empty; the other delivers a few frames, then goes quiet
Restart above the floor Set the frame rate to about 2 fps and run 20 stop/start cycles Every cycle succeeds
Control-path race Send the two stop commands 500 ms apart, then the two start commands 500 ms apart Failures become rare or disappear

On a rig that lets you enable one sensor alone, stop and start that sensor by itself. If it restarts cleanly every time while the pair fails, the shared timing is the culprit. Causes 1 and 3 also share a fix: both disappear once you stop toggling the pair mid-operation.

The fix: keep streaming and discard frames at the host

The decision: on a synchronized pair, never send the stop-streaming command in operation. If your pipeline exposes a camera-control message, its setStopStreaming() and setStartStreaming() methods are exactly the pair to leave alone here. Start the pipeline once, let both sensors run to shutdown, and throw away what you don't need downstream. The sensors never leave their timing relationship, so the pair stays in phase and the MIPI receive path stays alive.

Make discarding free at the host: give each output queue a small capacity — 4 frames works — and non-blocking behavior, then poll it in your loop and process the newest frame. A blocking queue does the opposite; it backs up, the device stalls waiting for the host, and you reintroduce the freeze you were avoiding. When callbacks go quiet because a queue is full, the camera streaming callback not called: keep acquisition alive walkthrough traces the host-side causes.

Worked example — a 30 fps pair feeding a host loop that wakes every 250 ms:

frames delivered per loop = 30 frames/s × 0.25 s = 7.5 frames queue capacity = 4 frames, so frames dropped per loop = 7.5 − 4 = 3.5 frames drop rate = 3.5 frames/loop × 4 loops/s = 14 frames/s processed rate = 30 − 14 = 16 frames/s oldest processed frame = 4 / 30 s ≈ 0.13 s (133 ms) after capture

Prove it on the bench: run 10 s with counters on both rates. Expect roughly 300 frames timestamped by the sensors, about 160 processed and 140 dropped at the host, with the sensor frame rate unchanged. The camera frame rate measurement from timestamped frames method gives the sensor-side count; if that count moves while you drop frames, the drop is not happening at the host and you have a different problem.

The frame-per-FSYNC contract survives untouched. Because the sensors never stop, each FSYNC toggle still produces exactly one frame; discarding happens after the frame has left the sensor. Keep the frames whose timestamps line up with the toggles you need and drop the rest.

Discarding at the host costs link bandwidth: the pair still sends every frame across USB or Ethernet so the host can drop 14 of every 30. When that traffic matters, move the discard upstream: a script node inside the pipeline sits after the frame sources, keeps the frames your logic flags, and forwards only those. The sensors never stop, so the pair timing and the frame-per-FSYNC relationship hold while the wire carries only what you use. It is the same principle as camera ROI cropping at the source: cut the data before the host, not after.

When stop and start is safe

On a single sensor with its own clock and its own link — one camera, one pipeline — stop and start is routine, under two conditions. Run the frame rate at or above the sensor's documented minimum, about 2 fps for most sensors: at 2 fps the frame period is 500 ms, so the restart has room to land, and you should wait two frame periods — 1 s — before judging the stream dead. And when the change is a parameter rather than a lifecycle event, change it while streaming: applying camera settings while streaming without stalling capture shows that pattern, and single-frame acquisition still busy: why repeated starts need a stop covers the stop/start lifecycle quirks of one sensor.

Preview-style hosts have a third tool: restarting the live camera preview without reopening the device keeps the device object alive across restarts, and the full reopen is where most of this latent state hides.

Recovery when the device has already died

After the fatal error from PlgSrcMipi, no in-band command recovers the device: the pipeline's frame source has crashed and left no dump to consult. Close the device so the host re-enumerates it, and if it still fails to open, remove power for a few seconds and try again. Then keep the next occurrence from costing you a shift with a watchdog: after any start, expect the first frame within about 100 ms at 30 fps — two frame periods (67 ms) plus margin — and recycle the device when it never arrives.

Build the rig so every sensor can run alone

If you are still specifying hardware, fix it architecturally: one sensor per camera, each with its own clock and its own USB3 or GigE link, exposures synchronized by a shared trigger line instead of streaming toggles. Each device then starts and stops independently, and a restart on one never touches another's timing. The camera GPIO wiring guide covers the trigger line and its damage modes, and multi-camera sensor matching for synchronized vision handles the sensor-to-sensor uniformity side.

Board-level cameras are the parts meant for this build — a single sensor per board, global shutter, and a C-mount or M12 lens position, each on its own link:

Board-level cameras3.1 MP USB3 board-level camera, IMX252, 1/1.8" global shutter, 120 fps (LS-BCM-0003)LS-BCM-0003
Sensor format
1/1.8"
Lens mount
C-mount
$690.00View part
Board-level camerasHikrobot MV-CB016-10GM-M-W 1.6 MP GigE board-level camera, IMX296, Mono, M12 lens mount, WTB GigE portMV-CB016-10GM-M-W
Sensor format
1/2.9"
Lens mount
M12
$559.00View part

For a housed sensor instead of a bare board, the MV-CU020-90GC is a 2.5 MP GigE area scan camera with a 1/1.7" global shutter and a C-mount:

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
Interface
GigE
Resolution
Up to 3 MP
$309.00View partBuild a system with it

The area scan cameras category holds the mounted equivalents across interfaces and resolutions. And when the pair exists to produce depth, skip the DIY pair entirely: a camera designed as one unit carries its internal timing itself. The 3D sensors category lists stereo and structured-light devices that deliver one stream from one pipeline — no pair timing for a restart to break.

Prevention checklist

  • Synchronized pair in operation: streaming runs from power-up to shutdown; discard at the host or gate in a pipeline script node; no stop-streaming commands to the pair.
  • Receive path: queue capacity 4, non-blocking, drain-and-keep-latest in the host loop.
  • Unavoidable restarts: frame rate dropped to about 2 fps first; the host waits two frame periods (1 s) before judging the stream dead.
  • Watchdog: first frame expected within two frame periods plus margin of any start, device recycled otherwise.
  • New builds: one sensor per camera on its own link, a shared trigger for exposure sync, or a single-device 3D camera for depth.
  • Verification: a 10 s run with processed and dropped counters, and the sensor-side frame rate confirmed unchanged.

If you are sizing cameras and links for a multi-camera head, the camera finder filters by interface, shutter and resolution, and the configurator walks the rest of the chain from sensor to host. The systems topic page collects the remaining streaming and lifecycle guides.

Questions

Why does only one camera of a synchronized pair restart?

The pair's frame timing is set once when the pipeline starts, and a streaming restart has to put both sensors back in phase together. One sensor waits for that shared timing and never recovers, while the other free-runs a few frames and freezes. Keep both sensors streaming continuously and discard unneeded frames at the host; a stop and start belongs only on a single, independently timed sensor.

What frame rate should I set before restarting a camera stream?

About 2 fps, the minimum most sensors accept per vendor guidance, is the dependable restart point. At 30 fps the restart has to land inside a 33 ms frame boundary; at 2 fps the boundary is 500 ms wide and the restart has room. Expect the first frame within two frame periods, 1 s at 2 fps, before treating the stream as failed.

How do I keep one frame per FSYNC toggle without stopping the stream?

You already have it, as long as the sensors keep streaming: each toggle produces exactly one frame, so the frame-per-toggle relationship holds for the whole run. Discarding after the sensor — at the host or in a pipeline script node — never touches sensor timing, so the contract survives untouched.

How many frames should my receive queue hold?

Four is a good default with non-blocking polling. At 30 fps a capacity of 4 buffers about 133 ms of frames, bounds the age of the oldest processed image, and absorbs a host loop that hiccups for one or two periods. Larger queues add latency without adding information; smaller ones drop frames during ordinary host jitter. Never make it blocking: a full blocking queue stalls the device.

Can the device recover after the fatal MIPI source error?

No. Once the pipeline's MIPI receive path reports a fatal error with no crash dump, stop and start commands reach a dead source and change nothing. Recovery means closing the device so the host re-enumerates it, cycling power if it still fails to open, and fitting a watchdog that recycles the device when the first frame is late.