Piping Raw Video from FFmpeg to Linux Tools

This article provides a practical guide on how to stream raw, uncompressed video data from FFmpeg into other Linux command-line utilities using standard streams. We will cover the specific FFmpeg syntax required to output raw pixel data, how to configure the receiving tool to read this data correctly, and explore common use cases such as piping video into tools like ffplay or custom scripts.


Understanding the FFmpeg Pipe Protocol

By default, FFmpeg expects an output file name to determine the container format and multiplexing settings. However, you can instruct FFmpeg to route its output directly to standard output (stdout) by using a single dash - or the explicit pipe: protocol.

When dealing with raw video, it is crucial to strip away container formats (like MP4 or MKV) and output the raw pixel bytes sequentially, frame by frame. Because raw video lacks a header to describe its dimensions or color space, you must explicitly define these parameters so the receiving application knows how to interpret the incoming byte stream.

The Standard Command Structure

To pipe raw video data successfully, use the following FFmpeg command template:

ffmpeg -i input.mp4 -f rawvideo -pix_fmt yuv420p -

Piping into Another Command

To send this data to another Linux tool, use the standard Linux pipe operator (|). The receiving tool must be configured to read from standard input (stdin) and must be manually told the video dimensions and pixel format, as raw video contains no metadata.

Example 1: Piping into FFplay for Real-Time Testing

A great way to verify your pipe is working is to pipe the raw data directly into ffplay. Notice how you must tell ffplay the resolution and pixel format so it can render the raw bytes correctly:

ffmpeg -i input.mp4 -f rawvideo -pix_fmt rgb24 - | ffplay -f rawvideo -pixel_format rgb24 -video_size 1920x1080 -

Example 2: Piping into a Custom Image Viewer (e.g., ImageMagick)

You can pipe raw frames into tools like ImageMagick’s stream utility to process individual pixel data:

ffmpeg -i input.mp4 -f rawvideo -pix_fmt rgb24 - | stream -map rgb -storage-type char -size 1920x1080 - output.png

Best Practices and Performance Considerations

Raw, uncompressed video generates a massive volume of data per second. A single 1080p frame in RGB24 format requires roughly 6 megabytes of data. At 60 frames per second, you are pushing over 360 megabytes per second through the Linux pipe.

To prevent bottlenecks, ensure your receiving tool can process the data as fast as FFmpeg produces it. If the downstream tool is slow, FFmpeg will pause and wait, which can cause high memory usage or dropped frames in live streaming scenarios. If you experience performance issues, consider lowering the resolution using FFmpeg’s video filter (-vf scale=640:360) before piping the data.