Which nvidia card for transcoding nvenc/265? (ts-877)

DLNA, AirPlay, Chromecast, PS3, XBOX, iTunes, & other media players
User avatar
dolbyman
Guru
Posts: 35216
Joined: Sat Feb 12, 2011 2:11 am
Location: Vancouver BC , Canada

Re: Which nvidia card for transcoding nvenc/265? (ts-877)

Post by dolbyman »

the formats I knew ..just quality I wasnt sure with your "nuff said"

I am waiting for plex to support tonemapping on hdr to sdr transcoding ..that way I could have one file base for all my players (hdr only) right now hdr transcoding results in washed out colors..

hope the cpu usage is not too high for the tonemapping (or could even be done in shader hardware) otherwise I am sol with that slow celeron
User avatar
jaysona
Been there, done that
Posts: 854
Joined: Tue Dec 02, 2008 11:26 am
Location: Somewhere in the Great White North

Re: Which nvidia card for transcoding nvenc/265? (ts-877)

Post by jaysona »

dolbyman wrote: Tue May 19, 2020 7:24 am the formats I knew ..just quality I wasnt sure with your "nuff said"

I am waiting for plex to support tonemapping on hdr to sdr transcoding ..that way I could have one file base for all my players (hdr only) right now hdr transcoding results in washed out colors..

hope the cpu usage is not too high for the tonemapping (or could even be done in shader hardware) otherwise I am sol with that slow celeron
I'm not sure if you have been following this thread or not
https://forums.plex.tv/t/info-plex-4k-t ... -4k/378203

But, I would not hold my breath, and if/when it done come out, the Celeron will most likely be far too pokey to handle such a task. :|
RAID is not a Back-up!

H/W: QNAP TVS-871 (i7-4790. 16GB) (Plex server) / TVS-EC1080 (32Gig ECC) - VM host & seedbox
H/W: Asustor AS6604T (8GB) / Asustor AS7010T (16GB) (media storage)
H/W: TS-219 Pro / TS-509 Pro
O/S: Slackware 14.2 / MS Windows 7-64 (x5)
Router1: Asus RT-AC86U - Asuswrt-Merlin - 386.7_2
Router2: Asus RT-AC68U - Asuswrt-Merlin - 386.7_2
Router3: Linksys WRT1900AC - DD-WRT v3.0-r46816 std
Router4: Asus RT-AC66U - FreshTomato v2021.10.15

Misc: Popcorn Hour A-110/WN-100, Pinnacle Show Center 250HD, Roku SoundBridge Radio (all retired)
Ditched QNAP units: TS-269 Pro / TS-253 Pro (8GB) / TS-509 Pro / TS-569 Pro / TS-853 Pro (8GB)
TS-670 Pro x2 (i7-3770s 16GB) / TS-870 Pro (i7-3770 16GB) / TVS-871 (i7-4790s 16GB)
gggplaya
Been there, done that
Posts: 747
Joined: Wed Apr 20, 2016 10:05 pm

Re: Which nvidia card for transcoding nvenc/265? (ts-877)

Post by gggplaya »

jaysona wrote: Tue May 19, 2020 6:09 am
gggplaya wrote: Tue May 19, 2020 5:46 am Intel Quicksync looks the WORST in terms of video encoding. It's a blocky mess. Here's the order from best to worst looking CPU>Nvidia Turing > Nvidia Pascal/Volta > AMD VCE > Intel Quicksync. I tried Intel Quicksync with my 451+ NAS and 4570T intel processor in my thin desktop. It looked awful and was what turned me onto CPU transcoding instead, it's a night and day difference especially at low bitrates and fast moving scenes. If all your playback is at high bitrates inside the home, you might be OK. But if you're playback is remote at 4 or 8mbps, it's a blocky mess. Nvidia Turing H.264 encoding looks only a little worse than CPU encoding and Nvidia Turing H.265 encoding(not plex) looks very very close to CPU transcoding. Intel transcoding looks terrible, you can try it for yourself and compare the same movie against CPU transcoding.

The OP has a 6 or 8 core ryzen processor, he should be able to handle 4-6 full 1080p transcodes without issue and look the best doing it. An Nvidia GPU will only do 2 transcodes unless you find the workaround hack for it or buy a Quadro card.
Over the past four years, I have not had and complaints or experienced any issues with quicksync and have never noticed any blockiness, even when sitting less than 2m from the screen which is 65" sin size. All my files are .x264 as that is the the only type Ivy Bride/Haswell can decode in hardware.

At some point as h.265 becomes more prevalent, I'll upgrade to a Coffee Lake or Ice Lake CPU, but I have still a couple of years, at least before that'll be necessary.

In my case plex does not need to perform any encoding, only decoding, as most of the players have issues with mkv, so the video file is decoded and streamed to the player as either MPEGTS or MP4.

Plex should never need to perform any sort of encoding, except in the case of a player not being able to play a VP8/9 or HEVC file for example. In that case I always re-encode my files using ffmpeg or similar tool first before making it available on plex.

Most people won't know any better unless they've seen both. They probably think macroblocking over the internet is normal.

You have to understand why GPU encoding is so much quicker. It uses a technique called macroblocking which breaks the screen into blocks and analyzes changes in each block as they move to the next frame. Blocks that have changes will be re-encoded, blocks that don't have changes will be transposed over. This significantly speeds up encoding, and since it's performing the same task over and over, you can design an ASIC to perform exactly that and bake it into the silicon of the GPU. The downside is during faster panning and high motion scenes, you'll see blockiness in the scene.

