You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何基于GStreamer实现环形缓冲区解决嵌入式摄像头帧文件损坏问题?

Solving Your GStreamer Ring Buffer & Stream Splitting Problem

Hey there! Let's break down how to fix your concurrent file corruption issue, keep the 25fps display stream, and implement that 10-file ring buffer for OpenCV processing—all using GStreamer's built-in tools, no external scripts required.

Core Approach

The key here is to split your camera stream into two separate branches with GStreamer's tee element:

  • One branch maintains the full 25fps for user display
  • The other branch gets downsampled to ~2fps, then writes to a rotating set of 10 JPEG files (your ring buffer)

Working Bash Script

Here's the updated pipeline that does exactly what you need:

STREAM_BUFFER_SIZE=-1
FILE_LOCATION=/tmp/cameraStreamResults
FRAME_RATE=25/1
# Use %02d to create indexed files (00-09) for the ring buffer
FILE_PREFIX=streamImage_%02d.jpg
# Total number of files in our ring buffer
RING_BUFFER_COUNT=10
# Target frame rate for OpenCV processing (2fps)
PROCESS_FRAME_RATE=2/1

mkdir -p $FILE_LOCATION

gst-launch-1.0 \
v4l2src num-buffers=$STREAM_BUFFER_SIZE device=$IPU1_CSI0_DEVICE ! \
video/x-$COL_FORMAT$FRAME_SIZE,framerate=$FRAME_RATE ! \
videoconvert ! \
# Split the stream into two branches
tee name=stream_splitter \
# Branch 1: Full 25fps stream for user display
stream_splitter. ! queue ! videoconvert ! autovideosink sync=false \
# Branch 2: Downsample to 2fps, encode to JPEG, write to ring buffer
stream_splitter. ! queue ! videorate ! video/x-raw,framerate=$PROCESS_FRAME_RATE ! \
jpegenc ! \
multifilesink location=$FILE_LOCATION/$FILE_PREFIX max-files=$RING_BUFFER_COUNT next-file=max-files-reached sync=false

Key Component Breakdown

Let's walk through the important parts so you understand what's happening:

  • tee: This element duplicates your input stream into multiple independent branches. No more fighting over a single file!
  • videorate: Forces the processing branch to drop frames down to 2fps—exactly what you need for OpenCV.
  • multifilesink Ring Buffer Setup:
    • location=$FILE_LOCATION/$FILE_PREFIX: The %02d placeholder creates files named streamImage_00.jpg to streamImage_09.jpg.
    • max-files=$RING_BUFFER_COUNT: Limits the total number of files to 10.
    • next-file=max-files-reached: Once we hit 10 files, GStreamer automatically overwrites the oldest file first—perfect for a ring buffer.
  • queue: Adds buffering to each branch so display and frame processing don't block each other (e.g., if display lags, it won't stop frame saving).

OpenCV Integration Tips

For your OpenCV script, you can:

  • Poll the /tmp/cameraStreamResults directory and check file modification times to grab the latest 2 frames.
  • Or simply loop through the indexed files (00 to 09) in order—since GStreamer overwrites the oldest first, you'll always get the most recent data.

No more corrupted files because each JPEG is fully written before it's ever overwritten, and we're never writing to the same file twice at the same time.

内容的提问来源于stack exchange,提问作者Thron

火山引擎 最新活动