NVIDIA FFmpeg Transcoding Guide

Originally published at: https://developer.nvidia.com/blog/nvidia-ffmpeg-transcoding-guide/

All NVIDIA GPUs starting with the Kepler generation support fully-accelerated hardware video encoding, and all GPUs starting with Fermi generation support fully-accelerated hardware video decoding. As of July 2019 Kepler, Maxwell, Pascal, Volta and Turing generation GPUs support hardware encoding, and Fermi, Kepler, Maxwell, Pascal, Volta and Turing generation GPUs support hardware decoding. The processing…

Why nVidia forum is not speed enough to solve the issue in time. ?

I get "No NVENC capable devices found" error from ffmpeg encoding, Only
if I use -flags:v +ildct flag. Without +ildct flag no issues except the
output is progressive.

All older nVidia cards are working fine with same flags.

I 100% need Interlaced output and I tried most of the Interlaced flags like,
-vf tinterlace=interleave_top,fieldorder=tff -x264opts tff=1
Nothing is giving me Interlaced output except -flags +ildct

But with "Zotac nVidia GEForce GTX 1660"
ffmpeg shows: No NVENC capable devices found

I even tried all latest nVidia drivers. Nothing helped me.

My pseudo ffmpeg command line is as below:
ffmpeg -i SourceFile.mkv -codec:v h264_nvenc -preset:v slow -flags:v +ildct+cgop -s:v 1920x1080 -ac 2 -ar 48000 -codec:a mp2 -b:a 384k -r 25 -f mp4 -y NewFile.mp4

Is it a bug with nVidia driver or GTX 1660 ?
Is latest nVidia Turing technology doesn't support Interlaced (very Bad) ?
Could some one help me ?

Why is there no NVENC encoding in Mac OS X, Handbrake only supports it in Windows, and the Voudker Adobe Premiere Plugin for exporting video's using NVENC / HEVC also only works in Windows. Nvidia developers should be assisting these open source projects for cross platform support, other wise there is no point in using Nvidia video cards on Mac Pro's even if it is only small market share for Nvidia.

"Activating support for hardware acceleration when building from source requires some extra steps:"
Did you follow instructions for compiling your own copy of FFMPEG?

@Terence Kearns: Thanks
Hope you read my post fully.

I have already built ffmpeg with nvEnc capable and I am using already. --enable-cuvid --enable-nvenc --enable-nvdec

My issue is with interlace is not supported in 16 series cards (Turing) Interlace option is must for broadcast streaming.

I don't know why all of a sudden nVidia taken away this feature from Turing cards.

This option throwing error in latest cards.
-flags:v +ildct

gaamaa

Well id doesn't look like nVidia is going to take any notice of you. It seems odd that you need an older card in order to retain features.

you're either going to have to get an older card or you're gonna have to use CPU.

It may be possible that an older version of FFMPEG or an older version of nv-codec-headers will still work. You will have to experiement. You've waited six months with no solution so maybe set aside a day to regression test older versions until you find one that works again.

I'm having trouble building a binary on windows. I'm not a C programmer so it's hard to figure out. I suspect this would be a lot easier under linux with gcc built right in, but I tried using mingw and it works to a point, but I get errors. I posted the problem here

https://devtalk.nvidia.com/...

Thanks again Terence Kearns,
I wend back to all older version of ffmpeg and no luck.
Older nVidia cards (9 and 10 series) are working like charm.
But those cards are no more avalable on the market.
My question is why all of a sudden nVidia removde bFrame (interlaced) support in latest cards like Turing.
Without interlaced support nVidia is useless.

Last I checked, interlaced encoding seems to be disabled on Turing GPUs. Also take a look at this: https://devtalk.nvidia.com/...
g

Hi,

Lokking for some help with something that I had working some time ago.

The command "ffmpeg -vsync 0 -i input.mp4 -c:v hevc_nvenc -gpu list -f null -" I copied from the page above does not work anymore.
I get the following error:

# ffmpeg -vsync 0 -i input.mp4 -c:v hevc_nvenc -gpu list out.mp4
ffmpeg version 4.2.2 Copyright (c) 2000-2019 the FFmpeg developers
built with gcc 4.8.5 (GCC) 20150623 (Red Hat 4.8.5-36)
configuration: --prefix=/usr --arch=x86_64 --disable-shared --disable-debug --enable-nonfree --enable-nvenc --enable-cuda --enable-cuvid --enable-libnpp --enable-gpl --enable-fontconfig --enable-gnutls --enable-gray --enable-libfreetype --enable-version3 --extra-cflags=-Ilocal/include --extra-cflags=-I/home/pcarmo/HARDENING/RPMS/ffmpeg/ffmpeg-4.2.2 --extra-ldflags=-L/home/pcarmo/HARDENING/RPMS/ffmpeg/ffmpeg-4.2.2 --extra-cflags=-I/home/pcarmo/HARDENING/RPMS/ffmpeg/Video_Codec_SDK_7.1.9/Samples/common/inc/ --extra-cflags=-I/usr/local/cuda-10.0/targets/x86_64-linux/include --extra-ldflags=-L/usr/local/cuda-10.0/targets/x86_64-linux/lib --extra-ldflags=-L/usr/lib64/nvidia
libavutil 56. 31.100 / 56. 31.100
libavcodec 58. 54.100 / 58. 54.100
libavformat 58. 29.100 / 58. 29.100
libavdevice 58. 8.100 / 58. 8.100
libavfilter 7. 57.100 / 7. 57.100
libswscale 5. 5.100 / 5. 5.100
libswresample 3. 5.100 / 3. 5.100
libpostproc 55. 5.100 / 55. 5.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.29.100
Duration: 00:00:27.90, start: 0.000000, bitrate: 374 kb/s
Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 1366x768 [SAR 1:1 DAR 683:384], 371 kb/s, 30 fps, 30 tbr, 15360 tbn, 60 tbc (default)
Metadata:
handler_name : VideoHandler
File 'out.mp4' already exists. Overwrite ? [y/N] y
Stream mapping:
Stream #0:0 -> #0:0 (h264 (native) -> hevc (hevc_nvenc))
Press [q] to stop, [?] for help
[hevc_nvenc @ 0x2347e40] [ GPU #0 - < Quadro P2000 > has Compute SM 6.1 ]
Error initializing output stream 0:0 -- Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height
Conversion failed!
.
.
.

I know hevc_nvenc is avaliable and working as I can successful run the command:

.
.
.

# ffmpeg -vsync 0 -i input.mp4 -c:v hevc_nvenc -gpu all out.mp4
ffmpeg version 4.2.2 Copyright (c) 2000-2019 the FFmpeg developers
built with gcc 4.8.5 (GCC) 20150623 (Red Hat 4.8.5-36)
configuration: --prefix=/usr --arch=x86_64 --disable-shared --disable-debug --enable-nonfree --enable-nvenc --enable-cuda --enable-cuvid --enable-libnpp --enable-gpl --enable-fontconfig --enable-gnutls --enable-gray --enable-libfreetype --enable-version3 --extra-cflags=-Ilocal/include --extra-cflags=-I/home/pcarmo/HARDENING/RPMS/ffmpeg/ffmpeg-4.2.2 --extra-ldflags=-L/home/pcarmo/HARDENING/RPMS/ffmpeg/ffmpeg-4.2.2 --extra-cflags=-I/home/pcarmo/HARDENING/RPMS/ffmpeg/Video_Codec_SDK_7.1.9/Samples/common/inc/ --extra-cflags=-I/usr/local/cuda-10.0/targets/x86_64-linux/include --extra-ldflags=-L/usr/local/cuda-10.0/targets/x86_64-linux/lib --extra-ldflags=-L/usr/lib64/nvidia
libavutil 56. 31.100 / 56. 31.100
libavcodec 58. 54.100 / 58. 54.100
libavformat 58. 29.100 / 58. 29.100
libavdevice 58. 8.100 / 58. 8.100
libavfilter 7. 57.100 / 7. 57.100
libswscale 5. 5.100 / 5. 5.100
libswresample 3. 5.100 / 3. 5.100
libpostproc 55. 5.100 / 55. 5.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.29.100
Duration: 00:00:27.90, start: 0.000000, bitrate: 374 kb/s
Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 1366x768 [SAR 1:1 DAR 683:384], 371 kb/s, 30 fps, 30 tbr, 15360 tbn, 60 tbc (default)
Metadata:
handler_name : VideoHandler
File 'out.mp4' already exists. Overwrite ? [y/N] y
Stream mapping:
Stream #0:0 -> #0:0 (h264 (native) -> hevc (hevc_nvenc))
Press [q] to stop, [?] for help
Output #0, mp4, to 'out.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.29.100
Stream #0:0(und): Video: hevc (hevc_nvenc) (Main) (hev1 / 0x31766568), yuv420p, 1366x768 [SAR 1:1 DAR 683:384], q=-1--1, 2000 kb/s, 30 fps, 15360 tbn, 30 tbc (default)
Metadata:
handler_name : VideoHandler
encoder : Lavc58.54.100 hevc_nvenc
Side data:
cpb: bitrate max/min/avg: 0/0/2000000 buffer size: 4000000 vbv_delay: -1
frame= 837 fps=563 q=9.0 Lsize= 1622kB time=00:00:27.86 bitrate= 476.9kbits/s speed=18.7x
video:1618kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.259576%
.
.
.

So, why the "-gpu list" stoped working? I had it work some time ago before upgrading ffmpeg/cuda...

Thank!

Excellent tutorial. I've added hw accelerated decodes and cuda_hwupload (for special filter cases) to my encodes.

ffmpeg -f lavfi -i nullsrc -c:v hevc_nvenc -gpu list -f null -

See if that works?

I am trying to encode 10-bit content to 8-bit, is there a way to this in complete GPU.. I am able to do it using CPU/GPU, however performance is not acceptable, I use the following command line::

ffmpeg -init_hw_device cuda=hw -filter_hw_device hw -c:v hevc_cuvid –resize 1280x720 -i hevc_10b_4K60p_BroadcastCaptureSample.mkv -vf "fps=fps=30,format=yuv420p,hwupload" -c:v hevc_nvenc output.mp4

Is there a way to avoid 10-bit to 8-bit conversion on CPU ? Please help.

Hi,

It does not:

# ffmpeg -f lavfi -i nullsrc -c:v hevc_nvenc -gpu list -f null -
ffmpeg version 4.2.2 Copyright (c) 2000-2019 the FFmpeg developers
built with gcc 4.8.5 (GCC) 20150623 (Red Hat 4.8.5-36)
configuration: --prefix=/usr --arch=x86_64 --disable-shared --disable-debug --enable-nonfree --enable-nvenc --enable-cuda --enable-cuvid --enable-libnpp --enable-gpl --enable-fontconfig --enable-gnutls --enable-gray --enable-libfreetype --enable-version3 --extra-cflags=-Ilocal/include --extra-cflags=-I/home/pcarmo/HARDENING/RPMS/ffmpeg/ffmpeg-4.2.2 --extra-ldflags=-L/home/pcarmo/HARDENING/RPMS/ffmpeg/ffmpeg-4.2.2 --extra-cflags=-I/home/pcarmo/HARDENING/RPMS/ffmpeg/Video_Codec_SDK_7.1.9/Samples/common/inc/ --extra-cflags=-I/usr/local/cuda-10.1/targets/x86_64-linux/include --extra-ldflags=-L/usr/local/cuda-10.1/targets/x86_64-linux/lib --extra-ldflags=-L/usr/lib64/nvidia
libavutil 56. 31.100 / 56. 31.100
libavcodec 58. 54.100 / 58. 54.100
libavformat 58. 29.100 / 58. 29.100
libavdevice 58. 8.100 / 58. 8.100
libavfilter 7. 57.100 / 7. 57.100
libswscale 5. 5.100 / 5. 5.100
libswresample 3. 5.100 / 3. 5.100
libpostproc 55. 5.100 / 55. 5.100
Input #0, lavfi, from 'nullsrc':
Duration: N/A, start: 0.000000, bitrate: N/A
Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p, 320x240 [SAR 1:1 DAR 4:3], 25 tbr, 25 tbn, 25 tbc
Stream mapping:
Stream #0:0 -> #0:0 (rawvideo (native) -> hevc (hevc_nvenc))
Press [q] to stop, [?] for help
[hevc_nvenc @ 0x31bf080] [ GPU #0 - < Quadro P2000 > has Compute SM 6.1 ]
Error initializing output stream 0:0 -- Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height
Conversion failed!

I'm sure it worked in the past, but now it just give the error above :(

Did you figure it out?

No.

Munish, could you give me some more detail about your business use case here? I'll try to find some answers for you, though our developers are a little busy with GTC Digital. Thanks!

Jen, I need 10-bit to 8-bit transcoding for casting 10-bit videos to streaming sticks and smart tvs. Additionally, I want to transcode 10-bit HDR (high dynamic range) content to 8-bit SDR content for casting on streaming sticks and smart tvs with SDR display.

Munish, may I suggest posting your question at https://forums.developer.nv... It would be great to open this up to the community and see if someone can help.

Jen, I have posted the same at https://forums.developer.nv...