You can try it for yourself by artificially setting your TV to play a lower bitrate than your movie, say you have a 10mbps movie, you can set your tv to 4mbps. Then enable and disable the hardware transcoding option on your plex server. You'll see the macroblocking taking effect when gpu transcoding but be much clearer when it's just the CPU. Normally you won't notice this as much inside your home because plex is default set to 20mbps transcoding inside the house. GPU transcoding normally needs much higher bitrate to achieve the same results as cpu transcoding.
User avatar
jaysona
Been there, done that
Posts: 854
Joined: Tue Dec 02, 2008 11:26 am
Location: Somewhere in the Great White North

Re: Which nvidia card for transcoding nvenc/265? (ts-877)

Post by jaysona »

gggplaya wrote: Tue May 19, 2020 8:14 am Most people won't know any better unless they've seen both. They probably think macroblocking over the internet is normal.

You have to understand why GPU encoding is so much quicker. It uses a technique called macroblocking which breaks the screen into blocks and analyzes changes in each block as they move to the next frame. Blocks that have changes will be re-encoded, blocks that don't have changes will be transposed over. This significantly speeds up encoding, and since it's performing the same task over and over, you can design an ASIC to perform exactly that and bake it into the silicon of the GPU. The downside is during faster panning and high motion scenes, you'll see blockiness in the scene.

You can try it for yourself by artificially setting your TV to play a lower bitrate than your movie, say you have a 10mbps movie, you can set your tv to 4mbps. Then enable and disable the hardware transcoding option on your plex server. You'll see the macroblocking taking effect when gpu transcoding but be much clearer when it's just the CPU. Normally you won't notice this as much inside your home because plex is default set to 20mbps transcoding inside the house. GPU transcoding normally needs much higher bitrate to achieve the same results as cpu transcoding.
I used to work for the green goblin, I am quite familiar with how GPU and GPGPU's work. ;)

As for bitrates, my external players are set to play original/quality maximum quality, that's just one of the many upsides to having Gigabit Internet access, and as such, my monthly upload is typically in the range on 18TB - 25TB/mo. ;)

As for my plex server, no GPU, just a decent Intel CPU with Quick Sync enabled and a local restaurant uses Plex on their 72" tv to play movies, and I have never noticed any blockiness when movies are played back.
RAID is not a Back-up!

H/W: QNAP TVS-871 (i7-4790. 16GB) (Plex server) / TVS-EC1080 (32Gig ECC) - VM host & seedbox
H/W: Asustor AS6604T (8GB) / Asustor AS7010T (16GB) (media storage)
H/W: TS-219 Pro / TS-509 Pro
O/S: Slackware 14.2 / MS Windows 7-64 (x5)
Router1: Asus RT-AC86U - Asuswrt-Merlin - 386.7_2
Router2: Asus RT-AC68U - Asuswrt-Merlin - 386.7_2
Router3: Linksys WRT1900AC - DD-WRT v3.0-r46816 std
Router4: Asus RT-AC66U - FreshTomato v2021.10.15

Misc: Popcorn Hour A-110/WN-100, Pinnacle Show Center 250HD, Roku SoundBridge Radio (all retired)
Ditched QNAP units: TS-269 Pro / TS-253 Pro (8GB) / TS-509 Pro / TS-569 Pro / TS-853 Pro (8GB)
TS-670 Pro x2 (i7-3770s 16GB) / TS-870 Pro (i7-3770 16GB) / TVS-871 (i7-4790s 16GB)
User avatar
dolbyman
Guru
Posts: 35216
Joined: Sat Feb 12, 2011 2:11 am
Location: Vancouver BC , Canada

Re: Which nvidia card for transcoding nvenc/265? (ts-877)

Post by dolbyman »

there is always a chance they implement offline transcoding with tonemapping at one point ..for now I just keep multiple versions if hdr is present
gggplaya
Been there, done that
Posts: 747
Joined: Wed Apr 20, 2016 10:05 pm

Re: Which nvidia card for transcoding nvenc/265? (ts-877)

Post by gggplaya »

jaysona wrote: Tue May 19, 2020 8:27 am
gggplaya wrote: Tue May 19, 2020 8:14 am Most people won't know any better unless they've seen both. They probably think macroblocking over the internet is normal.

You have to understand why GPU encoding is so much quicker. It uses a technique called macroblocking which breaks the screen into blocks and analyzes changes in each block as they move to the next frame. Blocks that have changes will be re-encoded, blocks that don't have changes will be transposed over. This significantly speeds up encoding, and since it's performing the same task over and over, you can design an ASIC to perform exactly that and bake it into the silicon of the GPU. The downside is during faster panning and high motion scenes, you'll see blockiness in the scene.

You can try it for yourself by artificially setting your TV to play a lower bitrate than your movie, say you have a 10mbps movie, you can set your tv to 4mbps. Then enable and disable the hardware transcoding option on your plex server. You'll see the macroblocking taking effect when gpu transcoding but be much clearer when it's just the CPU. Normally you won't notice this as much inside your home because plex is default set to 20mbps transcoding inside the house. GPU transcoding normally needs much higher bitrate to achieve the same results as cpu transcoding.
I used to work for the green goblin, I am quite familiar with how GPU and GPGPU's work. ;)

