2.2.21.1. H.264 VAAPI Encoder

The Video Acceleration API (VAAPI) H.264 encoder provides hardware-accelerated video encoding on Intel and AMD GPUs. VAAPI is a Linux-specific API that provides access to hardware video encoding and decoding capabilities.

The VAAPI encoder is available through the H264VaapiEncoderComponent class and can be used as a drop-in replacement for the default software X.264 encoder in any video output feed.

Prerequisites and Installation

Hardware Requirements

The VAAPI encoder requires:

  • Intel GPU: Intel HD Graphics 4000 (Ivy Bridge) or newer, or Intel Arc graphics

  • AMD GPU: AMD Radeon GPUs with VCE (Video Coding Engine) support

  • Linux kernel: Version 4.4 or newer with appropriate GPU drivers

Software Requirements

Note that if you have followed the instrustions in the Environment section, you should already have the necessary dependencies installed. Otherwise, ensure you have the following software components installed:

GStreamer Packages

The VAAPI encoder requires the GStreamer VAAPI plugin:

sudo apt update
sudo apt install gstreamer1.0-vaapi

Intel GPU Drivers

For Intel GPUs, you need to install the Intel media driver and ensure the non-free components are available:

# Install Intel media driver
sudo apt install \
    intel-media-va-driver-non-free \
    vainfo

Note

The non-free driver is in Ubuntu’s multiverse repository, which is typically enabled by default. If the package is not found, enable multiverse with: sudo add-apt-repository multiverse && sudo apt update

AMD GPU Drivers

For AMD GPUs, install the Mesa drivers:

sudo apt install \
    mesa-va-drivers \
    vainfo

Verification

After installation, verify that VAAPI is properly configured:

# Check available VAAPI devices and supported profiles
vainfo

You should see output listing your GPU and the supported H.264 encoding profiles (e.g., VAProfileH264Main, VAProfileH264High).

# Verify GStreamer VAAPI elements are available
gst-inspect-1.0 vaapih264enc
gst-inspect-1.0 vaapipostproc

Usage

The VAAPI encoder can be used with different types of video feeds in the SDK. The configuration approach depends on whether you’re using a feed component (like UDP or WebRTC) or a utility feed (like file recording).

Note

Default Settings: The VAAPI encoder defaults are optimized for WebRTC real-time communication (CBR rate control, 2000 kbps bitrate, low latency). These match the X.264 software encoder for consistency. Customize the encoder properties as needed for your specific use case (e.g., higher bitrate and VBR for file recording).

Using with Feed Components (UDP, WebRTC, Peer Streaming)

For feed components like VideoOutputFeedUdp, VideoWebRtcEncodeFeedH264, and PeerLocalVideoFeed, you can configure the VAAPI encoder either through the encoder() method (for UDP and WebRTC) or by passing it as a parameter to the create() method (for peer streaming).

UDP Output Example:

    // Create a VAAPI hardware encoder for Intel/AMD GPUs
    PxMedia::H264VaapiEncoderComponent vaapiEncoder;
    vaapiEncoder.bitrate(5000_kbps);

    PxMedia::VideoOutputFeedUdp udpOutput;
    udpOutput.host("localhost");
    udpOutput.port(5006);
    udpOutput.encoder(vaapiEncoder);
    auto outgoingFeed =
        PxMedia::MediaServerOutgoingVideoFeed::create(mediaSession, props, inputVideo, udpOutput);

WebRTC Example:

    // Create a VAAPI hardware encoder
    PxMedia::H264VaapiEncoderComponent vaapiEncoder;
    vaapiEncoder.bitrate(5000_kbps);
    vaapiEncoder.keyframePeriod(60);

    PxMedia::VideoWebRtcEncodeFeedH264 webrtcFeed;
    webrtcFeed.encoder(vaapiEncoder);

Peer Streaming Example:

    // Create a VAAPI hardware encoder
    PxMedia::H264VaapiEncoderComponent vaapiEncoder;
    vaapiEncoder.bitrate(4000_kbps);
    vaapiEncoder.keyframePeriod(60);
    vaapiEncoder.tune(PxMedia::H264VaapiEncoderComponent::Tune::LOW_POWER);

    // Create peer feed with VAAPI encoder
    PxMedia::PeerLocalVideoFeed::FeedProperties feedProps;
    feedProps.channel = "video-channel";
    feedProps.label   = "Camera Feed";

    PxMedia::VideoInputFeedV4Linux2 videoInput;
    videoInput.deviceProperties().device("/dev/video0");

    auto feedResult =
        PxMedia::PeerLocalVideoFeed::create(peerSession, feedProps, videoInput, &vaapiEncoder);

Using with File Recording

