How to Force GOP Size in FFmpeg for Adaptive Streaming
Setting a fixed Group of Pictures (GOP) size in FFmpeg is crucial for adaptive bitrate streaming formats like HLS and DASH. This article explains how to force a specific GOP size and disable scene change detection using FFmpeg, ensuring that keyframes align perfectly across different video resolutions and bitrates for seamless quality switching.
Why Fixed GOP Size Matters for Adaptive Streaming
In adaptive streaming, a video is cut into small segments (usually 2 to 6 seconds long). Every segment must start with an IDR (Instantaneous Decoder Refresh) frame, which is a type of keyframe. If your different video renditions (e.g., 1080p, 720p, 360p) do not have keyframes at the exact same timestamps, the player will stutter or lag when switching between qualities.
To prevent this, you must force a fixed GOP size and disable the encoder’s default behavior of inserting extra keyframes at scene cuts.
How to Calculate GOP Size
GOP size is measured in frames, not seconds. To calculate your GOP size, multiply your video’s frame rate (FPS) by your desired keyframe interval in seconds.
- Formula:
Frame Rate (FPS) * Desired Interval (Seconds) = GOP Size - Example: For a 30 FPS video with a 2-second
keyframe interval:
30 * 2 = 60. You need a GOP size of 60.
FFmpeg Commands for Fixed GOP
To force a strict GOP size, you must set the minimum and maximum GOP size to the exact same value and disable scene change detection.
For H.264 (libx264)
Use the following FFmpeg arguments for the H.264 encoder:
ffmpeg -i input.mp4 -c:v libx264 -g 60 -keyint_min 60 -sc_threshold 0 output.mp4Parameter Breakdown: * -g 60: Sets the
maximum distance between keyframes to 60 frames. *
-keyint_min 60: Sets the minimum distance between keyframes
to 60 frames. Matching this with -g forces a constant
interval. * -sc_threshold 0: Disables scene change
detection. This prevents FFmpeg from inserting extra keyframes when a
visual scene change is detected.
For H.265 / HEVC (libx265)
If you are encoding in HEVC, the scene change threshold option is
handled differently through x265-params:
ffmpeg -i input.mp4 -c:v libx265 -g 60 -keyint_min 60 -x265-params no-scenecut=1 output.mp4Parameter Breakdown: *
-x265-params no-scenecut=1: Disables scene-cut detection in
the libx265 encoder to ensure keyframes are only placed at the interval
defined by -g.
Verifying the Keyframe Interval
After encoding, you can verify that your keyframes are strictly
placed at the specified interval using ffprobe:
ffprobe -select_streams v:0 -show_entries frame=pict_type,pts_time -of csv=p=0 input.mp4 | grep -n IThis command lists all frames, their types, and timestamps. You should see “I” (keyframes) appearing at exact, predictable intervals (e.g., 0.0, 2.0, 4.0, 6.0 seconds).