As for bitrates, my external players are set to play original/quality maximum quality, that's just one of the many upsides to having Gigabit Internet access, and as such, my monthly upload is typically in the range on 18TB - 25TB/mo. ;)

As for my plex server, no GPU, just a decent Intel CPU with Quick Sync enabled and a local restaurant uses Plex on their 72" tv to play movies, and I have never noticed any blockiness when movies are played back.
Actually, Quicksync is part of the GPU built into the Intel CPU. They call it an iGPU.

If you have gigabit upload, than that's really not much different than being local. Lucky you, but most of us don't have that luxury. If you can play movies with GPU encoding at high bitrate(original max quality), it will look fine. Actually for most of your movies, it's only transcoding the container or direct play since you have full bandwdith. Not actually transcoding the video because most modern tv's and client devices support h.264 and h.265 HEVC, they just have certain container restrictions.

I only have 10mbps upload. Half my stuff is higher bitrate than that. So they require transcoding no matter what when playing remotely. Even at 8mbps, CPU transcoding looks drastically better than quicksync.
User avatar
jaysona
Been there, done that
Posts: 854
Joined: Tue Dec 02, 2008 11:26 am
Location: Somewhere in the Great White North

Re: Which nvidia card for transcoding nvenc/265? (ts-877)

Post by jaysona »

gggplaya wrote: Tue May 19, 2020 10:07 am Actually, Quicksync is part of the GPU built into the Intel CPU. They call it an iGPU.
Actually, no! Quick Sync is not part of the GPU, just because the Quick Sync hardware is located in the same area as the GPU does not make Quick Sync part of the GPU. The Quick Sync hardware is a separate purpose designed SIP core (hardware) whose sole function is for decoding and encoding certain types of media streams, same with NVENC. The proprietary OEM drivers determine the available functions and features available for their respective decoding/encoding. The green goblin is far more aggressive (in terms of the money charged) in their pricing and licensing than Intel.

Both Quick Sync and NVENC do not use any of the GPU shaders, ROPs, ALUs, etc. The "i" in iGPU is just a generic term for "Integrated" for nearly discrete GPU included in the same package as a CPU, AMD calls theirs an APU, and Intel decided the use the "i"for whatever marketing reasons they did back in the day.
gggplaya wrote: Tue May 19, 2020 10:07 am If you have gigabit upload, than that's really not much different than being local. Lucky you, but most of us don't have that luxury. If you can play movies with GPU encoding at high bitrate(original max quality), it will look fine. Actually for most of your movies, it's only transcoding the container or direct play since you have full bandwdith. Not actually transcoding the video because most modern tv's and client devices support h.264 and h.265 HEVC, they just have certain container restrictions.

I only have 10mbps upload. Half my stuff is higher bitrate than that. So they require transcoding no matter what when playing remotely. Even at 8mbps, CPU transcoding looks drastically better than quicksync.
Most of the remote players are Roku sticks, Playstation and Amazon Fire Stick, almost all of which require some level of transcoding, for what ever reasons. Transcoding seems to be quite common with x.264 AMZN.WEB-DL tv shows, the only player I have seen that is capable of direct play is the Amazon Fire Stick 4K, except when PGS subs are displayed, then transcoding is needed due to burning on the subs, which is why I try to get external srt subs for all the video files as necessary.

Transcoding 13 streams (even if just container) will have my CPU pinned above 90%, with Quick Sync the cpu rarely goes above 5% for those same 13 streams and quality looks the same as if it were being played locally.
RAID is not a Back-up!

H/W: QNAP TVS-871 (i7-4790. 16GB) (Plex server) / TVS-EC1080 (32Gig ECC) - VM host & seedbox
H/W: Asustor AS6604T (8GB) / Asustor AS7010T (16GB) (media storage)
H/W: TS-219 Pro / TS-509 Pro
O/S: Slackware 14.2 / MS Windows 7-64 (x5)
Router1: Asus RT-AC86U - Asuswrt-Merlin - 386.7_2
Router2: Asus RT-AC68U - Asuswrt-Merlin - 386.7_2
Router3: Linksys WRT1900AC - DD-WRT v3.0-r46816 std
Router4: Asus RT-AC66U - FreshTomato v2021.10.15

Misc: Popcorn Hour A-110/WN-100, Pinnacle Show Center 250HD, Roku SoundBridge Radio (all retired)
Ditched QNAP units: TS-269 Pro / TS-253 Pro (8GB) / TS-509 Pro / TS-569 Pro / TS-853 Pro (8GB)
TS-670 Pro x2 (i7-3770s 16GB) / TS-870 Pro (i7-3770 16GB) / TVS-871 (i7-4790s 16GB)
gggplaya
Been there, done that
Posts: 747
Joined: Wed Apr 20, 2016 10:05 pm

Re: Which nvidia card for transcoding nvenc/265? (ts-877)

Post by gggplaya »

jaysona wrote: Tue May 19, 2020 10:49 am
gggplaya wrote: Tue May 19, 2020 10:07 am Actually, Quicksync is part of the GPU built into the Intel CPU. They call it an iGPU.
Actually, no! Quick Sync is not part of the GPU, just because the Quick Sync hardware is located in the same area as the GPU does not make Quick Sync part of the GPU. The Quick Sync hardware is a separate purpose designed SIP core (hardware) whose sole function is for decoding and encoding certain types of media streams, same with NVENC. The proprietary OEM drivers determine the available functions and features available for their respective decoding/encoding. The green goblin is far more aggressive (in terms of the money charged) in their pricing and licensing than Intel.

