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/video0Look 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.mkvCommand 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.mp4Note: 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.