Quantcast
Aktuelles
Digital Eliteboard - Das Digitale Technik Forum

Registriere dich noch heute kostenlos, um Mitglied zu werden! Sobald du angemeldet bist, kannst du auf unserer Seite aktiv teilnehmen, indem du deine eigenen Themen und Beiträge erstellst und dich über deinen eigenen Posteingang mit anderen Mitgliedern unterhalten kannst! Zudem bekommst du Zutritt zu Bereichen, welche für Gäste verwehrt bleiben

Registriere dich noch heute kostenlos, um Mitglied zu werden! Sobald du angemeldet bist, kannst du auf unserer Seite aktiv teilnehmen, indem du deine eigenen Themen und Beiträge erstellst und dich über deinen eigenen Posteingang mit anderen Mitgliedern unterhalten kannst! Zudem bekommst du Zutritt zu Bereichen, welche für Gäste verwehrt bleiben

FFMPEG HWACCEL Transcoding

Registriert
11. Juni 2010
Beiträge
4.080
Reaktionspunkte
2.847
Punkte
373
Hallo Zusammen,

nach langer Zeit und einigen Anfragen habe ich hier ein neues Tutorial für euch.
In diesem Tutorial geht es darum, eine durch NVIDIAs GPU gepowertes Transcoding laufen zu lassen.
Darüber hinaus zeige ich euch, wie Ihr Filme ganz Easy und schnell nach MP4 transcoded könnt um Maßig Storage ohne Qualitätseinbußen des Videos zu sparen.

Die Anforderungen:
- Mind. einen Core i5 Prozessor, vergleichsweise AMD
- Mind. 8 GB RAM
- Eine HDD mit genug Kapazität
- eine NVIDIA GPU: GTX 1060 3GB / 6GB, GTX 1070, 1080, Quadro P2000 etc. unter dem würde ich nicht anfangen.
- Installation von Ubuntu Server 18.04 als Grundsystem wird vorausgesetzt.

Schritt 1:
Nach der Installation des Grundsystems und dem installieren der aktuellen Updates installieren wir das CUDA Toolkit und die notwendigen Requirements.
Code:
apt update
apt install autoconf automake build-essential cmake pkg-config texinfo wget yasm zlib1g-dev nasm
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-ubuntu1804.pin
sudo mv cuda-ubuntu1804.pin /etc/apt/preferences.d/cuda-repository-pin-600
wget https://developer.download.nvidia.com/compute/cuda/11.1.1/local_installers/cuda-repo-ubuntu1804-11-1-local_11.1.1-455.32.00-1_amd64.deb
sudo dpkg -i cuda-repo-ubuntu1804-11-1-local_11.1.1-455.32.00-1_amd64.deb
sudo apt-key add /var/cuda-repo-ubuntu1804-11-1-local/7fa2af80.pub
sudo apt-get update
sudo apt-get -y install cuda

Schritt 2:
Nachdem die Installation von CUDA ein paar Minuten gedauert hat, bauen wir uns FFMPEG.
Code:
#Zuerst installieren wir noch ein paar Requirements:
apt install libx264-dev libx265-dev libnuma-dev libfdk-aac-dev
cd /opt
git clone https://git.ffmpeg.org/ffmpeg.git
git clone https://github.com/FFmpeg/nv-codec-headers
cd nv-codec-headers && make install && cd ..
cd ffmpeg
#Jetzt bauen wir die eigentliche FFMPEG Binary mit libfdk_aac, cuda, h264 und h265 Support
./configure --enable-cuda-sdk --enable-cuda --enable-cuvid --enable-nvenc --enable-gpl --enable-nonfree --enable-libx264 --enable-libfreetype --enable-libfdk-aac --enable-cuda-nvcc --enable-libnpp --extra-cflags=-I/usr/local/cuda/include --extra-ldflags=-L/usr/local/cuda/lib64
make -j4
make install

Nun checkt eure ffmpeg Version:

Code:
ffmpeg -version
#Output:
ffmpeg version N-98403-g04e06beb0a Copyright (c) 2000-2020 the FFmpeg developers
built with gcc 7 (Ubuntu 7.5.0-3ubuntu1~18.04)
configuration: --enable-cuda-sdk --enable-cuda --enable-cuvid --enable-nvenc --enable-nonfree --enable-gpl --enable-libx264 --enable-libfreetype --enable-libfdk-aac --enable-cuda-nvcc --enable-libnpp --extra-cflags=-I/usr/local/cuda/include --extra-ldflags=-L/usr/local/cuda/lib64
libavutil      56. 55.100 / 56. 55.100
libavcodec     58. 94.100 / 58. 94.100
libavformat    58. 48.100 / 58. 48.100
libavdevice    58. 11.101 / 58. 11.101
libavfilter     7. 86.100 /  7. 86.100
libswscale      5.  8.100 /  5.  8.100
libswresample   3.  8.100 /  3.  8.100
libpostproc    55.  8.100 / 55.  8.100

Schritt 3:
Da nun das Grundgerüst zum Transcoding steht, können anfangen zum Beispiel einen Film von MKV nach MP4 zu transcoden.
Mit der Variable $f definiere ich das File, welches transcoded wird und mit $name den Output. Im nächsten Schritt wird CUDA initiiert und das Inputfile gelesen.
Hier beginnt dann nun das eigentlich transcoding. Der hwdownload lädt die Frame in den GPU RAM, ändert das Pixel Format zu nv12 und Uploaded Frames
für das weitere processing. Hier wird mit -c:v:0 der Video Stream 0 nun selektiert und vom Codec H264 (zum Beispiel) mit dem Profil Main und der Geschwindigkeit Slow bei mittlerer
Qualität qmin bis qmax ins Format YUV420P transcoded. Parallel dazu werden die Audio Streams mit deutscher Sprache selektiert und in den Codec LIBFDK_AAC umgewandelt. Hier ist zu beachten, dass der Audiostream 0 Stereo bei 48kbit/s und der Audiostream 1 bei 5.1 mit 384kbit/s umgewandelt wird.

