Capture V4L2 Video with MJPEG in FFmpeg to Save CPU

Capturing high-resolution video from a Video4Linux2 (V4L2) device, such as a webcam or capture card, can heavily tax your system’s CPU if the video stream is decoded and re-encoded on the fly. This article explains how to configure FFmpeg to request a pre-compressed MJPEG (Motion JPEG) stream directly from your V4L2 camera and save it without re-encoding. By utilizing the camera’s onboard hardware compression and copying the stream, you can record high-quality, high-frame-rate video with near-zero CPU usage.

Step 1: Identify Your Device and Supported Formats

Before running FFmpeg, you need to find your camera’s device path (typically /dev/video0) and verify that it supports MJPEG compression. You can do this using the v4l-utils package.

Run the following command in your terminal:

v4l2-ctl --list-formats-ext -d /dev/video0

Look through the output for an entry labeled ‘MJPG’ or ‘Motion-JPEG’. Note the supported resolutions (e.g., 1920x1080) and frame rates (e.g., 30 fps) available under the MJPEG format.

Step 2: The FFmpeg Command for Low-CPU Capture

To capture the MJPEG stream without taxing your CPU, you must tell FFmpeg to request the MJPEG format from the camera and use the stream copy codec (-c:v copy). This instructs FFmpeg to act as a demuxer and muxer only, bypassing the CPU-heavy decoding and encoding stages.

Use the following command structure:

ffmpeg -f v4l2 -input_format mjpeg -video_size 1920x1080 -framerate 30 -i /dev/video0 -c:v copy output.mkv

Command Breakdown:

Choosing the Right Container

While .mkv is highly recommended for storing raw MJPEG streams, you can also use .avi or .mp4.

If you use .mp4, some players may struggle to play the raw MJPEG stream inside an MP4 container. If compatibility is an issue and you must use a standard format like H.264, you will have to decode and re-encode, which will increase CPU usage:

ffmpeg -f v4l2 -input_format mjpeg -video_size 1920x1080 -framerate 30 -i /dev/video0 -c:v libx264 -preset ultrafast output.mp4

Note: Using -preset ultrafast keeps CPU usage as low as possible during H.264 encoding, though it will still use significantly more CPU than the -c:v copy method.