QSV
37c3317fd058; modified for Encode Wiki · CC BY-SA 4.0Quick Sync Video (QSV) is the fixed-function media engine in Intel integrated graphics and Arc GPUs. FFmpeg exposes it as h264_qsv, hevc_qsv, vp9_qsv, av1_qsv, mpeg2_qsv and mjpeg_qsv. It is fast and sips power, which is why it is popular for home servers, Plex/Jellyfin transcoding, laptops and recording.
Hardware or software encoder?
Section titled “Hardware or software encoder?”QSV trades compression efficiency for speed and power like every hardware encoder: at the same bitrate it loses to x264, x265 and SVT-AV1 at slow presets. It is generally considered competitive with NVENC and ahead of AMF. Use it for transcodes where speed matters; use a software encoder when quality per bit does.
Which hardware supports what
Section titled “Which hardware supports what”| Codec | Support |
|---|---|
| H.264 | Every Quick Sync generation. 8-bit 4:2:0 only in FFmpeg (nv12). |
| HEVC | 8-bit from Skylake (6th gen), 10-bit from Kaby Lake (7th gen). The Linux media driver only exposes 10-bit encode from Ice Lake. |
| VP9 | Ice Lake onward, 8 and 10-bit, low-power mode only. Lunar Lake and Battlemage have no VP9 encoder. |
| AV1 | Arc (Alchemist, Battlemage) and Meteor Lake or newer integrated graphics, 8 and 10-bit. Tiger Lake, Alder Lake and Raptor Lake only decode AV1. |
Current FFmpeg builds QSV against libvpl (2.6 or newer); the older libmfx path is deprecated and has no av1_qsv. On Linux you also need intel-media-driver and a GPU runtime: vpl-gpu-rt for Tiger Lake and newer (including Arc), or the legacy Media SDK runtime for older iGPUs. On Windows the regular Intel graphics driver includes it.
Quality-oriented encode
Section titled “Quality-oriented encode”ffmpeg -i input.mkv -c:v hevc_qsv -preset slower -global_quality 24 -c:a copy output.mkv-global_quality without -maxrate selects ICQ (intelligent constant quality), QSV’s CRF-like mode. The range is 1–51 and lower is better, but the number is not comparable to x264/x265 CRF. For AV1:
ffmpeg -i input.mkv -c:v av1_qsv -preset slower -global_quality 30 -c:a copy output.mkvFor 10-bit HEVC or AV1 add -pix_fmt p010le. h264_qsv only takes nv12.
With neither -global_quality nor -b:v you get fixed-QP encoding (CQP at 26, or 128 for AV1) and a warning, which is rarely what you want.
H.264 can add -look_ahead 1 to -global_quality for LA_ICQ, which looks ahead for better bit distribution at the cost of latency.
Bitrate-targeted
Section titled “Bitrate-targeted”ffmpeg -i input.mkv -c:v hevc_qsv -preset slower -b:v 6M -maxrate 9M -bufsize 12M -c:a copy output.mkvFFmpeg picks the mode from the options: -b:v with -maxrate equal to it is CBR, otherwise VBR. Adding -global_quality to a VBR command turns it into QVBR, quality-targeted with the bitrate settings as limits. For better VBR on supported hardware add -extbrc 1 -look_ahead_depth 40.
Full-GPU pipeline
Section titled “Full-GPU pipeline”ffmpeg -hwaccel qsv -hwaccel_output_format qsv -i input.mkv -vf vpp_qsv=w=1920:h=1080 -c:v hevc_qsv -preset slower -global_quality 24 output.mkvFrames stay in GPU memory from decode to encode. vpp_qsv scales and converts formats on the GPU; any filter that is not a QSV filter needs hwdownload first. With more than one GPU on Linux, create the device explicitly, for example -init_hw_device vaapi=va:/dev/dri/renderD128 -init_hw_device qsv=hw@va -filter_hw_device hw.
Options that matter
Section titled “Options that matter”| Option | What it does |
|---|---|
-preset veryfast–veryslow | Speed/quality trade-off, veryslow is the best quality. |
-global_quality | Quality target for ICQ (1–51). Combined with -look_ahead 1 (H.264) it selects LA_ICQ. |
-b:v, -maxrate, -bufsize | Bitrate mode selection: CBR when -maxrate equals -b:v, VBR otherwise. |
-extbrc 1, -look_ahead_depth N | Extended bitrate control with lookahead (up to 100 frames) for CBR and VBR. Needs support from the runtime and codec. |
-bf, -b_strategy, -adaptive_b, -adaptive_i | B-frame count and adaptive B/I placement. -1 leaves it to the driver. |
-low_power | Selects the fixed-function (VDENC) encoder instead of the programmable one. Default auto. Some codecs and GPUs only have this path; it has a smaller feature set, so some options are rejected. |
-async_depth | Frames in flight. Lower it for latency, raise it for throughput. |
-qsv_params key=value:… | Passes options straight to the VPL runtime when FFmpeg has no named option. |
Pitfalls
Section titled “Pitfalls”- A listed encoder only means FFmpeg was built with it. Whether AV1, 10-bit or low-power works depends on the GPU and runtime;
vpl-inspect(from libvpl) lists what the runtime supports. - The runtime can end up in a different rate-control mode than the one you asked for.
-v verboseprints a “Using the … ratecontrol method” line with the mode FFmpeg requested. -bfand lookahead interact with latency settings; low-delay settings (-async_depth 1 -bf 0 -low_delay_brc 1) cost compression efficiency.
Full option reference
Section titled “Full option reference”Every private option of av1_qsv in FFmpeg 9.0.2; h264_qsv and hevc_qsv have more. -1 and auto leave the setting to the oneVPL runtime, and INT_MAX is 2147483647.
Private options
Section titled “Private options”| Parameter | Type | Default | Meaning | Range / named values |
|---|---|---|---|---|
-async_depth | int | 4 | Frames processed in parallel; higher improves throughput and adds latency. | 1 to INT_MAX |
-preset | int | 0 | Target usage from veryslow (1, best) to veryfast (7). 0 leaves it to the runtime. -compression_level overrides it. | 0 to 7; veryfast=7, faster=6, fast=5, medium=4, slow=3, slower=2, veryslow=1 |
-forced_idr | boolean | false | Make every I-frame a key frame, not only those flagged as keyframes. | 0 to 1 |
-low_power | boolean | auto | Use the fixed-function (VDEnc) encoder. auto leaves it to the runtime. | -1 to 1 |
-qsv_params | dictionary | not exposed | Pass oneVPL/MediaSDK parameters directly, as key=value:key=value. | — |
-b_strategy | int | -1 | 1 uses B-frames as references (pyramid); 0 keeps them non-reference. -1 = runtime default. | -1 to 1 |
-adaptive_i | int | -1 | Let the encoder insert I-frames at scene changes. -1 = runtime default. | -1 to 1 |
-adaptive_b | int | -1 | Let the encoder adapt B-frame placement. -1 = runtime default. | -1 to 1 |
-extbrc | int | -1 | Extended bitrate control, required for -look_ahead_depth with VBR/CBR. -1 = runtime default. | -1 to 1 |
-low_delay_brc | boolean | auto | Strictly obey the average frame size, for low-latency streaming. auto = runtime default. | -1 to 1 |
-max_frame_size | int | -1 | Largest encoded frame, in bytes; -1 = no limit. | -1 to INT_MAX |
-max_frame_size_i | int | -1 | Largest encoded I-frame, in bytes; -1 = no limit. | -1 to INT_MAX |
-max_frame_size_p | int | -1 | Largest encoded P-frame, in bytes; -1 = no limit. | -1 to INT_MAX |
-profile | int | unknown | AV1 profile; unknown lets the runtime choose. | 0 to INT_MAX; unknown=0, main=1 |
-tile_cols | int | 0 | Tile columns; 0 = runtime default. | 0 to 65535 |
-tile_rows | int | 0 | Tile rows; 0 = runtime default. | 0 to 65535 |
-look_ahead_depth | int | 0 | Lookahead frames for VBR/CBR when -extbrc 1 is set; 0 = off. | 0 to 100 |
Codec-specific generic initialization overrides
Section titled “Codec-specific generic initialization overrides”The wrapper replaces these generic FFmpeg defaults for this encoder. -b is in bits/s; -g and
-bf count frames. -1, and 0 for -b and -refs, leave the value to the preset, driver or
rate-control logic.
| Generic parameter | Default |
|---|---|
-b | 0 |
-g | -1 |
-bf | -1 |
-refs | 0 |