# NVENC

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

NVENC is the dedicated encoder block on NVIDIA GPUs. It is separate from the CUDA cores and from the NVDEC decoder, so encoding barely loads the rest of the GPU or the CPU. People use it for game capture, streaming (OBS), screen recording and fast transcodes. FFmpeg exposes it as `h264_nvenc`, `hevc_nvenc` and `av1_nvenc`; there is no VP9 encoder.

## Hardware or software encoder?

A fixed-function encoder buys speed and low power draw by giving up compression efficiency. At the same bitrate, NVENC output is worse than x264, x265 or SVT-AV1 at slow presets, and it needs noticeably more bitrate to match their quality. Newer generations have narrowed the gap without closing it.

Use NVENC when speed matters more than size: live streaming, recording, previews, a big batch you need done today. For archival encodes or anything where quality per bit is the point, use [x264](/tools/software-encoders/x264/), [x265](/tools/software-encoders/x265/) or [SVT-AV1](/tools/software-encoders/svt-av1/). The other [hardware encoders](/tools/hardware-encoders/qsv/) on this wiki have the same trade-off.

## Which GPU supports what

| Codec | FFmpeg encoder | Notes |
| --- | --- | --- |
| H.264 | `h264_nvenc` | Every NVENC generation. 4:2:0 and 4:4:4. |
| HEVC | `hevc_nvenc` | Maxwell 2nd gen (GTX 950/960) onward; 10-bit from Pascal (GTX 10 series). B-frames need the 7th-gen NVENC in Turing (RTX 20, GTX 1660) and newer. |
| AV1 | `av1_nvenc` | Ada Lovelace (RTX 40 series) and newer. 4:2:0, 8 and 10-bit. |

Blackwell (RTX 50 series) adds 4:2:2 for H.264 and HEVC, and 10-bit H.264. The GTX 1630 and most GTX 1650 variants carry the older 6th-gen block: HEVC 10-bit, but no HEVC B-frames. NVIDIA's [support matrix](https://developer.nvidia.com/video-encode-and-decode-gpu-support-matrix-new) lists every card.

FFmpeg has to be built with nv-codec-headers, and the driver must be new enough for the header version. Otherwise you get "Driver does not support the required nvenc API version". Update the driver, or use a build with older headers.

## Quality-oriented encode

```sh
ffmpeg -i input.mkv -c:v hevc_nvenc -preset p7 -tune hq -rc vbr -cq 24 -c:a copy output.mkv
```

`-rc vbr -cq N` is NVENC's constant-quality mode: it holds quality and lets the bitrate float. Setting `-cq` makes the wrapper drop its default 2 Mbit/s average target, so the old `-b:v 0` habit is harmless but no longer needed; add `-maxrate` if you want a ceiling. Without `-cq` or `-b:v`, NVENC encodes VBR at that 2 Mbit/s default, which is the usual cause of unexpectedly blocky output. `-preset p7` is the slowest, best-quality preset; on a modern card it is still far faster than real time at 1080p. `-tune hq` is the offline-quality tuning (it is also the default).

`-cq` goes 1–51 for H.264 and HEVC and 1–63 for AV1, lower is better; the default 0 leaves CQ off. These numbers are not comparable to x264/x265 CRF or SVT-AV1 CRF. Pick a value by encoding a short clip and looking at it. AV1 needs higher numbers than HEVC for similar quality:

```sh
ffmpeg -i input.mkv -c:v av1_nvenc -preset p7 -tune hq -rc vbr -cq 30 -c:a copy output.mkv
```

For 10-bit output add `-pix_fmt p010le`. `-highbitdepth 1` encodes an 8-bit source as 10-bit, which helps against banding (HEVC and AV1; H.264 only on Blackwell).

### Streaming and recording

```sh
ffmpeg -i input -c:v h264_nvenc -preset p4 -tune ll -rc cbr -b:v 6M -g 120 -bf 0 -c:a aac -b:a 160k output.mp4
```

`-tune ll` selects the low-latency preset set, `-bf 0` keeps B-frames out, `-rc cbr` gives the steady rate streaming ingest expects, and `-g 120` is a two-second keyframe interval at 60 fps. Use `-tune ull` only when latency matters more than anything else.