For file recording with AVOutputFeedFile, pass the encoder as a parameter to the create() factory method:

    // Set up video input
    PxMedia::VideoInputFeedV4Linux2 videoInput;

    // Create VAAPI encoder with desired settings
    PxMedia::H264VaapiEncoderComponent vaapiEncoder;
    vaapiEncoder.bitrate(8000_kbps);
    vaapiEncoder.keyframePeriod(60);
    vaapiEncoder.rateControl(PxMedia::H264VaapiEncoderComponent::RateControlMode::CBR);

    // Set up file output settings
    PxMedia::AVOutputFeedFile::FeedProperties           feedProps{"my-recording"};
    PxMedia::AVOutputFeedFile::AVOutputFeedFileSettings settings;
    if (auto err = settings.destinationDirectory("/path/to/recordings")) {
        // Handle error...
    }
    if (auto err = settings.destinationFilenamePattern("video-%05d.mp4")) {
        // Handle error...
    }

    // Create the feed with the VAAPI encoder
    auto feedResult =
        PxMedia::AVOutputFeedFile::create(context, feedProps, settings, videoInput, vaapiEncoder);

Note

The API patterns differ based on feed type:

  • Feed components (UDP, WebRTC) use a setter method encoder() to configure the encoder after feed creation

  • Utility feeds (file recording) and peer feeds pass the encoder as a parameter to the create() factory method

All patterns fully support hardware encoders.

Multi-GPU Systems

On systems with multiple GPUs, you can control which GPU is used for VAAPI encoding through environment variables. This is particularly useful in systems with both integrated and discrete GPUs.

Selecting the VAAPI Device

VAAPI uses the /dev/dri/renderD* devices for hardware acceleration. By default, it will use /dev/dri/renderD128. To specify a different device:

# Specify device path directly
export GST_VAAPI_DRM_DEVICE=/dev/dri/renderD129

# Run your application
./your_application

The VAAPI driver will be automatically detected based on the GPU. In rare cases where auto-detection fails, you can explicitly set the driver:

export LIBVA_DRIVER_NAME=iHD      # For newer Intel GPUs (Broadwell+)
export LIBVA_DRIVER_NAME=i965     # For older Intel GPUs
export LIBVA_DRIVER_NAME=radeonsi # For AMD GPUs

Listing Available GPUs

To see all available GPUs and their render devices:

# List all DRI devices
ls -la /dev/dri/

# Show detailed information about each GPU
for device in /dev/dri/renderD*; do
    echo "Device: $device"
    LIBVA_DRIVER_NAME=iHD vainfo --display drm --device $device 2>/dev/null | grep -E "Driver version|VAProfile"
    echo "---"
done

Specifying GPU in Code

While environment variables are the recommended approach, you can also specify the device programmatically through GStreamer properties if needed. However, this requires custom GStreamer pipeline configuration and is beyond the scope of typical SDK usage.

Example Multi-GPU Configuration

For a system with both Intel integrated graphics (iGPU) and a discrete GPU:

# Use Intel iGPU (typically renderD128)
export GST_VAAPI_DRM_DEVICE=/dev/dri/renderD128

# Or use second GPU (typically renderD129)
export GST_VAAPI_DRM_DEVICE=/dev/dri/renderD129

Tip

Intel integrated GPUs often provide the best performance-per-watt for video encoding. If you have a discrete GPU for graphics-intensive tasks, consider dedicating the integrated GPU for video encoding to avoid resource contention.

Performance Benefits

The VAAPI encoder provides significant performance improvements over the software X.264 encoder, particularly for CPU usage. The following benchmarks were conducted on an Intel GPU system in recording mode with 300-second test duration per encoder.

Important: Performance varies significantly based on source video format. Cameras that provide raw/uncompressed formats (I420, NV12, YUY2) achieve much better results than JPEG/MJPEG cameras.

Note

Performance Variability: The benchmark results shown below were obtained on a specific Intel GPU system. Actual performance may vary based on:

  • CPU and GPU models and generations

  • Video content characteristics (motion complexity, scene changes, lighting conditions)

  • System load and thermal conditions

  • Driver versions and system configuration

Use these benchmarks as a general guide. We recommend conducting your own performance testing with your specific hardware and video content to determine real-world gains.

Performance by Resolution and Source Format

720p (1280x720) at 2 Mbps

With JPEG Source Format:

Encoder

Avg CPU

Max CPU

Avg GPU

Max GPU

X.264 (software)

4.17%

4.90%

0.00%

0.00%

VAAPI (hardware)

1.60%

2.41%

1.95%

6.39%

CPU Reduction: 61.6% (4.17% → 1.60%)

With RAW Source Format:

Encoder

Avg CPU

Max CPU

Avg GPU

Max GPU

X.264 (software)

3.21%

3.97%

0.00%

0.00%

VAAPI (hardware)

0.33%

0.45%

2.08%

6.73%

CPU Reduction: 89.7% (3.21% → 0.33%)

1080p (1920x1080) at 5 Mbps

With JPEG Source Format:

Encoder

Avg CPU

Max CPU

Avg GPU

Max GPU

X.264 (software)

9.42%

10.76%

0.00%

0.00%

VAAPI (hardware)

3.74%

4.11%

6.73%

11.51%

CPU Reduction: 60.3% (9.42% → 3.74%)

With RAW Source Format:

Encoder

