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:

  • -f v4l2: Forces FFmpeg to use the Video4Linux2 input device driver.
  • -input_format mjpeg: Forces the camera hardware to output the video in MJPEG format rather than raw YUV.
  • -video_size 1920x1080: Sets the capture resolution (replace with your desired supported resolution).
  • -framerate 30: Sets the capture frame rate (match this to your camera's supported MJPEG frame rates).
  • -i /dev/video0: Specifies the path to your input camera device.
  • -c:v copy: Copies the video stream directly to the output file without decoding or re-encoding it. This is the key setting that reduces CPU usage to almost 0%.
  • output.mkv: The output file. The Matroska (.mkv) container natively and reliably supports MJPEG video streams.

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.