Hardware Accelerated Multi-Bitrate FFmpeg Encoding
This guide explains how to configure a multi-bitrate adaptive bitrate (ABR) encoding ladder for HTTP Live Streaming (HLS) and Dynamic Adaptive Streaming over HTTP (DASH) using FFmpeg with hardware acceleration. By leveraging hardware encoders such as NVIDIA NVENC or Intel Quick Sync Video (QSV), you can offload decoding, scaling, and encoding from the CPU to the GPU, enabling high-throughput generation of multiple video renditions in a single execution pipeline.
Prerequisites and Hardware Setup
To execute hardware-accelerated multi-bitrate encoding, FFmpeg must be compiled with the appropriate hardware acceleration libraries:
- NVIDIA: Requires
--enable-cuda-nvcc,--enable-libnpp, and--enable-nvencwith compatible NVIDIA drivers and CUDA toolkit installed. - Intel: Requires
--enable-libvpl(or--enable-libmfxon older versions) with the Intel oneVPL runtime installed.
Keyframe alignment across all renditions is mandatory for seamless
ABR switching. Set a fixed Group of Pictures (GOP) size using
-g and disable scene-cut detection.
NVIDIA NVENC: Multi-Bitrate HLS Pipeline
Using cuda hardware acceleration keeps video frames in
GPU VRAM across the decode, scale, and encode stages, avoiding costly
CPU-GPU memory transfers.
ffmpeg -hwaccel cuda -hwaccel_output_format cuda -i input.mp4 \
-filter_complex \
"[0:v]split=3[v1_in][v2_in][v3_in]; \
[v1_in]scale_cuda=1920:1080[v1_out]; \
[v2_in]scale_cuda=1280:720[v2_out]; \
[v3_in]scale_cuda=854:480[v3_out]" \
-map "[v1_out]" -c:v:0 h264_nvenc -b:v:0 5000k -maxrate:v:0 5350k -bufsize:v:0 7500k -g 48 -keyint_min 48 -sc_threshold 0 \
-map "[v2_out]" -c:v:1 h264_nvenc -b:v:1 2800k -maxrate:v:1 2996k -bufsize:v:1 4200k -g 48 -keyint_min 48 -sc_threshold 0 \
-map "[v3_out]" -c:v:2 h264_nvenc -b:v:2 1400k -maxrate:v:2 1498k -bufsize:v:2 2100k -g 48 -keyint_min 48 -sc_threshold 0 \
-map 0:a? -c:a:0 aac -b:a:0 192k \
-map 0:a? -c:a:1 aac -b:a:1 128k \
-map 0:a? -c:a:2 aac -b:a:2 96k \
-f hls \
-hls_time 2 \
-hls_playlist_type vod \
-hls_flags independent_segments \
-master_pl_name master.m3u8 \
-var_stream_map "v:0,a:0 v:1,a:1 v:2,a:2" \
hls_%v/stream.m3u8Command Breakdown:
-hwaccel cuda -hwaccel_output_format cuda: Decodes the input directly into CUDA memory.split=3: Duplicates the hardware frame surface into three branches within VRAM.scale_cuda: Performs hardware-based bicubic/bilinear scaling on the GPU.-g 48 -keyint_min 48 -sc_threshold 0: Enforces a deterministic keyframe interval (assuming 24 fps, this creates an IDR frame every 2 seconds).-var_stream_map: Maps video streams (v:n) and audio streams (a:n) to generate variants linked inmaster.m3u8.
Intel QSV: Multi-Bitrate DASH Pipeline
Intel Quick Sync Video achieves complete in-VRAM processing using the
qsv device driver and vpp_qsv (Video
Processing Project) filter for hardware scaling.
ffmpeg -init_hw_device qsv=hw -filter_hw_device hw \
-hwaccel qsv -hwaccel_output_format qsv -i input.mp4 \
-filter_complex \
"[0:v]split=3[v1_in][v2_in][v3_in]; \
[v1_in]vpp_qsv=w=1920:h=1080[v1_out]; \
[v2_in]vpp_qsv=w=1280:h=720[v2_out]; \
[v3_in]vpp_qsv=w=854:h=480[v3_out]" \
-map "[v1_out]" -c:v:0 h264_qsv -b:v:0 5000k -maxrate:v:0 5000k -bufsize:v:0 10000k -g 60 -sc_threshold 0 \
-map "[v2_out]" -c:v:1 h264_qsv -b:v:1 2800k -maxrate:v:1 2800k -bufsize:v:1 5600k -g 60 -sc_threshold 0 \
-map "[v3_out]" -c:v:2 h264_qsv -b:v:2 1400k -maxrate:v:2 1400k -bufsize:v:2 2800k -g 60 -sc_threshold 0 \
-map 0:a? -c:a aac -b:a 128k \
-f dash \
-seg_duration 2 \
-use_template 1 \
-use_timeline 1 \
-adaptation_sets "id=0,streams=v id=1,streams=a" \
manifest.mpdCommand Breakdown:
-init_hw_device qsv=hw -filter_hw_device hw: Initializes the QSV context for filter pipelines.vpp_qsv: Scales video surfaces directly on the Intel GPU execution units.-f dash: Configures the MPD (Media Presentation Description) multiplexer.-adaptation_sets "id=0,streams=v id=1,streams=a": Groups all video renditions under a single adaptive set and pairs them with the audio track.
Important Operational Considerations
- VRAM Constraints: Hardware-accelerated pipelines
decode and scale all renditions in parallel. Monitor GPU memory usage
via
nvidia-smiorintel_gpu_topto prevent out-of-memory errors when processing high-resolution 4K inputs. - Buffer Sizing: Always set
-bufsizeto between 1.5x and 2x the target-b:vto give the hardware rate controller sufficient elasticity for VBR (variable bitrate) while maintaining strict limits for network streaming clients. - Audio Mapping: For DASH packaging, a single
high-quality audio stream mapped once under an adaptation set avoids
redundant bandwidth usage across resolutions. For HLS, pairing dedicated
audio renditions via
-var_stream_mapensures broad compatibility across older Apple devices.