Both Quick Sync and NVENC do not use any of the GPU shaders, ROPs, ALUs, etc. The "i" in iGPU is just a generic term for "Integrated" for nearly discrete GPU included in the same package as a CPU, AMD calls theirs an APU, and Intel decided the use the "i"for whatever marketing reasons they did back in the day.
gggplaya wrote: Tue May 19, 2020 10:07 am If you have gigabit upload, than that's really not much different than being local. Lucky you, but most of us don't have that luxury. If you can play movies with GPU encoding at high bitrate(original max quality), it will look fine. Actually for most of your movies, it's only transcoding the container or direct play since you have full bandwdith. Not actually transcoding the video because most modern tv's and client devices support h.264 and h.265 HEVC, they just have certain container restrictions.

I only have 10mbps upload. Half my stuff is higher bitrate than that. So they require transcoding no matter what when playing remotely. Even at 8mbps, CPU transcoding looks drastically better than quicksync.
Most of the remote players are Roku sticks, Playstation and Amazon Fire Stick, almost all of which require some level of transcoding, for what ever reasons. Transcoding seems to be quite common with x.264 AMZN.WEB-DL tv shows, the only player I have seen that is capable of direct play is the Amazon Fire Stick 4K, except when PGS subs are displayed, then transcoding is needed due to burning on the subs, which is why I try to get external srt subs for all the video files as necessary.

Transcoding 13 streams (even if just container) will have my CPU pinned above 90%, with Quick Sync the cpu rarely goes above 5% for those same 13 streams and quality looks the same as if it were being played locally.

The QuickSync video decode/encode SIP block is baked into the GPU portion of Intel chips. It's why there's no difference in GPU encoding with a 1050ti vs a 1080ti. They have the same quicksync SIP block. Intel F/KF series processors have their GPU disabled, and therefore have no quicksync. If quicksync were separate from the GPU, it would still work. Yes, technically it's a specific block in the GPU that does the transcoding, but the generally used vernacular is to say "GPU transcode."
Image


I don't have a playstation, but I know for Roku and the Firestick, most of the time it only transcodes the container, not the actual video. Most subtitles are text based and won't need transcoding unless you use image based subtitles. CPU usage is very low. But like I said, try quicksync at lower bitrates and compare it to CPU transcoding, you'll see what I'm talking about.

Once Plex embraces HEVC output or similar codec, i'll probably switch to Nvidia's Turing or better GPU. Their h.265 NVENC looks extremely close to CPU encoding even at lower bitrates. H.264 still looks worse than CPU encoding, so i'll stick with what I have for now.
lalaw
New here
Posts: 6
Joined: Wed Dec 12, 2018 6:52 am

Re: Which nvidia card for transcoding nvenc/265? (ts-877)

Post by lalaw »

spikemixture wrote: Sat Apr 25, 2020 1:08 pm Looks like wmadoss has no answer - or anyone else..

Yes I know it can be done on a win10 machine but this is a QNAP Forum.....
So, big YMMV on this, but I actually just hacked the script from https://github.com/keylase/nvidia-patch and it seems to work on my TS-1277.

Here's the modified version:

Code: Select all

#!/bin/bash
# halt on any error for safety and proper pipe handling
set -euo pipefail ; # <- this semicolon and comment make options apply
# even when script is corrupt by CRLF line terminators (issue #75)
# empty line must follow this comment for immediate fail with CRLF newlines

backup_path="/share/CACHEDEV1_DATA/.qpkg/NVIDIA_GPU_DRV/usr/nvidia/libnvidia-encode-backup"
silent_flag=''

print_usage() { printf '
SYNOPSIS
       patch.sh [-s] [-r|-h|-c VERSION|-l]

DESCRIPTION
       The patch for Nvidia drivers to remove NVENC session limit

       -s             Silent mode (No output)
       -r             Rollback to original (Restore lib from backup)
       -h             Print this help message
       -c VERSION     Check if version VERSION supported by this patch.
                      Returns true exit code (0) if version is supported.
       -l             List supported driver versions

'
}

# shellcheck disable=SC2209
opmode="patch"

while getopts 'rshc:l' flag; do
    case "${flag}" in
        r) opmode="${opmode}rollback" ;;
        s) silent_flag='true' ;;
        h) opmode="${opmode}help" ;;
        c) opmode="${opmode}checkversion" ; checked_version="$OPTARG" ;;
        l) opmode="${opmode}listversions" ;;
        *) echo "Incorrect option specified in command line" ; exit 2 ;;
    esac
done

if [[ $silent_flag ]]; then
    exec 1> /dev/null
fi

patch='s/\x00\x00\x00\x84\xc0\x0f\x84\x40\xfd\xff\xff/\x00\x00\x00\x84\xc0\x90\x90\x90\x90\x90\x90/g'

object='libnvcuvid.so'

check_version_supported () {
    local ver="$1"
    [[ 1 ]]
}

get_supported_versions () {
    return 0
}

