Skip to content

NVENC

currentMigrated from docs/encoders_hw/nvenc.mdx at 37c3317fd058; modified for Encode Wiki · CC BY-SA 4.0

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.

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, x265 or SVT-AV1. The other hardware encoders on this wiki have the same trade-off.

CodecFFmpeg encoderNotes
H.264h264_nvencEvery NVENC generation. 4:2:0 and 4:4:4.
HEVChevc_nvencMaxwell 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.
AV1av1_nvencAda 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 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.

Terminal window
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:

Terminal window
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).

Terminal window
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.

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

Terminal window
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.

OptionWhat it does
-preset p1–p7Speed/quality ladder. p1 is fastest, p7 slowest and best. The older slow/medium/fast names are legacy presets; use p1–p7.
-tunehq 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.
-rcvbr (with -cq for constant quality), cbr, constqp (with -qp).
-rc-lookahead NLooks 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 middleB-frames and using them as references. HEVC B-frames need Turing or newer.
-spatial-aq 1, -temporal-aq 1Adaptive 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 fullresTwo-pass analysis inside the encoder (not FFmpeg’s -pass 1/-pass 2). Slower, steadier bit allocation.
-gpu NChoose the GPU. -gpu list prints the devices.
  • -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.

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

ParameterTypeDefaultMeaningRange / named values
-presetintp4Speed/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
-tuneinthqhq 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
-levelintautoAV1 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
-tierint0AV1 tier: 0 Main, 1 High.0 to 1; 0=0, 1=1
-rcint-1Rate control: constqp, vbr or cbr. -1 picks constqp when -qp is set, otherwise vbr.-1 to INT_MAX; constqp=0, vbr=1, cbr=2
-multipassintdisabledExtra 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
-highbitdepthbooleanfalseEncode 10-bit from 8-bit input; reduces banding at little cost.0 to 1
-tile-rowsint-1Tile rows; -1 lets the driver choose.-1 to 64
-tile-columnsint-1Tile columns; -1 lets the driver choose.-1 to 64
-surfacesint0Input frame buffers; 0 sizes them from B-frames and lookahead.0 to 64
-gpuintanyGPU index (0 = first). list prints the available GPUs; any uses the default device.-2 to INT_MAX; any=-1, list=-2
-rgb_modeintyuv420Packed RGB input is converted to yuv420 or yuv444; disabled rejects RGB input.0 to INT_MAX; yuv420=1, yuv444=2, disabled=0
-delayintINT_MAXFrames of output delay (async depth); INT_MAX means automatic (surfaces − 1). Too small a value disables lookahead.0 to INT_MAX
-rc-lookaheadint0Lookahead frames for rate control and adaptive I/B placement; 0 = off. Clipped to what -surfaces/-delay allow.0 to INT_MAX
-cqfloat0Quality 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_qpPint-1Starting QP for P-frames in VBR/CBR; -1 derives it from -qmin/-qmax.-1 to 255
-init_qpBint-1Starting QP for B-frames in VBR/CBR; -1 derives it.-1 to 255
-init_qpIint-1Starting QP for I-frames in VBR/CBR; -1 derives it.-1 to 255
-qpint-1Constant QP for all frames (selects constqp). AV1 scale 0–255.-1 to 255
-qp_cb_offsetint0QP offset for Cb (blue-difference chroma).-12 to 12
-qp_cr_offsetint0QP offset for Cr. The AV1 driver ignores it and applies the Cb offset to both.-12 to 12
-qminint-1Lowest QP rate control may use; -1 = no limit.-1 to 255
-qmaxint-1Highest QP rate control may use; -1 = no limit.-1 to 255
-no-scenecutbooleanfalseWith lookahead on, stop inserting I-frames at scene cuts.0 to 1
-forced-idrbooleanfalseMake keyframes requested with -force_key_frames full key frames instead of intra-only frames.0 to 1
-b_adaptbooleantrueWith lookahead on, adapt the B-frame count to the content; 0 keeps a fixed pattern.0 to 1
-spatial-aqbooleanfalseSpatial adaptive quantization: moves bits into flat areas where blocking shows. Strength from -aq-strength.0 to 1
-temporal-aqbooleanfalseTemporal adaptive quantization: more bits for static areas that later frames reference.0 to 1
-zerolatencybooleanfalseNo reordering delay in the output; for low-latency streaming.0 to 1
-nonref_pbooleanfalseAutomatically insert non-reference P-frames.0 to 1
-strict_gopbooleanfalseHold each GOP to its bit budget, reducing rate swings between GOPs.0 to 1
-aq-strengthint8Spatial AQ strength, 1 (weak) to 15 (strong).1 to 15
-weighted_predbooleanfalseWeighted prediction, which helps fades.0 to 1
-b_ref_modeint-1Use 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_sizeint0Reference-frame buffer size; 0 = automatic.0 to INT_MAX
-ldkfsint0How much larger a scene-change frame may be with single-frame VBV or CBR; 0 = driver default.0 to 255
-intra-refreshbooleanfalseRolling intra refresh instead of periodic key frames; for low-latency streaming.0 to 1
-timing-infobooleanfalseWrite timing information into the sequence/frame headers.0 to 1
-extra_seibooleantruePass side data such as captions into the bitstream as metadata.0 to 1
-a53ccbooleantrueCarry A/53 closed captions from the input.0 to 1
-s12m_tcbooleantrueCarry SMPTE 12M timecode from the input.0 to 1
-cbr_paddingbooleanfalsePad CBR output so the bitrate never falls below the target.0 to 1
-tf_levelint-1Temporal filtering before encoding: 0 off, 4 on. Needs at least 4 B-frames (-bf 4).-1 to INT_MAX; 0=0, 4=4
-lookahead_levelint-1Lookahead 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_modeintautoSplit 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

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 parameterDefault
-b2M
-qmin-1
-qmax-1
-qdiff-1
-qblur-1
-qcomp-1
-g-1
-bf-1
-refs0