Avg CPU

Max CPU

Avg GPU

Max GPU

X.264 (software)

8.35%

8.44%

0.00%

0.00%

VAAPI (hardware)

1.10%

1.21%

6.66%

11.38%

CPU Reduction: 86.8% (8.35% → 1.10%)

4K (3840x2160) at 10 Mbps

With JPEG Source Format:

Encoder

Avg CPU

Max CPU

Avg GPU

Max GPU

X.264 (software)

10.73%

11.75%

0.00%

0.00%

VAAPI (hardware)

3.54%

3.94%

14.79%

20.06%

CPU Reduction: 67.0% (10.73% → 3.54%)

Camera Source Format Recommendations

Camera Compatibility Note: Raw/uncompressed formats require camera hardware support and sufficient USB bandwidth. Most professional cameras and many consumer webcams support raw formats like I420 or YUY2. You can check your camera’s supported formats using:

v4l2-ctl --device=/dev/video0 --list-formats-ext

When configuring your video input feed, prefer raw formats when available for optimal VAAPI performance. The performance difference is substantial:

  • JPEG/MJPEG sources: 60-67% CPU reduction

  • RAW sources: 87-90% CPU reduction

Key Observations

  • Source Format Matters: Raw/uncompressed video sources provide the best performance with VAAPI, achieving 87-90% CPU reduction. When using JPEG/MJPEG sources, CPU usage is higher due to decode overhead, but VAAPI still provides substantial benefits (60-67% reduction depending on resolution).

  • Dedicated GPU Utilization: The VAAPI encoder uses the GPU’s dedicated video encoding engine, which operates independently of the main GPU processing units. This allows video encoding to proceed without impacting graphics rendering or compute workloads.

  • Consistent Performance: Maximum CPU usage with VAAPI remains low and predictable across all resolutions, making it easier to design systems with deterministic resource allocation.

  • Multi-Stream Benefits: When encoding multiple video streams simultaneously, the CPU savings multiply, making VAAPI essential for applications handling multiple concurrent video sessions.

Troubleshooting

Common Issues

“No VAAPI device found”

This typically indicates missing drivers or incorrect permissions. Try:

  1. Verify your GPU supports VAAPI: lspci | grep -i vga

  2. Check driver installation: vainfo

  3. Ensure your user is in the video and render groups:

    sudo usermod -a -G video $USER
    sudo usermod -a -G render $USER
    # Log out and back in for group changes to take effect
    

“No such element or plugin ‘vaapih264enc’”

If gst-inspect-1.0 vaapih264enc returns this error, first ensure you have completed the installation steps in the GStreamer Packages section above, particularly installing the gstreamer1.0-vaapi package.

If the package is installed but the element is still not found, especially on older Ubuntu versions like 22.04, you may need to explicitly set the VAAPI driver. The correct driver depends on your GPU type. See the Multi-GPU Systems section above for detailed driver selection guidance.

Common driver options:

  • iHD - Modern Intel GPUs (Broadwell and newer)

  • i965 - Older Intel GPUs

  • radeonsi - AMD GPUs

To test if setting the driver resolves the issue:

export LIBVA_DRIVER_NAME=iHD  # Use appropriate driver for your GPU
gst-inspect-1.0 vaapih264enc

Once you’ve verified the element is available with the correct driver, set it before running your application:

export LIBVA_DRIVER_NAME=iHD  # Use appropriate driver for your GPU
./your_application

For a permanent solution, manually add the following line to your shell profile (~/.bashrc, ~/.zshrc, or ~/.profile):

export LIBVA_DRIVER_NAME=iHD  # Use appropriate driver for your GPU

Note

This is typically needed on Ubuntu 22.04 and older versions where the default driver selection may not work correctly. Newer Ubuntu versions usually auto-detect the correct driver.

“vaapipostproc element not found”

This usually means the non-free Intel drivers are not installed. Ensure you’ve enabled the non-free repositories and installed intel-media-va-driver-non-free as described in the installation section.

“XDG_RUNTIME_DIR not set in the environment”

This error message may appear when using VAAPI in Docker containers or minimal environments. It occurs because VAAPI’s display connection libraries expect the XDG_RUNTIME_DIR environment variable to be set for runtime files and IPC mechanisms.

This error does not affect encoding performance or functionality - VAAPI will still use hardware encoding successfully. However, to eliminate the error message, set the environment variable before running your application:

export XDG_RUNTIME_DIR=/tmp/runtime-root
mkdir -p $XDG_RUNTIME_DIR
chmod 700 $XDG_RUNTIME_DIR

For Docker containers, add the environment variable to your container configuration:

docker run -e XDG_RUNTIME_DIR=/tmp/runtime-root ...

Performance is worse than X.264

If VAAPI performance is unexpectedly poor:

  1. Check GPU utilization: intel_gpu_top (Intel) or radeontop (AMD)

  2. Verify hardware encoding is being used: Look for GPU Video Engine usage in monitoring tools

  3. Ensure no CPU-based fallback is occurring due to driver issues

See Also