Das folgende Script könnt Ihr als transcode in /usr/local/bin speichern.
Bitte vergesst nicht dem Script entsprechende Rechte zum Ausführen zu geben wie etwa chmod 777 /usr/local/bin/transcode
Code:
#!/bin/bash
f="$1" # all args
name="$2"
 ffmpeg -y -loglevel verbose \ 
           -init_hw_device cuda=cuda \ 
           -hwaccel cuda \ 
           -filter_hw_device cuda \ 
           -hwaccel_output_format cuda \
           -i "$f" \ 
          -flags -global_header \ 
          -filter_complex "[0:v]hwdownload,format=nv12,hwupload_cuda" \ 
          -c:v:0 hevc_nvenc \ 
          -profile:v main \ 
          -preset slow \ 
          -qmin 28 \ 
          -qmax 30 \
          -format yuv420p \ 
          -map 0:m:language:ger -map 0:m:language:ger \ 
          -c:a:0 libfdk_aac -ar:a 48000 \ 
          -channel_layout:a 5.1 -ab:a 640k
          -c:a:1 libfdk_aac -ab:a 384k -ar 48000 \ 
          -sn "$name".mp4
Ausführungsbeispiel:
Wir haben unter /mnt/share/ unseren Film Avatar.264.DEB.mkv liegen.
Dieser Film ist in etwas 10GB groß.
Code:
cd /mnt/share
transcode "Avatar.264.DEB.mkv" "Avatar.HVENC.Peters.Release"
Nach etwa 10-15 Minuten ist das Transcoding abgeschlossen.
Nun könnt Ihr mittels ls- l --block-size=m prüfen wie groß das Outputfile Avatar.HVENC.Peters.Release.mp4 ist.
Ihr werdet feststellen, dass der Output am Ende nur noch 2...maximal 3,5GB sein wird ohne das Ihr Qualität am Bildmaterial verloren habt.
Ihr könnt gerne mit dem qmin und qmax etwas experimentieren. Für mich sind dies aber ganz gute Werte gemessen daran, wie die Qualität beim Inputfile ist. Bei qmin und qmax gilt:
Je niedriger der Wert, umso höher die Bitrate --> je Höher die Bitrate umso besser das Bild --> Umso besser das Bild --> Je größer wird das File. Also kann es im Extremfall am Ende auch 30GB groß sein, statt ursprünglich 10GB...nur tut man so nichts gewinnen.

Um den ganzen hier noch etwas Würze zu geben, lege ich noch mein UHD Script ontop.
Ich habe hier wirklich starke Erfolge eingefahren für mich. Ich habe einen guten alten Klassiker mit 49GB MKV auf knapp 8.9GB transcoded. Und ganz ehrlich....wenn ich nicht gerade mit einer Lupe vorm Fernseher sitze, sehe ich keinen Unterschied.


Der Unterschied hier ist zum einen das Pixel Format yuv420p10le, sowie der Color Space color_primaries bt2020 -color_trc smpte2084 -colorspace bt2020nc.
Sind die Settings nicht vorhanden, gehen die Farbtöne verloren und werden durch Weiss ersetzt. In diesem Script sind auch die Metadaten gesetzt, wie die Audiostreams benannt sind.
Code:
#!/bin/bash
f="$1" # all args
name="$2"
        ffmpeg -y -loglevel verbose \
         -init_hw_device cuda=cuda \
         -hwaccel cuda \
         -filter_hw_device cuda \
         -hwaccel_output_format cuda -i "$f" \
         -flags -global_header -filter_complex \
         "[0:v]hwdownload,format=p010le,hwupload_cuda" \
         -color_primaries bt2020 -color_trc smpte2084 -colorspace bt2020nc \
         -c:v hevc_nvenc -profile:v main10 -preset slow -qp 25 -format yuv420p10le \
         -map 0:m:language:ger -map 0:m:language:ger -map 0:m:language:ger -map 0:m:language:ger \
         -c:a:1 copy -metadata:s:a:0 title="Original Audio" \
         -c:a:2 libfdk_aac -ar:a 48000 -channel_layout:a 5.1 -ab:a 640k -metadata:s:a:1 title="AAC 5.1" \
         -c:a:3 libfdk_aac -ab:a 384k -ar 48000 -metadata:s:a:2 title="AAC Stereo" \
         -c:a:4 ac3 -ac 6 -ab 640k -metadata:s:a:3 title="AC3 5.1" \
         -sn "$name".mp4

Kleine Info noch zum Abschluss:
Über ein paar kleinere Anpassungen lassen sich damit auch ts Streams erstellen und Livestreamen.
 
Über ein paar kleinere Anpassungen lassen sich damit auch ts Streams erstellen und Livestreamen.
Ich habe damit rumgespielt, sehr interessant!
ich bekomme Errors wenn z.B. ein stream 0:1 oder 0:2 drin ist mit z.B 7.1 Ton

Ausserdem welche Änderungen würdest du vorschlagen wenn das Ausgangmaterial 30fps hat und man möchte egentlich 25fps
Desweiteren welche Änderungen würdest du vorschlagen wenn du mpeg-ts als Ziel hast
 
Zurück
Oben