How to Transcode Video to H.264 Using AMD Radeon Hardware Acceleration Using FFmpeg

These commands transcode a video to H.264 using AMD Radeon VAAPI hardware acceleration. They were tested with a Radeon RX 7800 XT. Most modern Radeon cards support H.264 hardware encoding; unlike AV1, this is not limited to RDNA3.

Speed-optimized command

Use this when you want fast H.264 encoding with a good balance of quality and speed:

transcode_h264_speed.sh
LIBVA_DRIVER_NAME=radeonsi ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -hwaccel_output_format vaapi -i input.mp4 -c:v h264_vaapi -rc_mode CQP -global_quality:v 24 -c:a copy output-h264.mp4

Replace input.mp4 and output-h264.mp4 with your file names. The default render device is /dev/dri/renderD128; if you are not sure which device belongs to your Radeon card, see How to Identify Which /dev/dri/renderD Device Is Your AMD Radeon GPU.

What the flags do

  • LIBVA_DRIVER_NAME=radeonsi forces the Radeon VAAPI driver. You may not need this on every distribution, but it helps when multiple GPU drivers are installed.
  • -hwaccel vaapi enables hardware-accelerated decoding.
  • -hwaccel_device /dev/dri/renderD128 points FFmpeg at the default DRM render node.
  • -hwaccel_output_format vaapi keeps the decoded frames in video memory so the encoder can read them directly.
  • -c:v h264_vaapi selects the H.264 VAAPI encoder.
  • -rc_mode CQP uses constant-quantizer (CQP) rate control.
  • -global_quality:v 24 sets the encoder quality. Lower is higher quality and larger file; higher is smaller and lower quality.
  • -c:a copy copies the audio stream without re-encoding.

Wrapper script

Save this as transcode-h264-radeon.sh and run it with the input file; it will automatically write <basename>-h264.mp4 next to the input:

transcode-h264-radeon.sh
#!/bin/bash
set -euo pipefail

RENDER_DEVICE="${RENDER_DEVICE:-/dev/dri/renderD128}"

if [ $# -ne 1 ]; then
    echo "Usage: $0 <input video>" >&2
    exit 1
fi

input="$1"
base="${input%.*}"
output="${base}-h264.mp4"

LIBVA_DRIVER_NAME=radeonsi ffmpeg \
  -hwaccel vaapi -hwaccel_device "$RENDER_DEVICE" -hwaccel_output_format vaapi \
  -i "$input" \
  -c:v h264_vaapi -rc_mode CQP -global_quality:v 24 \
  -c:a copy \
  "$output"

Example:

example_usage_h264.sh
chmod +x transcode-h264-radeon.sh
./transcode-h264-radeon.sh input.mp4
# Produces input-h264.mp4

Use a different render node by exporting it:

example_render_device_h264.sh
RENDER_DEVICE=/dev/dri/renderD129 ./transcode-h264-radeon.sh input.mp4

Quality / bitrate guidance

For h264_vaapi the global_quality value is roughly equivalent to the H.264 CRF scale (0–51). These are approximate mappings; always test with your own source:

Target qualityCPU CRF (0–51)h264_vaapi global_quality (0–51)Typical 720pTypical 1080pTypical 4KTypical 8K
High quality / near-transparent1818~4 – 6 Mbps~8 – 12 Mbps~40 – 60 Mbps~120 – 180 Mbps
Standard quality (recommended)2323~2 – 4 Mbps~4 – 8 Mbps~20 – 30 Mbps~60 – 90 Mbps
Moderate compression2828~1.5 – 3 Mbps~3 – 5 Mbps~12 – 20 Mbps~35 – 60 Mbps
Below standard quality3535~0.8 – 1.5 Mbps~1.5 – 3 Mbps~6 – 12 Mbps~18 – 35 Mbps
High compression / archival low4040~0.4 – 0.8 Mbps~0.8 – 1.5 Mbps~3 – 6 Mbps~9 – 18 Mbps

The command above uses 24 as the default starting point, which is the standard-quality (recommended) setting from the table. Tune it to your eyes and delivery requirements.

Confirming H.264 hardware encoding is available

Check the relevant part of vainfo:

vainfo_h264_output.txt
      VAProfileH264ConstrainedBaseline:	VAEntrypointVLD
      VAProfileH264ConstrainedBaseline:	VAEntrypointEncSlice
      VAProfileH264Main               :	VAEntrypointVLD
      VAProfileH264Main               :	VAEntrypointEncSlice
      VAProfileH264High               :	VAEntrypointVLD
      VAProfileH264High               :	VAEntrypointEncSlice

On this machine vainfo reports the AMD driver as:

vainfo_h264_driver.txt
vainfo: Driver version: Mesa Gallium driver 26.0.8-1ubuntu0.3 for AMD Radeon RX 7800 XT (radeonsi, navi32, ACO, DRM 3.64, 7.0.0-31-generic)

Verification on this computer

Running the command against a short 1920×1080 test clip produced the following encoding summary:

transcode_h264_output.txt
Output #0, mp4, to 'testsrc_h264.mp4':
  Stream #0:0: Video: h264 (High) (avc1 / 0x31637661), vaapi(tv, progressive), 1920x1080, q=2-31, 30 fps
  Stream #0:1: Audio: aac (LC), 44100 Hz, mono, fltp, 69 kb/s
[out#0/mp4] video:151KiB audio:43KiB ... bitrate= 330.4kbits/s speed=8.98x

ffprobe on the output confirmed codec_name=h264 and profile=High, with the video correctly produced by h264_vaapi.

On this particular PC the Radeon card is actually /dev/dri/renderD129 because /dev/dri/renderD128 belongs to the integrated Intel GPU. Always use the device that vainfo reports as your Radeon card.

Using an Intel GPU instead

The same h264_vaapi codec works on Intel VAAPI with the iHD driver. Replace the environment variable and pick the correct render node:

transcode_h264_intel.sh
LIBVA_DRIVER_NAME=iHD ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -hwaccel_output_format vaapi -i input.mp4 -c:v h264_vaapi -rc_mode CQP -global_quality:v 24 -c:a copy output-h264.mp4

Use the render-node identification post to find the right device for your hardware.


Check out similar posts by category: Video Linux