# QSV

Canonical URL: https://encode.wiki/tools/hardware-encoders/qsv/
Content version: ca42e61ede0a24f789d7287a0001244ad22f4abf
Status: current
License: CC BY-SA 4.0
Checksum (SHA-256): 8f16191a2b4309262cdbfc033ebcbdc7bf26f1233bcf6e3c084fcb4457413625

Quick 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?

QSV trades compression efficiency for speed and power like every hardware encoder: at the same bitrate it loses to [x264](/tools/software-encoders/x264/), [x265](/tools/software-encoders/x265/) and [SVT-AV1](/tools/software-encoders/svt-av1/) at slow presets. It is generally considered competitive with [NVENC](/tools/hardware-encoders/nvenc/#hardware-or-software-encoder) and ahead of [AMF](/tools/hardware-encoders/amf/). Use it for transcodes where speed matters; use a software encoder when quality per bit does.

## 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

```sh
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:

```sh
ffmpeg -i input.mkv -c:v av1_qsv -preset slower -global_quality 30 -c:a copy output.mkv
```

For 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

```sh
ffmpeg -i input.mkv -c:v hevc_qsv -preset slower -b:v 6M -maxrate 9M -bufsize 12M -c:a copy output.mkv
```

FFmpeg 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

```sh
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.mkv
```

Frames 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

| 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

- 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 verbose` prints a "Using the … ratecontrol method" line with the mode FFmpeg requested.
- `-bf` and lookahead interact with latency settings; low-delay settings (`-async_depth 1 -bf 0 -low_delay_brc 1`) cost compression efficiency.

## 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.

{/* ffmpeg-parameters:start */}

### 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

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` |

{/* ffmpeg-parameters:end */}
