Hardware Accelerated Decode (Nvidia) for Linux

Interesting, didn’t realize that was something that could be hardware accelerated too (personally I never really saw any noteworthy CPU usage after doing what I did, so I assumed everything was HW accelerated)

For h264, it’s not a big deal but h265 is pretty hard on the cpu

1 Like

It’s an issue because the plex transcoder is an outdated version of ffmpeg. They need to update it to v4+ before enabling NVDEC support. Emby uses a newer version ffmpeg which is why it doesn’t have the issue.

1 Like

Nvdec is new but cuvid is not. It’s been supported in ffmpeg for a long time, well over a year at least and the version plex uses supports it just fine.

If you look at the history of this page, the cuvid mention /discussion goes back over two years: https://trac.ffmpeg.org/wiki/HWAccelIntro

3 Likes

Fair point.

this is useful to see how much GPU is being consumed.

watch -n 0.5 nvidia-smi pmon -c 1

mostly 1080p x264 DTS transcoding down to 720p AAC 5.1/stereo
P2000 and i7 8700


nvtop is useful as well if you haven’t already played with that.

2 Likes

Someone wrote a netdata plugin to graph GPU usage as well. For anyone interested.

2 Likes

Did you get it working?

I’ve been unsuccessful at compiling the repo above, after digging through a dependency hell I cant get past this on a Ubuntu 18.04 LTS Server.

LD	ffmpeg_g
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
Makefile:108: recipe for target 'ffmpeg_g' failed
make: *** [ffmpeg_g] Error 1

anyone got the binary statically compiled yet? we could just share amongst our self until Plex devs get off their rumps and fix this low hanging fruit.

1 Like

@Ryan_Cassidi Can you share a docker image or what you have to get to that far in building ffmpeg? One of us may be able to help get it further.

1 Like

digging through bash history this is wha I got:

apt-get install libx264-dev libx265-dev libswscale-dev nvidia-cuda-dev yasm libnuma-dev libmp3lame-dev git libopus-dev pkg-config
mkdir ~/dev
cd ~/dev
git clone https://github.com/FFmpeg/nv-codec-headers.git
cd nv-codec-headers/
git checkout sdk/8.1
sudo make install PREFIX=/usr
cd ~/dev
git clone https://github.com/galli-leo/FFmpeg.git
cd FFmpeg/
git checkout plex-changes
./configure --disable-bzlib --disable-ffplay --disable-ffprobe --disable-avdevice --disable-schannel --disable-linux-perf --disable-mediacodec --disable-debug --disable-doc --enable-muxers --enable-gpl --enable-version3 --enable-eae --disable-encoders --disable-decoders --disable-hwaccels --enable-libass --disable-devices --disable-lzma --disable-iconv --disable-protocol=concat --enable-libvorbis --enable-libopus --external-decoder=h264 --disable-bsfs --enable-bsf='aac_adtstoasc,extract_extradata,dca_core,h264_mp4toannexb,hevc_mp4toannexb,vp9_superframe,vp9_superframe_split,framedrop' --enable-decoder=png --enable-decoder=apng --enable-decoder=bmp --enable-decoder=mjpeg --enable-decoder=thp --enable-decoder=gif --enable-decoder=dirac --enable-decoder=ffv1 --enable-decoder=ffvhuff --enable-decoder=huffyuv --enable-decoder=rawvideo --enable-decoder=zero12v --enable-decoder=ayuv --enable-decoder=r210 --enable-decoder=v210 --enable-decoder=v210x --enable-decoder=v308 --enable-decoder=v408 --enable-decoder=v410 --enable-decoder=y41p --enable-decoder=yuv4 --enable-decoder=ansi --enable-decoder=alac --enable-decoder=flac --enable-decoder=vorbis --enable-decoder=opus --enable-decoder=pcm_f32be --enable-decoder=pcm_f32le --enable-decoder=pcm_f64be --enable-decoder=pcm_f64le --enable-decoder=pcm_lxf --enable-decoder=pcm_s16be --enable-decoder=pcm_s16be_planar --enable-decoder=pcm_s16le --enable-decoder=pcm_s16le_planar --enable-decoder=pcm_s24be --enable-decoder=pcm_s24le --enable-decoder=pcm_s24le_planar --enable-decoder=pcm_s32be --enable-decoder=pcm_s32le --enable-decoder=pcm_s32le_planar --enable-decoder=pcm_s8 --enable-decoder=pcm_s8_planar --enable-decoder=pcm_u16be --enable-decoder=pcm_u16le --enable-decoder=pcm_u24be --enable-decoder=pcm_u24le --enable-decoder=pcm_u32be --enable-decoder=pcm_u32le --enable-decoder=pcm_u8 --enable-decoder=pcm_alaw --enable-decoder=pcm_mulaw --enable-decoder=ass --enable-decoder=dvbsub --enable-decoder=dvdsub --enable-decoder=ccaption --enable-decoder=pgssub --enable-decoder=jacosub --enable-decoder=microdvd --enable-decoder=movtext --enable-decoder=mpl2 --enable-decoder=pjs --enable-decoder=realtext --enable-decoder=sami --enable-decoder=ssa --enable-decoder=stl --enable-decoder=subrip --enable-decoder=subviewer --enable-decoder=text --enable-decoder=vplayer --enable-decoder=webvtt --enable-decoder=xsub --enable-decoder=eac3_eae --enable-decoder=truehd_eae --enable-decoder=mlp_eae --enable-encoder=flac --enable-encoder=alac --enable-encoder=libvorbis --enable-encoder=libopus --enable-encoder=mjpeg --enable-encoder=wrapped_avframe --enable-encoder=ass --enable-encoder=dvbsub --enable-encoder=dvdsub --enable-encoder=movtext --enable-encoder=ssa --enable-encoder=subrip --enable-encoder=text --enable-encoder=webvtt --enable-encoder=xsub --enable-encoder=pcm_f32be --enable-encoder=pcm_f32le --enable-encoder=pcm_f64be --enable-encoder=pcm_f64le --enable-encoder=pcm_s8 --enable-encoder=pcm_s8_planar --enable-encoder=pcm_s16be --enable-encoder=pcm_s16be_planar --enable-encoder=pcm_s16le --enable-encoder=pcm_s16le_planar --enable-encoder=pcm_s24be --enable-encoder=pcm_s24le --enable-encoder=pcm_s24le_planar --enable-encoder=pcm_s32be --enable-encoder=pcm_s32le --enable-encoder=pcm_s32le_planar --enable-encoder=pcm_u8 --enable-encoder=pcm_u16be --enable-encoder=pcm_u16le --enable-encoder=pcm_u24be --enable-encoder=pcm_u24le --enable-encoder=pcm_u32be --enable-encoder=pcm_u32le --enable-encoder=h264_vaapi --enable-encoder=hevc_vaapi --enable-encoder=h264_nvenc --enable-encoder=eac3_eae --arch=x86_64 --enable-nvenc --enable-nvdec
ulimit -s 65536
make -j <cpu cores>
1 Like

