Jak korzystać z kodowania CRF z nvenc w ffmpeg?

23

To jest moje obecne polecenie zmiany rozmiaru filmów (1080p) z 2 GB do 300 MB, ale zajmuje to dużo czasu:

mkdir newfiles  
for %%a in ("*.mp4") do ffmpeg -i "%%a" -c:v  libx264 -preset slow -crf 21 -c:a aac -b:a 128k -vf scale=678:-2 "newfiles\%%~na.mp4"  
pause

Próbowałem nvenc z moim NVIDIA GTX1070:

mkdir newfiles  
for %%a in ("*.mp4") do ffmpeg -i "%%a" -c:v h264_nvenc -preset slow -c:a aac -b:a 128k -vf scale=678:-2 "newfiles\%%~na.mp4"  
pause

Rozmiar wyjściowy wynosi zawsze 3⨉ lub 5⨉ rozmiaru oryginalnego - nvenc nie używa -crf.

Jak więc użyć nvenc z ffmpeg do konwersji / zmiany rozmiaru wideo o wysokiej jakości i małym rozmiarze? Czy powinienem używać GPU do kodowania?

hongducwb
źródło
Możesz zmienić slowna fastw pierwszym poleceniu. CRF nie jest zaimplementowany w nvenc.
Gyan
Celem NVENC jest umożliwienie kodowania wideo w czasie rzeczywistym (np. Podczas połączeń wideo); jakość jest podrzędnym czynnikiem.
CL.

Odpowiedzi:

24

W przypadku kodowania opartego na CRF przekaż FFmpeg następujące argumenty we fragmencie poniżej:

-c:v h264_nvenc -rc:v vbr_hq -cq:v 19 -b:v 2500k -maxrate:v 5000k -profile:v high

Oczywiście musisz dostosować docelową przepływność i stałą cqwartość. 19 jest zalecanym ustawieniem, ponieważ jest „wizualnie identyczne z 0, ale zachowuje dobrą kompromis kompresji do rozmiaru pliku. Zobacz ten opis, aby dowiedzieć się więcej o tym, co robi CRF.

Zauważ, że -cqskala jest logarytmiczna, co oznacza, że ​​0 jest zasadniczo bezstratne, a 51 byłoby absolutnie najgorsze.

