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-nvenc with compatible NVIDIA drivers and CUDA toolkit installed.
  • Intel: Requires --enable-libvpl (or --enable-libmfx on 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.m3u8

Command 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 in master.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.mpd

Command 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

  1. VRAM Constraints: Hardware-accelerated pipelines decode and scale all renditions in parallel. Monitor GPU memory usage via nvidia-smi or intel_gpu_top to prevent out-of-memory errors when processing high-resolution 4K inputs.
  2. Buffer Sizing: Always set -bufsize to between 1.5x and 2x the target -b:v to give the hardware rate controller sufficient elasticity for VBR (variable bitrate) while maintaining strict limits for network streaming clients.
  3. 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_map ensures broad compatibility across older Apple devices.