patch_common () {
    NVIDIA_SMI="$(command -v /share/CACHEDEV1_DATA/.qpkg/NVIDIA_GPU_DRV/usr/bin/nvidia-smi || true)"
    if [[ ! "$NVIDIA_SMI" ]] ; then
        echo 'nvidia-smi utility not found. Probably driver is not installed.'
        exit 1
    fi

    ret_code=$?
    driver_version="418.56"
    if [[ $ret_code -ne 0 ]] ; then
        echo "Can not detect nvidia driver version."
        echo "CMD: \"$cmd\""
        echo "Result: \"$driver_versions_list\""
        echo "nvidia-smi retcode: $ret_code"
        exit 1
    fi

    echo "Detected nvidia driver version: $driver_version"

    if ! check_version_supported "$driver_version" ; then
        echo "Patch for this ($driver_version) nvidia driver not found."
        echo "Patch is available for versions: "
        get_supported_versions
        exit 1
    fi

    patch='s/\x00\x00\x00\x84\xc0\x0f\x84\x40\xfd\xff\xff/\x00\x00\x00\x84\xc0\x90\x90\x90\x90\x90\x90/g'

    object='libnvcuvid.so'

    declare -a driver_locations=(
        '/share/CACHEDEV1_DATA/.qpkg/NVIDIA_GPU_DRV/usr/lib'
	'/share/CACHEDEV1_DATA/.qpkg/NVIDIA_GPU_DRV/usr/nvidia'
	'/share/CACHEDEV1_DATA/.qpkg/NVIDIA_GPU_DRV/usr/nvidia.u18.04'
        "/share/CACHEDEV1_DATA/.qpkg/NVIDIA_GPU_DRV/usr/lib/nvidia-${driver_version%%.*}"
    )

    dir_found=''
    for driver_dir in "${driver_locations[@]}" ; do
        if [[ -e "$driver_dir/$object.$driver_version" ]]; then
            dir_found='true'
            break
        fi
    done

    [[ "$dir_found" ]] || { echo "ERROR: cannot detect driver directory"; exit 1; }

}

rollback () {
    patch_common
    if [[ -f "$backup_path/$object.$driver_version" ]]; then
        cp -p "$backup_path/$object.$driver_version" \
           "$driver_dir/$object.$driver_version"
        echo "Restore from backup $object.$driver_version"
    else
        echo "Backup not found. Try to patch first."
        exit 1
    fi
}

patch () {
    patch_common
    if [[ -f "$backup_path/$object.$driver_version" ]]; then
        bkp_hash="$(sha1sum "$backup_path/$object.$driver_version" | cut -f1 -d\ )"
        drv_hash="$(sha1sum "$driver_dir/$object.$driver_version" | cut -f1 -d\ )"
        if [[ "$bkp_hash" != "$drv_hash" ]] ; then
            echo "Backup exists and driver file differ from backup. Skipping patch."
            return 0
        fi
    else
        echo "Attention! Backup not found. Copying current $object to backup."
        mkdir -p "$backup_path"
        cp -p "$driver_dir/$object.$driver_version" \
           "$backup_path/$object.$driver_version"
    fi
    sha1sum "$backup_path/$object.$driver_version"
    sed "$patch" "$backup_path/$object.$driver_version" > \
      "${PATCH_OUTPUT_DIR-$driver_dir}/$object.$driver_version"
    sha1sum "${PATCH_OUTPUT_DIR-$driver_dir}/$object.$driver_version"
    ldconfig
    echo "Patched!"
}

query_version_support () {
    if check_version_supported "$checked_version" ; then
        echo "SUPPORTED"
        exit 0
    else
        echo "NOT SUPPORTED"
        exit 1
    fi
}

list_supported_versions () {
    get_supported_versions
}

case "${opmode}" in

    patch) patch ;;
    patchrollback) rollback ;;
    patchhelp) print_usage ; exit 2 ;;
    patchcheckversion) query_version_support ;;
    patchlistversions) list_supported_versions ;;
    *) echo "Incorrect combination of flags. Use option -h to get help."
       exit 2 ;;
esac

Summary of changes:
1. Changed some paths around to support the weird location of the Nvidia GPU driver.
2. bash was throwing errors with the default Hash table, so I ended up having to hard-code the driver version.
3. Had to update references to the above hash tables to instead use my hard coded patch and object.

Anyway, big hack, but it seems to work for me. It will probably work for you if your drivers are installed in a similar location and are at the same level.
ilboss841
Starting out
Posts: 11
Joined: Thu May 28, 2020 1:04 am

Re: Which nvidia card for transcoding nvenc/265? (ts-877)

Post by ilboss841 »

lalaw wrote: Thu Jun 25, 2020 6:34 am
Here's the modified version:

Code: Select all

#!/bin/bash
# halt on any error for safety and proper pipe handling
set -euo pipefail ; # <- this semicolon and comment make options apply
# even when script is corrupt by CRLF line terminators (issue #75)
# empty line must follow this comment for immediate fail with CRLF newlines

backup_path="/share/CACHEDEV1_DATA/.qpkg/NVIDIA_GPU_DRV/usr/nvidia/libnvidia-encode-backup"
silent_flag=''

print_usage() { printf '
SYNOPSIS
       patch.sh [-s] [-r|-h|-c VERSION|-l]

DESCRIPTION
       The patch for Nvidia drivers to remove NVENC session limit

       -s             Silent mode (No output)
       -r             Rollback to original (Restore lib from backup)
       -h             Print this help message
       -c VERSION     Check if version VERSION supported by this patch.
                      Returns true exit code (0) if version is supported.
       -l             List supported driver versions

'
}

# shellcheck disable=SC2209
opmode="patch"

while getopts 'rshc:l' flag; do
    case "${flag}" in
        r) opmode="${opmode}rollback" ;;
        s) silent_flag='true' ;;
        h) opmode="${opmode}help" ;;
        c) opmode="${opmode}checkversion" ; checked_version="$OPTARG" ;;
        l) opmode="${opmode}listversions" ;;
        *) echo "Incorrect option specified in command line" ; exit 2 ;;
    esac