## Full-GPU pipeline

Decoding and scaling on the GPU avoids copying frames back to system memory:

```sh
ffmpeg -hwaccel cuda -hwaccel_output_format cuda -i input.mkv -vf scale_cuda=1920:1080 -c:v hevc_nvenc -preset p7 -tune hq -rc vbr -cq 24 output.mkv
```

This only works while every filter has a CUDA version. For anything else (crop, denoise, subtitles, most colour filters) decode in software or add `hwdownload,format=nv12` and take the copy. For a single encode the copy is rarely the bottleneck.

## Options that matter

| Option | What it does |
| --- | --- |
| `-preset p1`–`p7` | Speed/quality ladder. p1 is fastest, p7 slowest and best. The older `slow`/`medium`/`fast` names are legacy presets; use p1–p7. |
| `-tune` | `hq` for offline, `ll` and `ull` for low latency, `lossless`. `uhq` (HEVC and AV1 only) is slower than `hq` and somewhat better; it needs a recent driver. |
| `-rc` | `vbr` (with `-cq` for constant quality), `cbr`, `constqp` (with `-qp`). |
| `-rc-lookahead N` | Looks N frames ahead for better bit distribution and scene-change handling. Adds latency and memory use. p6 and p7 may already enable lookahead from the preset. |
| `-bf N`, `-b_ref_mode middle` | B-frames and using them as references. HEVC B-frames need Turing or newer. |
| `-spatial-aq 1`, `-temporal-aq 1` | Adaptive quantization. Spatial AQ (`-aq-strength` 1–15, default 8) moves bits toward flat areas where blocking and banding show. Temporal AQ shifts bits toward static areas that later frames reference. |
| `-multipass fullres` | Two-pass analysis inside the encoder (not FFmpeg's `-pass 1`/`-pass 2`). Slower, steadier bit allocation. |
| `-gpu N` | Choose the GPU. `-gpu list` prints the devices. |

## Pitfalls

- `-global_quality` is rejected. Use `-cq` (with `-rc vbr`) or `-qp`.
- Presets and CQ values from other encoders do not transfer. `-cq 24` is not CRF 24.
- GeForce cards are limited to a fixed number of simultaneous encode sessions (12 on current drivers); professional cards are unrestricted.
- Features differ by GPU generation and codec. If you ask for one the card lacks (B-frames on HEVC before Turing, temporal AQ, lookahead, 10-bit), FFmpeg stops with "… not supported" rather than silently ignoring it.
- For HDR, use a 10-bit pixel format and keep the colour tags and metadata through the whole chain. A 10-bit pixel format alone does not make the file HDR.

## Full option reference

Every private option of `av1_nvenc` in FFmpeg 9.0.2; `h264_nvenc` and `hevc_nvenc` share most of them. `-1` leaves the setting to the preset and driver, and `INT_MAX` is 2147483647. `-cq` and `-qp` use the codec's quantizer scale (0–255 for AV1, 0–51 for H.264/HEVC).

{/* ffmpeg-parameters:start */}

### Private options

| Parameter | Type | Default | Meaning | Range / named values |
| --- | --- | --- | --- | --- |
| `-preset` | `int` | `p4` | Speed/quality preset from `p1` (fastest) to `p7` (slowest, best). `slow`, `medium` and `fast` are legacy aliases for `p7` with two-pass, `p4` and `p1`. | `0` to `9`; `slow`=`0`, `medium`=`1`, `fast`=`2`, `p1`=`3`, `p2`=`4`, `p3`=`5`, `p4`=`6`, `p5`=`7`, `p6`=`8`, `p7`=`9` |
| `-tune` | `int` | `hq` | `hq` for normal encodes; `uhq` is slower and better on recent GPUs/drivers; `ll`/`ull` for low latency; `lossless`. | `1` to `5`; `hq`=`1`, `uhq`=`5`, `ll`=`2`, `ull`=`3`, `lossless`=`4` |
| `-level` | `int` | `auto` | AV1 level limit; `auto` lets the driver choose. | `0` to `24`; `auto`=`24`, `2`=`0`, `2.0`=`0`, `2.1`=`1`, `2.2`=`2`, `2.3`=`3`, `3`=`4`, `3.0`=`4`, `3.1`=`5`, `3.2`=`6`, `3.3`=`7`, `4`=`8`, `4.0`=`8`, `4.1`=`9`, `4.2`=`10`, `4.3`=`11`, `5`=`12`, `5.0`=`12`, `5.1`=`13`, `5.2`=`14`, `5.3`=`15`, `6`=`16`, `6.0`=`16`, `6.1`=`17`, `6.2`=`18`, `6.3`=`19`, `7`=`20`, `7.0`=`20`, `7.1`=`21`, `7.2`=`22`, `7.3`=`23` |
| `-tier` | `int` | `0` | AV1 tier: 0 Main, 1 High. | `0` to `1`; `0`=`0`, `1`=`1` |
| `-rc` | `int` | `-1` | Rate control: `constqp`, `vbr` or `cbr`. -1 picks `constqp` when `-qp` is set, otherwise `vbr`. | `-1` to `INT_MAX`; `constqp`=`0`, `vbr`=`1`, `cbr`=`2` |
| `-multipass` | `int` | `disabled` | Extra analysis pass within one run: `qres` (quarter resolution, cheaper) or `fullres`. The legacy `slow` preset forces `fullres`. | `0` to `2`; `disabled`=`0`, `qres`=`1`, `fullres`=`2` |
| `-highbitdepth` | `boolean` | `false` | Encode 10-bit from 8-bit input; reduces banding at little cost. | `0` to `1` |
| `-tile-rows` | `int` | `-1` | Tile rows; -1 lets the driver choose. | `-1` to `64` |
| `-tile-columns` | `int` | `-1` | Tile columns; -1 lets the driver choose. | `-1` to `64` |
| `-surfaces` | `int` | `0` | Input frame buffers; 0 sizes them from B-frames and lookahead. | `0` to `64` |
| `-gpu` | `int` | `any` | GPU index (0 = first). `list` prints the available GPUs; `any` uses the default device. | `-2` to `INT_MAX`; `any`=`-1`, `list`=`-2` |
| `-rgb_mode` | `int` | `yuv420` | Packed RGB input is converted to `yuv420` or `yuv444`; `disabled` rejects RGB input. | `0` to `INT_MAX`; `yuv420`=`1`, `yuv444`=`2`, `disabled`=`0` |
| `-delay` | `int` | `INT_MAX` | Frames of output delay (async depth); INT_MAX means automatic (surfaces − 1). Too small a value disables lookahead. | `0` to `INT_MAX` |
| `-rc-lookahead` | `int` | `0` | Lookahead frames for rate control and adaptive I/B placement; 0 = off. Clipped to what `-surfaces`/`-delay` allow. | `0` to `INT_MAX` |
| `-cq` | `float` | `0` | Quality target for VBR (lower = better). 0 = automatic. Pair with `-b:v 0` so the 2 Mbit/s default bitrate does not cap it. | `0` to `63` |
| `-init_qpP` | `int` | `-1` | Starting QP for P-frames in VBR/CBR; -1 derives it from `-qmin`/`-qmax`. | `-1` to `255` |
| `-init_qpB` | `int` | `-1` | Starting QP for B-frames in VBR/CBR; -1 derives it. | `-1` to `255` |
| `-init_qpI` | `int` | `-1` | Starting QP for I-frames in VBR/CBR; -1 derives it. | `-1` to `255` |
| `-qp` | `int` | `-1` | Constant QP for all frames (selects `constqp`). AV1 scale 0–255. | `-1` to `255` |
| `-qp_cb_offset` | `int` | `0` | QP offset for Cb (blue-difference chroma). | `-12` to `12` |
| `-qp_cr_offset` | `int` | `0` | QP offset for Cr. The AV1 driver ignores it and applies the Cb offset to both. | `-12` to `12` |
| `-qmin` | `int` | `-1` | Lowest QP rate control may use; -1 = no limit. | `-1` to `255` |
| `-qmax` | `int` | `-1` | Highest QP rate control may use; -1 = no limit. | `-1` to `255` |
| `-no-scenecut` | `boolean` | `false` | With lookahead on, stop inserting I-frames at scene cuts. | `0` to `1` |
| `-forced-idr` | `boolean` | `false` | Make keyframes requested with `-force_key_frames` full key frames instead of intra-only frames. | `0` to `1` |
| `-b_adapt` | `boolean` | `true` | With lookahead on, adapt the B-frame count to the content; 0 keeps a fixed pattern. | `0` to `1` |
| `-spatial-aq` | `boolean` | `false` | Spatial adaptive quantization: moves bits into flat areas where blocking shows. Strength from `-aq-strength`. | `0` to `1` |
| `-temporal-aq` | `boolean` | `false` | Temporal adaptive quantization: more bits for static areas that later frames reference. | `0` to `1` |
| `-zerolatency` | `boolean` | `false` | No reordering delay in the output; for low-latency streaming. | `0` to `1` |
| `-nonref_p` | `boolean` | `false` | Automatically insert non-reference P-frames. | `0` to `1` |
| `-strict_gop` | `boolean` | `false` | Hold each GOP to its bit budget, reducing rate swings between GOPs. | `0` to `1` |
| `-aq-strength` | `int` | `8` | Spatial AQ strength, 1 (weak) to 15 (strong). | `1` to `15` |
| `-weighted_pred` | `boolean` | `false` | Weighted prediction, which helps fades. | `0` to `1` |
| `-b_ref_mode` | `int` | `-1` | Use B-frames as references: `disabled`, `each` or `middle`. -1 keeps the preset's choice. | `-1` to `4`; `disabled`=`0`, `each`=`1`, `middle`=`2`, `hierarchical`=`4` |
| `-dpb_size` | `int` | `0` | Reference-frame buffer size; 0 = automatic. | `0` to `INT_MAX` |
| `-ldkfs` | `int` | `0` | How much larger a scene-change frame may be with single-frame VBV or CBR; 0 = driver default. | `0` to `255` |
| `-intra-refresh` | `boolean` | `false` | Rolling intra refresh instead of periodic key frames; for low-latency streaming. | `0` to `1` |
| `-timing-info` | `boolean` | `false` | Write timing information into the sequence/frame headers. | `0` to `1` |
| `-extra_sei` | `boolean` | `true` | Pass side data such as captions into the bitstream as metadata. | `0` to `1` |
| `-a53cc` | `boolean` | `true` | Carry A/53 closed captions from the input. | `0` to `1` |
| `-s12m_tc` | `boolean` | `true` | Carry SMPTE 12M timecode from the input. | `0` to `1` |
| `-cbr_padding` | `boolean` | `false` | Pad CBR output so the bitrate never falls below the target. | `0` to `1` |
| `-tf_level` | `int` | `-1` | Temporal filtering before encoding: `0` off, `4` on. Needs at least 4 B-frames (`-bf 4`). | `-1` to `INT_MAX`; `0`=`0`, `4`=`4` |
| `-lookahead_level` | `int` | `-1` | Lookahead analysis depth 0–3 or `auto`; higher is slower and better. Only with `-rc-lookahead`. | `-1` to `15`; `auto`=`15`, `0`=`0`, `1`=`1`, `2`=`2`, `3`=`3` |
| `-split_encode_mode` | `int` | `auto` | Split each frame across several NVENC engines on GPUs that have them: `auto`, `forced`, `2`/`3`/`4` engines, or `disabled`. | `0` to `15`; `disabled`=`15`, `auto`=`0`, `forced`=`1`, `2`=`2`, `3`=`3`, `4`=`4` |

### 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` | `2M` |
| `-qmin` | `-1` |
| `-qmax` | `-1` |
| `-qdiff` | `-1` |
| `-qblur` | `-1` |
| `-qcomp` | `-1` |
| `-g` | `-1` |
| `-bf` | `-1` |
| `-refs` | `0` |

{/* ffmpeg-parameters:end */}