If it helps, this is the specific command that is failing during the make process.

gcc -Llibavcodec -Llibavdevice -Llibavfilter -Llibavformat -Llibavresample -Llibavutil -Llibpostproc -Llibswscale -Llibswresample -Wl,--as-needed -Wl,--gc-sections -Wl,-z,noexecstack -Wl,--warn-common -Wl,-rpath-link=libpostproc:libswresample:libswscale:libavfilter:libavdevice:libavformat:libavcodec:libavutil:libavresample -o ffmpeg_g 
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status

2 Likes

I started a repo here with A docker-compose setup that has the necessary dependencies. When I trya nd use the build.py in the repo I end up getting a segmentation fault. https://github.com/bassrock/FFmpeg/tree/plex-changes-docker Feel free to PR and help get it working!

1 Like

So regard to two comments posted here:

  1. The thought of having Intel QSV doing decode and Nvidia doing encode or vice-a-versa I believe one of the Plex devs mentioned either in this very thread or elsewhere that it was due to not being a direct pipeline staying on the same GPU memory and maintaining high bandwidth. Having to move across the PCIe bus, through the CPU and memory controller therein for the iGPU is going to have vastly reduced bandwidth during this entire transcode process. Now how much of that is going to be a significant issue for basic video transcoding I have no idea and don’t have numbers to go by.

  2. Why using Intel for both is an issue is that you need to have I think either a Skylake or better processor to do 10 bit, HEVC, 4k, or a combination thereof. So if you have even a Haswell family chip, working with 4k HEVC decode is out of the question. Upgrading means pretty much scrapping the entire system when you need a new motherboard, CPU, ram, etc… MUCH cheaper to throw in even a cheap Geforce 950 (which I have and can do 4k HEVC) or 1050.

2 Likes

Instead of using the source code from GitHub that was provided in this post, I looked at the license file and used the download link for my current version of Plex.

licenseFile: /usr/lib/plexmediaserver/Resources/LICENSE
transcoderSource: http://downloads.plex.tv/ffmpeg-source/ffmpeg-2018-03-22.tar.gz

I was able to compile in --enable-decoder=h264_cuvid into that version with ease.

I have not tested it as a replacement yet, but will do so later tonight.

7 Likes

Please update! :star_struck: :raised_hands:t3:

FYI, more recent source can be found here:

1 Like

How do I get plex to call the Plex Transcoder with the appropriate options? Even with cuvid compiled in, it wont use it since Plex Transcoder is being asked to use software h264 decoder specifically.

Would I need to write a wrapper to adjust the settings, or is there something I am missing?

1 Like