Read Raw Video from Shared Memory into FFmpeg

Reading raw video frames from a shared memory segment into FFmpeg is an efficient way to process video data in real-time without the overhead of disk I/O. This guide explains how to configure FFmpeg to ingest raw pixel data from shared memory using named pipes (FIFOs) or standard input (stdin) redirection, detailing the exact command-line parameters required to interpret the raw stream.

Why Use an Intermediary for Shared Memory?

FFmpeg does not have a native, built-in input device protocol for directly mapping IPC (Inter-Process Communication) shared memory blocks (like POSIX shm_open or Windows Named Shared Memory). To read this data, you must stream the raw memory buffer out of the shared memory segment and into FFmpeg using one of two primary methods: standard input piping or named pipes (FIFOs).

Method 1: Piping via Standard Input (stdin)

The most common approach is to write a lightweight script (in Python, C++, or Go) that attaches to the shared memory segment, reads the raw frames, and writes them directly to standard output. FFmpeg then reads this data from standard input.

The FFmpeg Command

python read_shm.py | ffmpeg -f rawvideo -pix_fmt rgb24 -s 1920x1080 -r 30 -i - -c:v libx264 output.mp4

Parameter Breakdown:

  • -f rawvideo: Tells FFmpeg that the incoming data has no container format or headers.
  • -pix_fmt rgb24: Defines the pixel format of the raw frames (e.g., rgb24, bgr24, yuv420p, or bgra). This must exactly match the memory layout of the shared memory buffer.
  • -s 1920x1080: Specifies the width and height of the video frames. Because raw video lacks metadata, FFmpeg cannot auto-detect the resolution.
  • -r 30: Sets the input framerate to 30 frames per second.
  • -i -: Instructs FFmpeg to read the input from stdin.

Method 2: Using a Named Pipe (FIFO)

If you prefer not to use standard input redirection, you can use a system named pipe. The application controlling the shared memory writes to the pipe, and FFmpeg reads from it as if it were a physical file.

Step 1: Create the Named Pipe

On Linux or macOS, create a FIFO pipe using the command line:

mkfifo /tmp/video_pipe

Step 2: Launch FFmpeg to Listen to the Pipe

Run FFmpeg, pointing the input parameter to the newly created FIFO:

ffmpeg -f rawvideo -pix_fmt yuv420p -s 1280x720 -r 60 -i /tmp/video_pipe -c:v copy output.mkv

Step 3: Write Shared Memory Data to the Pipe

In your application, open /tmp/video_pipe as a standard writable file and continuously dump the raw byte buffers from the shared memory segment into it. FFmpeg will block until data begins flowing, process the frames as they arrive, and close when the pipe is broken.

Important Considerations

  • Buffer Synchronization: Ensure your writing application does not overwrite a frame in the shared memory segment before FFmpeg has finished reading it. Implement semaphores or double-buffering to prevent frame tearing.
  • Exact Byte Matching: The size of each write operation must precisely equal the expected size of one frame: Width * Height * BytesPerPixel. For a 1920x1080 frame in rgb24 format, each write must be exactly 1920 * 1080 * 3 = 6,220,800 bytes.