done

if [[ $silent_flag ]]; then
    exec 1> /dev/null
fi

patch='s/\x00\x00\x00\x84\xc0\x0f\x84\x40\xfd\xff\xff/\x00\x00\x00\x84\xc0\x90\x90\x90\x90\x90\x90/g'

object='libnvcuvid.so'

check_version_supported () {
    local ver="$1"
    [[ 1 ]]
}

get_supported_versions () {
    return 0
}

patch_common () {
    NVIDIA_SMI="$(command -v /share/CACHEDEV1_DATA/.qpkg/NVIDIA_GPU_DRV/usr/bin/nvidia-smi || true)"
    if [[ ! "$NVIDIA_SMI" ]] ; then
        echo 'nvidia-smi utility not found. Probably driver is not installed.'
        exit 1
    fi

    ret_code=$?
    driver_version="418.56"
    if [[ $ret_code -ne 0 ]] ; then
        echo "Can not detect nvidia driver version."
        echo "CMD: \"$cmd\""
        echo "Result: \"$driver_versions_list\""
        echo "nvidia-smi retcode: $ret_code"
        exit 1
    fi

    echo "Detected nvidia driver version: $driver_version"

    if ! check_version_supported "$driver_version" ; then
        echo "Patch for this ($driver_version) nvidia driver not found."
        echo "Patch is available for versions: "
        get_supported_versions
        exit 1
    fi

    patch='s/\x00\x00\x00\x84\xc0\x0f\x84\x40\xfd\xff\xff/\x00\x00\x00\x84\xc0\x90\x90\x90\x90\x90\x90/g'

    object='libnvcuvid.so'

    declare -a driver_locations=(
        '/share/CACHEDEV1_DATA/.qpkg/NVIDIA_GPU_DRV/usr/lib'
	'/share/CACHEDEV1_DATA/.qpkg/NVIDIA_GPU_DRV/usr/nvidia'
	'/share/CACHEDEV1_DATA/.qpkg/NVIDIA_GPU_DRV/usr/nvidia.u18.04'
        "/share/CACHEDEV1_DATA/.qpkg/NVIDIA_GPU_DRV/usr/lib/nvidia-${driver_version%%.*}"
    )

    dir_found=''
    for driver_dir in "${driver_locations[@]}" ; do
        if [[ -e "$driver_dir/$object.$driver_version" ]]; then
            dir_found='true'
            break
        fi
    done

    [[ "$dir_found" ]] || { echo "ERROR: cannot detect driver directory"; exit 1; }

}

rollback () {
    patch_common
    if [[ -f "$backup_path/$object.$driver_version" ]]; then
        cp -p "$backup_path/$object.$driver_version" \
           "$driver_dir/$object.$driver_version"
        echo "Restore from backup $object.$driver_version"
    else
        echo "Backup not found. Try to patch first."
        exit 1
    fi
}

patch () {
    patch_common
    if [[ -f "$backup_path/$object.$driver_version" ]]; then
        bkp_hash="$(sha1sum "$backup_path/$object.$driver_version" | cut -f1 -d\ )"
        drv_hash="$(sha1sum "$driver_dir/$object.$driver_version" | cut -f1 -d\ )"
        if [[ "$bkp_hash" != "$drv_hash" ]] ; then
            echo "Backup exists and driver file differ from backup. Skipping patch."
            return 0
        fi
    else
        echo "Attention! Backup not found. Copying current $object to backup."
        mkdir -p "$backup_path"
        cp -p "$driver_dir/$object.$driver_version" \
           "$backup_path/$object.$driver_version"
    fi
    sha1sum "$backup_path/$object.$driver_version"
    sed "$patch" "$backup_path/$object.$driver_version" > \
      "${PATCH_OUTPUT_DIR-$driver_dir}/$object.$driver_version"
    sha1sum "${PATCH_OUTPUT_DIR-$driver_dir}/$object.$driver_version"
    ldconfig
    echo "Patched!"
}

query_version_support () {
    if check_version_supported "$checked_version" ; then
        echo "SUPPORTED"
        exit 0
    else
        echo "NOT SUPPORTED"
        exit 1
    fi
}

list_supported_versions () {
    get_supported_versions
}

case "${opmode}" in

    patch) patch ;;
    patchrollback) rollback ;;
    patchhelp) print_usage ; exit 2 ;;
    patchcheckversion) query_version_support ;;
    patchlistversions) list_supported_versions ;;
    *) echo "Incorrect combination of flags. Use option -h to get help."
       exit 2 ;;
esac

Summary of changes:
1. Changed some paths around to support the weird location of the Nvidia GPU driver.
2. bash was throwing errors with the default Hash table, so I ended up having to hard-code the driver version.
3. Had to update references to the above hash tables to instead use my hard coded patch and object.

Anyway, big hack, but it seems to work for me. It will probably work for you if your drivers are installed in a similar location and are at the same level.
Very interesting this hack, it would be oxygen for me to be able to use at least 4 video transcoding with my nvidia 1050ti, I tried to follow your instructions but I haven't managed to make it work for now.
Question since already on windows now video transcoding has gone from 2 to 3 simultaneous streams, will an update on qts qnap happen?
User avatar
peelos
Been there, done that
Posts: 580
Joined: Sun Jun 26, 2016 9:28 pm

