Configure H.264 Slices in FFmpeg for Parallel Decoding
This article explains how to configure the slice count and slice size in H.264 encoding using FFmpeg to improve parallel decoding performance. By dividing video frames into multiple independent regions called slices, decoders can leverage multi-core CPUs to process a single frame simultaneously. You will learn the specific FFmpeg commands needed to control slice distribution, their parameters, and the trade-offs associated with slice-based encoding.
Understanding H.264 Slices and Parallel Decoding
By default, an H.264 video frame is encoded as a single continuous block of data. To decode this frame, a player must process the data sequentially, which limits decoding to a single CPU thread per frame.
Slices break a single video frame into independent spatial regions. Because these slices do not rely on data from neighboring slices within the same frame, a multi-threaded decoder can decode different slices of the same frame at the same time. This significantly reduces decoding latency, making it highly beneficial for real-time streaming, high-resolution playback (such as 4K or 8K), and low-latency virtual reality applications.
How to Configure Slice Count in FFmpeg
To force the encoder to divide every frame into a specific number of
slices, use the -slices option in your FFmpeg command. This
is supported by the standard H.264 encoder (libx264).
ffmpeg -i input.mp4 -c:v libx264 -slices 4 -cref 23 output.mp4In this command: * -slices 4: Splits each video frame
into 4 equal-sized slices. A multi-threaded decoder can now use up to 4
threads to decode a single frame in parallel.
For optimal parallel decoding, set the slice count to match the number of CPU cores or threads available on your target decoding hardware (commonly 4, 8, or 16).
How to Configure Slice Size in FFmpeg
Instead of setting a fixed number of slices, you can define slices based on physical size limits. This is useful for streaming protocols (like RTP) where slices must fit within specific network packet sizes (MTU limits) to prevent packet fragmentation.
You can configure slice size using two different metrics:
1. Limit by Maximum
Bytes (-slice-max-size)
This option limits the maximum size of each slice in bytes. If a slice exceeds this limit during encoding, it is split into a new slice.
ffmpeg -i input.mp4 -c:v libx264 -slice-max-size 1200 output.mp4-slice-max-size 1200: Limits each slice to a maximum of 1200 bytes, which is a common setting for ensuring IP packets fit within standard 1500-byte MTU limits.
2. Limit by Macroblocks
(-slice-max-mbs)
This option limits the maximum number of macroblocks (16x16 pixel blocks) allowed in a single slice.
ffmpeg -i input.mp4 -c:v libx264 -slice-max-mbs 1500 output.mp4-slice-max-mbs 1500: Ensures that no slice contains more than 1500 macroblocks, providing consistent computational complexity per slice for the decoder.
Important Trade-offs of Using Slices
While configuring slices improves parallel decoding speed, it introduces certain trade-offs:
- Decreased Compression Efficiency: Slices prevent the encoder from utilizing intra-prediction (predicting pixels using neighboring pixels) across slice boundaries. As a result, files with high slice counts will require a higher bitrate to maintain the same visual quality as single-slice files.
- Overhead: Each slice adds a small amount of header data to the bitstream, slightly increasing the overall file size.