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 creationUtility 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:
Verify your GPU supports VAAPI:
lspci | grep -i vgaCheck driver installation:
vainfoEnsure your user is in the
videoandrendergroups: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 GPUsradeonsi- 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:
Check GPU utilization:
intel_gpu_top(Intel) orradeontop(AMD)Verify hardware encoding is being used: Look for GPU Video Engine usage in monitoring tools
Ensure no CPU-based fallback is occurring due to driver issues
See Also
H264VaapiEncoderComponent- API referenceX264EncoderFeedComponent- Software encoder referenceVideo Outputs - Video output feeds documentation