Jakość można jeszcze poprawić, dodając opcje, takie jak ramki B. (ogranicz to maksymalnie do 3, a to wymaga profilu głównego H.264 i wyższych. Profile podstawowe nie obsługują ramek B. Aby to zrobić, przejdź -bf {uint}do koder wideo, taki, -bf:v 4który spowodowałby, że koder używałby 4 ramek B.

Kluczowe są tu części -cq:v 19i -rc:v vbr_hqargumenty, które pozwalają dostroić enkodera ze zmiennym bitrate zarówno zaprogramowany i maksymalnym dopuszczalnym bitrate ( -b:vi -maxrate:v) przy jednoczesnym przestrzeganiu wartości CRF 19.

A teraz małe notatki na temat NVENC i dostrajanie go do kodowania wysokiej jakości:

NVENC, jak każdy inny koder sprzętowy, ma kilka ograniczeń, a zwłaszcza HEVC, tutaj są znane ograniczenia:

  1. W Pascal:

    W przypadku kodów HEVC obowiązują następujące ograniczenia:

    • Rozmiary CTU powyżej 32 nie są obsługiwane.
    • Ramki B w HEVC również nie są obsługiwane.
    • Formaty tekstur obsługiwane przez koder NVENC ograniczają przestrzenie kolorów, z którymi koder może współpracować. Na razie mamy wsparcie dla 4: 2: 0 (8-bit) i 4: 4: 4 (dla 10-bit). Zewnętrzne formaty, takie jak 4: 2: 2 10-bitowe nie są obsługiwane. Wpłynie to na niektóre przepływy pracy, w których wymagane są takie przestrzenie kolorów.
    • Kontrola z wyprzedzeniem jest również ograniczona do 32 klatek. Więcej informacji możesz znaleźć w tym artykule wstępnym.

Turing ma wszystkie ulepszenia dostępne dla Pascala, z dodatkiem obsługi ramki B dla HEVC i możliwością użycia ramek B jako odniesienia. Zobacz odpowiedź, aby zobaczyć przykład tej możliwości.

  1. A w Maxwell Gen 2 (procesory graficzne z serii GM200x):

    Kodowaniu HEVC brakuje następujących funkcji:

Wpływ Maxwella jest taki, że sceny o dużym ruchu z HEVC przy ograniczonych przepływnościach mogą cierpieć z powodu artefaktów (blokowania) z powodu brakujących funkcji wyprzedzających i możliwości filtrowania pętli adaptacyjnego próbkowania (SAO). Pascal nieco poprawił tę funkcję, ale w zależności od wersji zestawu SDK, w którym został zbudowany koder wideo, nie wszystkie funkcje mogą być dostępne.

Na przykład tryb prognozowania ważonego dla kodowania H.264 na Pascalu wymaga zestawu NVENC SDK 8.0x i nowszego, a ten tryb kodowania również wyłączy obsługę ramki B. Podobnie, połączenie sprzętowych skalerów działających z Nvidia Performance Primitive (NPP) z NVENC może wprowadzić ulepszenia wydajności w aplikacjach do skalowania wideo kosztem artefaktów skalowania, szczególnie w przypadku skalowanej treści. To samo wpływa na potok kodowania wideo, ponieważ funkcje skalowania NPP działają poza rdzeniami CUDA na GPU i jako taki wpływ na wydajność wprowadzony przez dodatkowe obciążenie powinien być analizowany indywidualnie dla każdego przypadku, aby ustalić, czy jakość wykonania kompromis jest akceptowalny.

Miej to na uwadze: koder sprzętowy zawsze będzie oferował nieco mniejszą personalizację niż równoważna implementacja programowa, a zatem przebieg i akceptowalna jakość wyjściowa zawsze będą się różnić.

I w celach informacyjnych:

Dzięki FFmpeg możesz zawsze odwoływać się do ustawień kodera w celu dostosowania poprzez:

ffmpeg -h encoder {encoder-name}

W przypadku koderów opartych na NVENC możesz uruchomić:

ffmpeg -h encoder=hevc_nvenc

ffmpeg -h encoder=h264_nvenc

Możesz również zobaczyć wszystkie kodery oparte na NVENC i skalery oparte na NPP (jeśli są zbudowane jako takie), uruchamiając:

for i in encoders decoders filters; do
    echo $i:; ffmpeg -hide_banner -${i} | egrep -i "npp|cuvid|nvenc|cuda"
done

Przykładowe dane wyjściowe na moim testbed:

encoders:
 V..... h264_nvenc           NVIDIA NVENC H.264 encoder (codec h264)
 V..... nvenc                NVIDIA NVENC H.264 encoder (codec h264)
 V..... nvenc_h264           NVIDIA NVENC H.264 encoder (codec h264)
 V..... nvenc_hevc           NVIDIA NVENC hevc encoder (codec hevc)
 V..... hevc_nvenc           NVIDIA NVENC hevc encoder (codec hevc)
decoders:
 V..... h263_cuvid           Nvidia CUVID H263 decoder (codec h263)
 V..... h264_cuvid           Nvidia CUVID H264 decoder (codec h264)
 V..... hevc_cuvid           Nvidia CUVID HEVC decoder (codec hevc)
 V..... mjpeg_cuvid          Nvidia CUVID MJPEG decoder (codec mjpeg)
 V..... mpeg1_cuvid          Nvidia CUVID MPEG1VIDEO decoder (codec mpeg1video)
 V..... mpeg2_cuvid          Nvidia CUVID MPEG2VIDEO decoder (codec mpeg2video)
 V..... mpeg4_cuvid          Nvidia CUVID MPEG4 decoder (codec mpeg4)
 V..... vc1_cuvid            Nvidia CUVID VC1 decoder (codec vc1)
 V..... vp8_cuvid            Nvidia CUVID VP8 decoder (codec vp8)
 V..... vp9_cuvid            Nvidia CUVID VP9 decoder (codec vp9)
filters:
 ... hwupload_cuda     V->V       Upload a system memory frame to a CUDA device.
 ... scale_npp         V->V       NVIDIA Performance Primitives video scaling and format conversion
林正浩
źródło
1
Świetna odpowiedź! Wiki ffmpeg na nvenc jest trochę przestarzałe i nie ma tych wszystkich informacji… jeśli masz kilka minut, byłoby wspaniale, gdybyś mógł tam przekazać swoją wiedzę: trac.ffmpeg.org/wiki/HWAccelIntro
slhck
1
dziękuję za odpowiedź :) ffmpeg wiki potrzebuje więcej odpowiedzi w ten sposób
hongducwb
Dziękujemy za opinię. Zajmę się dodaniem tego do wiki FFmpeg.
林正浩
wyjściowe pliki kolorów wydają się ciemniejsze, pamiętam, że jeden argument może kontrolować kolor tak samo jak plik wejściowy
hongducwb
2
vbr_minqpwydaje się teraz przestarzałe. Zgadzam się, że ta odpowiedź może być źle zrozumiana, ponieważ nie ma trybu CRF h264_nvenc.
slhck,
4

Myślę, że znalazłem rozwiązanie:

ffmpeg -hwaccel auto -i in.mp4 -c:v h264_nvenc -preset llhq -rc constqp -qp 21 -c:a copy out.mp4

Wygląda na to, że h264_nvenc używa -qpzamiast -crf. Ta opcja działa tylko, gdy -rcjest ustawiona na constqp.

Alexander01998
źródło
1
Nie, -qpwszystko różni się od -crf. h264_nvenc 's -qpjest równa libx264 ' s-qp
Miau
@Meow To dla mnie wystarczająco blisko, ale dobrze wiedzieć, że jest różnica. Dla każdego, kto może to zobaczyć w przyszłości, ta strona wyjaśnia różnicę między CRF a QP.
Alexander01998
3

Do -crfwymiany z libx264 może być -cqlub -qpz h264_nvenc:

-crf Wybierz jakość dla trybu stałej jakości

-cq Ustaw docelowy poziom jakości (od 0 do 51, 0 oznacza tryb automatyczny) dla trybu stałej jakości w kontroli prędkości VBR

-qp Metoda kontroli stałej parametru kwantyzacji (od -1 do 51) (domyślnie -1)

Najszybsza metoda kodowania akcelerowanego sprzętowo:

ffmpeg -hwaccel cuvid -c:v h264_cuvid -resize 640x480 -i input.mp4 -c:v h264_nvenc -cq 21 -c:a copy output.mp4

-resizerozdzielczość na wejściu (sprzętowo); nie ma potrzeby kompilacji ffmpeg --enable-libnppdla scale_nppfiltra.

Po więcej informacji:

ffmpeg -h encoder=h264_nvenc

ffmpeg -h denoder=h264_cuvid
ABC
źródło