Re: Which nvidia card for transcoding nvenc/265? (ts-877)

Post by peelos »

lalaw wrote:
spikemixture wrote: Sat Apr 25, 2020 1:08 pm Looks like wmadoss has no answer - or anyone else..

Yes I know it can be done on a win10 machine but this is a QNAP Forum.....
So, big YMMV on this, but I actually just hacked the script from https://github.com/keylase/nvidia-patch and it seems to work on my TS-1277.

Here's the modified version:

Code: Select all

#!/bin/bash
# halt on any error for safety and proper pipe handling
set -euo pipefail ; # <- this semicolon and comment make options apply
# even when script is corrupt by CRLF line terminators (issue #75)
# empty line must follow this comment for immediate fail with CRLF newlines

backup_path="/share/CACHEDEV1_DATA/.qpkg/NVIDIA_GPU_DRV/usr/nvidia/libnvidia-encode-backup"
silent_flag=''

print_usage() { printf '
SYNOPSIS
       patch.sh [-s] [-r|-h|-c VERSION|-l]

DESCRIPTION
       The patch for Nvidia drivers to remove NVENC session limit

       -s             Silent mode (No output)
       -r             Rollback to original (Restore lib from backup)
       -h             Print this help message
       -c VERSION     Check if version VERSION supported by this patch.
                      Returns true exit code (0) if version is supported.
       -l             List supported driver versions

'
}

# shellcheck disable=SC2209
opmode="patch"

while getopts 'rshc:l' flag; do
    case "${flag}" in
        r) opmode="${opmode}rollback" ;;
        s) silent_flag='true' ;;
        h) opmode="${opmode}help" ;;
        c) opmode="${opmode}checkversion" ; checked_version="$OPTARG" ;;
        l) opmode="${opmode}listversions" ;;
        *) echo "Incorrect option specified in command line" ; exit 2 ;;
    esac
done

if [[ $silent_flag ]]; then
    exec 1> /dev/null
fi

patch='s/\x00\x00\x00\x84\xc0\x0f\x84\x40\xfd\xff\xff/\x00\x00\x00\x84\xc0\x90\x90\x90\x90\x90\x90/g'

object='libnvcuvid.so'

check_version_supported () {
    local ver="$1"
    [[ 1 ]]
}

get_supported_versions () {
    return 0
}

patch_common () {
    NVIDIA_SMI="$(command -v /share/CACHEDEV1_DATA/.qpkg/NVIDIA_GPU_DRV/usr/bin/nvidia-smi || true)"
    if [[ ! "$NVIDIA_SMI" ]] ; then
        echo 'nvidia-smi utility not found. Probably driver is not installed.'
        exit 1
    fi

    ret_code=$?
    driver_version="418.56"
    if [[ $ret_code -ne 0 ]] ; then
        echo "Can not detect nvidia driver version."
        echo "CMD: \"$cmd\""
        echo "Result: \"$driver_versions_list\""
        echo "nvidia-smi retcode: $ret_code"
        exit 1
    fi

    echo "Detected nvidia driver version: $driver_version"

    if ! check_version_supported "$driver_version" ; then
        echo "Patch for this ($driver_version) nvidia driver not found."
        echo "Patch is available for versions: "
        get_supported_versions
        exit 1
    fi

    patch='s/\x00\x00\x00\x84\xc0\x0f\x84\x40\xfd\xff\xff/\x00\x00\x00\x84\xc0\x90\x90\x90\x90\x90\x90/g'

    object='libnvcuvid.so'

    declare -a driver_locations=(
        '/share/CACHEDEV1_DATA/.qpkg/NVIDIA_GPU_DRV/usr/lib'
	'/share/CACHEDEV1_DATA/.qpkg/NVIDIA_GPU_DRV/usr/nvidia'
	'/share/CACHEDEV1_DATA/.qpkg/NVIDIA_GPU_DRV/usr/nvidia.u18.04'
        "/share/CACHEDEV1_DATA/.qpkg/NVIDIA_GPU_DRV/usr/lib/nvidia-${driver_version%%.*}"
    )

    dir_found=''
    for driver_dir in "${driver_locations[@]}" ; do
        if [[ -e "$driver_dir/$object.$driver_version" ]]; then
            dir_found='true'
            break
        fi
    done

    [[ "$dir_found" ]] || { echo "ERROR: cannot detect driver directory"; exit 1; }

}

rollback () {
    patch_common
    if [[ -f "$backup_path/$object.$driver_version" ]]; then
        cp -p "$backup_path/$object.$driver_version" \
           "$driver_dir/$object.$driver_version"
        echo "Restore from backup $object.$driver_version"
    else
        echo "Backup not found. Try to patch first."
        exit 1
    fi
}

patch () {
    patch_common
    if [[ -f "$backup_path/$object.$driver_version" ]]; then
        bkp_hash="$(sha1sum "$backup_path/$object.$driver_version" | cut -f1 -d\ )"
        drv_hash="$(sha1sum "$driver_dir/$object.$driver_version" | cut -f1 -d\ )"
        if [[ "$bkp_hash" != "$drv_hash" ]] ; then
            echo "Backup exists and driver file differ from backup. Skipping patch."
            return 0
        fi
    else
        echo "Attention! Backup not found. Copying current $object to backup."
        mkdir -p "$backup_path"
        cp -p "$driver_dir/$object.$driver_version" \
           "$backup_path/$object.$driver_version"
    fi
    sha1sum "$backup_path/$object.$driver_version"
    sed "$patch" "$backup_path/$object.$driver_version" > \
      "${PATCH_OUTPUT_DIR-$driver_dir}/$object.$driver_version"
    sha1sum "${PATCH_OUTPUT_DIR-$driver_dir}/$object.$driver_version"
    ldconfig
    echo "Patched!"
}

