{"id":112,"date":"2017-04-10T10:54:00","date_gmt":"2017-04-10T13:54:00","guid":{"rendered":"https:\/\/www.linuxpro.com.br\/2017\/04\/compile-ffmpeg-nvenc-ubuntu\/"},"modified":"2026-09-08T11:12:43","modified_gmt":"2026-09-08T14:12:43","slug":"compile-ffmpeg-nvenc-ubuntu","status":"publish","type":"post","link":"https:\/\/www.linuxpro.com.br\/en\/2017\/04\/compile-ffmpeg-nvenc-ubuntu\/","title":{"rendered":"Compiling FFMPEG with NVENC on Ubuntu"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" alt=\"Mascote do LinuxPro encaixando uma placa NVIDIA para usar o NVENC com FFmpeg\" src=\"\/wp-content\/uploads\/2026\/09\/compile-ffmpeg-nvenc-v2.webp\" width=\"1486\" height=\"856\" \/><\/p>\n<div style=\"background:#fff8e1;border-left:4px solid #8b1a1a;padding:.8em 1em;margin:1em 0\"><strong>Note (2026):<\/strong> the original text covered Ubuntu 16.04, FFmpeg 3.2.1, and NVIDIA Video Codec SDK 6.0.1\/7.0.1. The video from Canal Oficina do Tux (<code data-no-translation=\"\">xdltF4HvfjE<\/code>) went offline. The DEBs from the oficinadotux repository (16\/18\/19) and the compilation gist from 2017 remain only as historical material at the end. Today the approach is the proprietary driver + FFmpeg with <code data-no-translation=\"\">ffnvcodec<\/code> (headers 13.1.15, Linux driver \u2265 610) \u2014 and, most of the time, <em>without<\/em> downloading the proprietary SDK.<\/div>\n<p>NVENC is still the same NVIDIA hardware block: it takes H.264\/HEVC\/AV1 off the CPU and sends it to the GPU's ASIC. What changed is the packaging. In 2017 you compiled FFmpeg against the SDK. In 2026 FFmpeg talks to the driver through <a href=\"https:\/\/code.ffmpeg.org\/FFmpeg\/nv-codec-headers\">nv-codec-headers<\/a> (MIT). First check whether the binary you already have lists the encoders; compile only if they are missing.<\/p>\n<p><!-- more --><\/p>\n<h2>What changed since 2017<\/h2>\n<ul>\n<li>Ubuntu 24.04 LTS ships FFmpeg <strong>6.1.1<\/strong>; 26.04 LTS ships <strong>8.0.1<\/strong> (universe).<\/li>\n<li>The current Video Codec SDK is <strong>13.1<\/strong>. The public headers are at <code data-no-translation=\"\">nv-codec-headers<\/code> 13.1.15 \u2014 minimum driver 610.<\/li>\n<li>Old presets (<code data-no-translation=\"\">llhq<\/code>, <code data-no-translation=\"\">slow<\/code> as an NVENC preset name) gave way to <code data-no-translation=\"\">p1<\/code>\u2026<code data-no-translation=\"\">p7<\/code>.<\/li>\n<li>In addition to <code data-no-translation=\"\">h264_nvenc<\/code> and <code data-no-translation=\"\">hevc_nvenc<\/code> there is <code data-no-translation=\"\">av1_nvenc<\/code> (Ada \/ RTX 40 and newer).<\/li>\n<li>NPP in FFmpeg is deprecated with CUDA greater than 12.8. NVIDIA calls for <code data-no-translation=\"\">scale_cuda<\/code>, not <code data-no-translation=\"\">scale_npp<\/code>. Avoid <code data-no-translation=\"\">--enable-libnpp<\/code>.<\/li>\n<li class=\"translation-block\">OBS on Linux talks to NVENC through the driver. Compiling FFmpeg is <em>no longer<\/em> a prerequisite for recording\/streaming in OBS.<\/li>\n<\/ul>\n<h2>Check the GPU and driver<\/h2>\n<p>Without the proprietary driver there is no NVENC. Nouveau does not count. Details on how the GPU works: <a href=\"\/en\/2026\/09\/como-funcionam-placas-de-video\/\">How graphics cards work<\/a>.<\/p>\n<pre data-no-translation=\"\"><code class=\"language-bash\" data-no-translation=\"\">nvidia-smi\n# Driver Version e o nome da GPU. Para headers 13.1: driver \u2265 610.\n\nffmpeg -hide_banner -encoders | grep nvenc\nffmpeg -hide_banner -decoders | grep cuvid\nffmpeg -hide_banner -hwaccels | grep -E 'cuda|nvdec'<\/code><\/pre>\n<p>If you see <code data-no-translation=\"\">h264_nvenc<\/code> \/ <code data-no-translation=\"\">hevc_nvenc<\/code> (and <code data-no-translation=\"\">av1_nvenc<\/code> on Ada+), the system's FFmpeg is already suitable. Also install the driver's encode\/decode libraries:<\/p>\n<pre data-no-translation=\"\"><code class=\"language-bash\" data-no-translation=\"\"># Ubuntu\nsudo apt install libnvidia-decode libnvidia-encode\n\n# Debian (nomes com sufixo 1)\nsudo apt install libnvcuvid1 libnvidia-encode1<\/code><\/pre>\n<p>For those who do not have the driver yet:<\/p>\n<pre data-no-translation=\"\"><code class=\"language-bash\" data-no-translation=\"\">ubuntu-drivers devices\nsudo ubuntu-drivers install\n# ou um ramo espec\u00edfico, ex.: sudo apt install nvidia-driver-570\nsudo reboot<\/code><\/pre>\n<h2>Shortcut: Ubuntu's ffmpeg<\/h2>\n<pre data-no-translation=\"\"><code class=\"language-bash\" data-no-translation=\"\">sudo apt update\nsudo apt install ffmpeg\nffmpeg -version\nffmpeg -hide_banner -encoders | grep nvenc<\/code><\/pre>\n<p>Debian\/Ubuntu compile FFmpeg with <code data-no-translation=\"\">libffmpeg-nvenc-dev<\/code> (MIT headers only). NVENC\/NVDEC are included through autodetection; the NVIDIA libraries are a <em>suggested<\/em>, not mandatory, package dependency. That is why the binary lists the encoders even on a machine without a GPU \u2014 and fails at runtime if the driver is absent.<\/p>\n<p>If <code data-no-translation=\"\">grep nvenc<\/code> returns nothing, you have a build without ffnvcodec (snap, an old static binary, an odd PPA). Then use jellyfin-ffmpeg or compile.<\/p>\n<h2>Shortcut 2: jellyfin-ffmpeg<\/h2>\n<p>The <a href=\"https:\/\/github.com\/jellyfin\/jellyfin-ffmpeg\">jellyfin-ffmpeg<\/a> is FFmpeg 7.1.x \/ 8.1.x already linked with NVENC, QSV, and VA-API. You can install the package by itself, without the Jellyfin server. In 2026: <code data-no-translation=\"\">jellyfin-ffmpeg7<\/code> (7.1.4) and <code data-no-translation=\"\">jellyfin-ffmpeg8<\/code> (8.1.1).<\/p>\n<pre data-no-translation=\"\"><code class=\"language-bash\" data-no-translation=\"\">curl -fsSL https:\/\/repo.jellyfin.org\/install-debuntu.sh | sudo bash\nsudo apt install jellyfin-ffmpeg7 libnvidia-decode libnvidia-encode\n\n\/usr\/lib\/jellyfin-ffmpeg\/ffmpeg -hide_banner -encoders | grep nvenc<\/code><\/pre>\n<p>The binary lives in <code data-no-translation=\"\">\/usr\/lib\/jellyfin-ffmpeg\/ffmpeg<\/code>, it does not replace Ubuntu's <code data-no-translation=\"\">\/usr\/bin\/ffmpeg<\/code> . Use the full path (or an alias) when you want guaranteed NVENC support.<\/p>\n<h2>Compiling: official NVIDIA 13.1 recipe<\/h2>\n<p>Documentation: <a href=\"https:\/\/docs.nvidia.com\/video-technologies\/video-codec-sdk\/13.1\/ffmpeg-with-nvidia-gpu\/index.html\">Using FFmpeg with NVIDIA GPU Hardware Acceleration<\/a> (SDK 13.1). Official FFmpeg repositories are now at <code data-no-translation=\"\">code.ffmpeg.org<\/code>.<\/p>\n<p>Useful when you want FFmpeg 8 on 24.04, CUDA filters, or an isolated prefix without touching the system package.<\/p>\n<pre data-no-translation=\"\"><code class=\"language-bash\" data-no-translation=\"\">sudo apt update\nsudo apt -y install git build-essential pkg-config nasm clang \n  libx264-dev libx265-dev libopus-dev libvpx-dev libmp3lame-dev \n  libass-dev libfreetype6-dev libgnutls28-dev\n\nmkdir -p ~\/src && cd ~\/src\n\ngit clone https:\/\/code.ffmpeg.org\/FFmpeg\/nv-codec-headers.git\ncd nv-codec-headers\n# driver &lt; 610: git checkout n12.2.72.0\nsudo make install\ncd ..\n\ngit clone https:\/\/code.ffmpeg.org\/FFmpeg\/FFmpeg.git\ncd FFmpeg\n# master quebra de vez em quando; pin numa release:\n# git checkout n8.0.1\n\n.\/configure --prefix=\"$PWD\/build\" \n  --enable-gpl --enable-nonfree \n  --disable-static --enable-shared \n  --nvcc=clang \n  --enable-libx264 --enable-libx265 --enable-libopus \n  --enable-libvpx --enable-libmp3lame --enable-libass --enable-gnutls\n\nmake -j\"$(nproc)\"\nmake install\n\nexport PATH=\"$PWD\/build\/bin:$PATH\"\nexport LD_LIBRARY_PATH=\"$PWD\/build\/lib:${LD_LIBRARY_PATH:-}\"\n\nffmpeg -hide_banner -encoders | grep nvenc\nffmpeg -hide_banner -filters  | grep cuda<\/code><\/pre>\n<p>The flag <code data-no-translation=\"\">--enable-nonfree<\/code> is included because FFmpeg treats NVENC as nonfree when redistributing the binary. The headers are MIT; the proprietary blob is the driver. Do not enable <code data-no-translation=\"\">--enable-libnpp<\/code>. The CUDA runtime is not mandatory \u2014 FFmpeg uses the driver API.<\/p>\n<p>To persist the local prefix, add this to <code data-no-translation=\"\">~\/.bashrc<\/code>:<\/p>\n<pre data-no-translation=\"\"><code class=\"language-bash\" data-no-translation=\"\">export PATH=\"$HOME\/src\/FFmpeg\/build\/bin:$PATH\"\nexport LD_LIBRARY_PATH=\"$HOME\/src\/FFmpeg\/build\/lib:${LD_LIBRARY_PATH:-}\"<\/code><\/pre>\n<p>Do not install in <code data-no-translation=\"\">\/usr<\/code> on top of the package <code data-no-translation=\"\">ffmpeg<\/code>. The prefix <code data-no-translation=\"\">build\/<\/code> avoids fighting with apt.<\/p>\n<h2>Using the encoders<\/h2>\n<p>Entire pipeline on the GPU (CUDA decode \u2192 NVENC encode), without going back through RAM:<\/p>\n<pre data-no-translation=\"\"><code class=\"language-bash\" data-no-translation=\"\">ffmpeg -y -hwaccel cuda -hwaccel_output_format cuda \n  -i entrada.mp4 \n  -c:v h264_nvenc -preset p4 -b:v 5M -fps_mode passthrough \n  -c:a copy \n  saida.mp4<\/code><\/pre>\n<p>HEVC (Maxwell 2nd gen+) and AV1 (Ada \/ RTX 40+):<\/p>\n<pre data-no-translation=\"\"><code class=\"language-bash\" data-no-translation=\"\"># HEVC qualidade (arquivo, n\u00e3o live)\nffmpeg -y -hwaccel cuda -hwaccel_output_format cuda -i entrada.mp4 \n  -c:v hevc_nvenc -preset p6 -tune hq -rc vbr -cq 23 -b:v 0 \n  -c:a copy saida.mkv\n\n# AV1\nffmpeg -y -hwaccel cuda -hwaccel_output_format cuda -i entrada.mp4 \n  -c:v av1_nvenc -preset p5 -tune hq -rc constqp -qp 28 \n  -c:a copy saida.mkv<\/code><\/pre>\n<p>Resize on the GPU with <code data-no-translation=\"\">scale_cuda<\/code> (replacement for <code data-no-translation=\"\">scale_npp<\/code>):<\/p>\n<pre data-no-translation=\"\"><code class=\"language-bash\" data-no-translation=\"\">ffmpeg -y -hwaccel cuda -hwaccel_output_format cuda -i entrada.mp4 \n  -vf scale_cuda=1280:720:interp_algo=bilinear \n  -c:v h264_nvenc -preset p4 -b:v 4M -c:a copy saida.mp4<\/code><\/pre>\n<p>Presets: <code data-no-translation=\"\">p1<\/code> faster \/ lower quality, <code data-no-translation=\"\">p7<\/code> slower \/ better. <code data-no-translation=\"\">p4<\/code> is the default. Tune: <code data-no-translation=\"\">hq<\/code> (file), <code data-no-translation=\"\">ll<\/code> \/ <code data-no-translation=\"\">ull<\/code> (live), <code data-no-translation=\"\">uhq<\/code> (HEVC\/AV1, Turing+, more VRAM).<\/p>\n<p>Multiple GPUs: <code data-no-translation=\"\">-hwaccel_device 1<\/code> or <code data-no-translation=\"\">CUDA_VISIBLE_DEVICES=1<\/code>. List: <code data-no-translation=\"\">nvidia-smi -L<\/code>.<\/p>\n<h2>OBS Studio<\/h2>\n<p>In current OBS, the \u201cNVIDIA NVENC\u201d encoder appears automatically when the proprietary driver is running. It does not depend on the FFmpeg you compiled. OBS Flatpak uses its own runtime: the NVIDIA Flatpak package (<code data-no-translation=\"\">org.freedesktop.Platform.GL.nvidia-\u2026<\/code>) needs to match the host driver.<\/p>\n<p>On the CLI, the equivalent of \u201crecord the screen with NVENC\u201d is still FFmpeg; OBS is the UI. SimpleScreenRecorder has fallen behind \u2014 if you still use it, migrate to OBS or FFmpeg itself.<\/p>\n<h2>Hardware by generation<\/h2>\n<ul>\n<li><code data-no-translation=\"\">h264_nvenc<\/code> \u2014 Kepler (GTX 600) onward.<\/li>\n<li><code data-no-translation=\"\">hevc_nvenc<\/code> \u2014 Maxwell 2nd gen (GTX 900) onward; 10-bit becomes decent on Pascal+.<\/li>\n<li><code data-no-translation=\"\">av1_nvenc<\/code> \u2014 Ada (RTX 40) and Blackwell (RTX 50).<\/li>\n<\/ul>\n<p>The limit of 3 simultaneous sessions on GeForce was removed in driver 456.71 (2020). If an encode refuses a session, update the driver before blaming FFmpeg.<\/p>\n<h2>History (2017)<\/h2>\n<p>The workflow back then \u2014 SDK 6\/7, FFmpeg 3.2.1, a gist script, DEB for Ubuntu 16\/18\/19 \u2014 is archived at:<\/p>\n<ul>\n<li><a href=\"https:\/\/gist.github.com\/jniltinho\/9273dc133796062c13ca739d17862125\">compilation gist (FFmpeg 3.2.1 + SDK 7.0.1)<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/jniltinho\/oficinadotux\">oficinadotux<\/a> (16\/18\/19 binaries)<\/li>\n<li><a href=\"https:\/\/gitlab.com\/jniltinho\/docker-ffmpeg\">gitlab.com\/jniltinho\/docker-ffmpeg<\/a><\/li>\n<\/ul>\n<p>Do not use these binaries on Ubuntu 24.04\/26.04. The YouTube video accompanying the original post is no longer available.<\/p>\n<p>Summary: <code data-no-translation=\"\">nvidia-smi<\/code> running, <code data-no-translation=\"\">ffmpeg -encoders | grep nvenc<\/code> listed, encode with <code data-no-translation=\"\">-hwaccel cuda -hwaccel_output_format cuda<\/code> and <code data-no-translation=\"\">scale_cuda<\/code>. Compile only if Ubuntu's package or jellyfin-ffmpeg is not enough.<\/p>","protected":false},"excerpt":{"rendered":"<p>NVENC remains the same NVIDIA hardware block: it takes H.264\/HEVC\/AV1 off the CPU and sends it to the GPU\u2019s ASIC. What changed is the packaging. In 2017, you compiled FFmpeg against the SDK. In 2026, FFmpeg communicates \u2026 <a title=\"Compiling FFMPEG with NVENC on Ubuntu\" class=\"read-more\" href=\"https:\/\/www.linuxpro.com.br\/en\/2017\/04\/compile-ffmpeg-nvenc-ubuntu\/\" aria-label=\"Read more about Compilar FFMPEG com NVENC no Ubuntu\">Read more<\/a><\/p>","protected":false},"author":0,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[33,2,3],"tags":[36,37,134,38,4,205,152,34,35],"class_list":["post-112","post","type-post","status-publish","format-standard","hentry","category-howtos","category-linux","category-ubuntu","tag-compile","tag-ffmpeg","tag-gpu","tag-gravar","tag-linux","tag-nvenc","tag-nvidia","tag-obs","tag-www"],"_links":{"self":[{"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/posts\/112","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/comments?post=112"}],"version-history":[{"count":7,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/posts\/112\/revisions"}],"predecessor-version":[{"id":1405,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/posts\/112\/revisions\/1405"}],"wp:attachment":[{"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/media?parent=112"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/categories?post=112"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/tags?post=112"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}