query_version_support () {
    if check_version_supported "$checked_version" ; then
        echo "SUPPORTED"
        exit 0
    else
        echo "NOT SUPPORTED"
        exit 1
    fi
}

list_supported_versions () {
    get_supported_versions
}

case "${opmode}" in

    patch) patch ;;
    patchrollback) rollback ;;
    patchhelp) print_usage ; exit 2 ;;
    patchcheckversion) query_version_support ;;
    patchlistversions) list_supported_versions ;;
    *) echo "Incorrect combination of flags. Use option -h to get help."
       exit 2 ;;
esac

Summary of changes:
1. Changed some paths around to support the weird location of the Nvidia GPU driver.
2. bash was throwing errors with the default Hash table, so I ended up having to hard-code the driver version.
3. Had to update references to the above hash tables to instead use my hard coded patch and object.

Anyway, big hack, but it seems to work for me. It will probably work for you if your drivers are installed in a similar location and are at the same level.
Many thanks, is this still working? Presume it will need running again or adapting if new nvidia drivers are released in future?
NAS: TVS-1282-i7-7700-40G / 4 x 500GB SSD 2.5" RAID 10 / 2 x 500GB M.2 SSD / 8 x 12TB WD Whites 3.5" RAID 6 / Noctua L9x65 / 3 x 80mm PWM Noctua fans / Corsair 600W PSU / Asus Turbo GTX 1060 6GB GPU
Software: Plex Media Server / Transmission / Sonarr / Radarr / Bazarr / Jackett / Tautulli / Home Assistant / Resilio Sync / Python / NetData / SortMyQPKGs
pfSense Firewall / OpenVPN Server: QOTOM Fanless Mini PC / Core i5 / 8GB RAM / 128GB SSD / 4 Gigabit NICs / AES-NI
Wireless Routers: 2 x Netgear AC1900 R7000 Nighthawk / 1 x Netgear AC3200 R8000 Nighthawk / FreshTomato Firmware
lalaw
New here
Posts: 6
Joined: Wed Dec 12, 2018 6:52 am

Re: Which nvidia card for transcoding nvenc/265? (ts-877)

Post by lalaw »

I just did this patch a few weeks ago, so I'd imagine it still works. Again, you should probably know your way around a Linux system with some comfort before attempting at home.

I would imagine that any update to the drivers would require re-patching.
ilboss841
Starting out
Posts: 11
Joined: Thu May 28, 2020 1:04 am

Re: Which nvidia card for transcoding nvenc/265? (ts-877)

Post by ilboss841 »

Can anyone help me install this patch? or is there any detailed guide without doing damage to my qnap system?
lalaw
New here
Posts: 6
Joined: Wed Dec 12, 2018 6:52 am

Re: Which nvidia card for transcoding nvenc/265? (ts-877)

Post by lalaw »

FWIW, I was tinkering with this given the updated drivers on QNAP. Not sure whats going on, but it seems like the driver either doesn't need to be patched or is already patched, because the patch didn't make any changes to the file. That said, I was able to run 4 streams simultaneously, all using HW encoding.
User avatar
spikemixture
Been there, done that
Posts: 890
Joined: Wed Mar 07, 2018 11:04 pm
Location: 3rd World

TT

Post by spikemixture »

lalaw wrote: Wed Feb 03, 2021 3:29 pm FWIW, I was tinkering with this given the updated drivers on QNAP. Not sure whats going on, but it seems like the driver either doesn't need to be patched or is already patched, because the patch didn't make any changes to the file. That said, I was able to run 4 streams simultaneously, all using HW encoding.
Hi I have the 1277 and 1050Ti card.
I am running the very latest firmware and drivers!
The card is functioning as the temp and fan show.
I have never seen the GPU go above 0%

I have tried multiple times in QTS mode running Plex
Virtualization Mode running a win10 VM
And Container mode running Tdarr in Docker.

Any suggestions ???
GPU Capture.JPG
You do not have the required permissions to view the files attached to this post.
Qnap TS-1277 1700 (48gb RAM) 8x10TB WD White,- Raid5, 2x M.2 Crucial 1TB (Raid 1 VM),
2x SSD 860 EVO 500gb (Raid1 QTS), 2x SSD 860 EVO 250GB (Cache), 2x M.2 PCIe 970 500gb NVME (Raid1 Plex and Emby server)
GTX 1050 TI
Qnap TVS-1282 i7 (32GB RAM) 6x8TB WD White - JBOD, 2x M.2 Crucial 500gb (Raid1 VM),
2x SSD EVO 500gb (Raid1 QTS), 2x SSD EVO 250gb (Raid1 Cache), 2x M.2 PCIe Intel 512GB NVME (Raid1-Servers)
Synology -1817+ - DOA
Drobo 5n - 5x4TB Seagate, - Drobo Raid = 15TB
ProBox 8 Bay USB3 - 49TB mixed drives - JBOD
All software is updated asap.
I give my opinion from my experience i.e. I have (or had) that piece of equipment/software and used it! :roll:
Post Reply

Return to “Media Streaming”