Intel i5 Kaby Lake Hardware-Assited Transcoding von Video und Audio in VP9 und FLAC mithilfe von ffmpeg

1875
Billy

Ich habe etwa 30 Gigabyte Video (meistens MP4, einige MKV und Webm). Ich muss 8-Bit-VP9 mit FLAC-Audio (Free Lossless Audio Codec) in einem MKV-Container von verschiedenen Eingabecodecs (AAC-Audio; H264, VP8, H265 / HEVC und wahrscheinlich einige andere Videocodecs). Auf meinem leistungsstärksten System dauert das Transkodieren von Videos mit niedriger Auflösung doppelt so lange wie die Länge des Videos. Ich benutze ffmpegunter Linux die Argumente, ffmpeg -i input -c:v libvpx-vp9 -lossless 1 -c:a FLAC -preset veryslow output.mkvum Videos ohne Hardwareunterstützung zu transcodieren. Vor kurzem hat jedoch ein Freund von mir eine Intel i5 Kaby Lake-CPU für seinen PC erhalten und hat angeboten, die Videos für mich zu transcodieren. Laut Wikipedia und ihren Referenzen unterstützen die neuen Kaby Lake-CPUs die Hardware-Dekodierung aller meiner Eingabecodecs und die Kodierung von 8-Bit-VP9. Ich habe also zwei Fragen:

  1. Welche ffmpegArgumente kann mein Freund verwenden, um die Videos in VP9 und Audio in FLAC in einem MKV-Container umzuwandeln? Arbeiten sie mit Windows? Wenn nicht, ist dies in Ordnung, da er einen Windows 10-Linux-Dual-Boot hat.

  2. Ist das veryslowPreset noch notwendig, um die beste Komprimierung zu erreichen?

Ich habe versucht, die Antwort auf diese Frage anderswo zu finden, konnte aber nur Beispiele für die Codierung von Codecs wie H264 und JPEG finden.

1

2 Antworten auf die Frage

4
林正浩

Ab heute ist es möglich, FFmpeg mit VAAPI zu erstellen, mit der Sie auf unterstützten Systemen VP9 auf der Intel Integrated GPU kodieren können.

Der neue Encoder wird aufgerufen, wenn ffmpeg mit VAAPI-Unterstützung kompiliert wird vp9_vaapi.

Führen Sie folgende Schritte aus, um die verfügbaren Optionen beim Abstimmen des Encoders anzuzeigen:

ffmpeg -hide-banner -h encoder=vp9_vaapi 

Ausgabe:

Encoder vp9_vaapi [VP9 (VAAPI)]: General capabilities: delay  Threading capabilities: none Supported pixel formats: vaapi_vld vp9_vaapi AVOptions: -loop_filter_level <int> E..V.... Loop filter level (from 0 to 63) (default 16) -loop_filter_sharpness <int> E..V.... Loop filter sharpness (from 0 to 15) (default 4) 

Was passiert, wenn Sie versuchen, dies mit nicht unterstützter Hardware durchzuführen, sagen Sie Skylake?

Siehe die Beispielausgabe unten:

[Parsed_format_0 @ 0x42cb500] compat: called with args=[nv12] [Parsed_format_0 @ 0x42cb500] Setting 'pix_fmts' to value 'nv12' [Parsed_scale_vaapi_2 @ 0x42cc300] Setting 'w' to value '1920' [Parsed_scale_vaapi_2 @ 0x42cc300] Setting 'h' to value '1080' [graph 0 input from stream 0:0 @ 0x42cce00] Setting 'video_size' to value '3840x2026' [graph 0 input from stream 0:0 @ 0x42cce00] Setting 'pix_fmt' to value '0' [graph 0 input from stream 0:0 @ 0x42cce00] Setting 'time_base' to value '1/1000' [graph 0 input from stream 0:0 @ 0x42cce00] Setting 'pixel_aspect' to value '1/1' [graph 0 input from stream 0:0 @ 0x42cce00] Setting 'sws_param' to value 'flags=2' [graph 0 input from stream 0:0 @ 0x42cce00] Setting 'frame_rate' to value '24000/1001' [graph 0 input from stream 0:0 @ 0x42cce00] w:3840 h:2026 pixfmt:yuv420p tb:1/1000 fr:24000/1001 sar:1/1 sws_param:flags=2 [format @ 0x42cba40] compat: called with args=[vaapi_vld] [format @ 0x42cba40] Setting 'pix_fmts' to value 'vaapi_vld' [auto_scaler_0 @ 0x42cd580] Setting 'flags' to value 'bicubic' [auto_scaler_0 @ 0x42cd580] w:iw h:ih flags:'bicubic' interl:0 [Parsed_format_0 @ 0x42cb500] auto-inserting filter 'auto_scaler_0' between the filter 'graph 0 input from stream 0:0' and the filter 'Parsed_format_0' [AVFilterGraph @ 0x42ca360] query_formats: 6 queried, 4 merged, 1 already done, 0 delayed [auto_scaler_0 @ 0x42cd580] w:3840 h:2026 fmt:yuv420p sar:1/1 -> w:3840 h:2026 fmt:nv12 sar:1/1 flags:0x4 [hwupload @ 0x42cbcc0] Surface format is nv12. [AVHWFramesContext @ 0x42ccbc0] Created surface 0x4000000. [AVHWFramesContext @ 0x42ccbc0] Direct mapping possible. [AVHWFramesContext @ 0x42c3e40] Created surface 0x4000001. [AVHWFramesContext @ 0x42c3e40] Direct mapping possible. [AVHWFramesContext @ 0x42c3e40] Created surface 0x4000002. [AVHWFramesContext @ 0x42c3e40] Created surface 0x4000003. [AVHWFramesContext @ 0x42c3e40] Created surface 0x4000004. [AVHWFramesContext @ 0x42c3e40] Created surface 0x4000005. [AVHWFramesContext @ 0x42c3e40] Created surface 0x4000006. [AVHWFramesContext @ 0x42c3e40] Created surface 0x4000007. [AVHWFramesContext @ 0x42c3e40] Created surface 0x4000008. [AVHWFramesContext @ 0x42c3e40] Created surface 0x4000009. [AVHWFramesContext @ 0x42c3e40] Created surface 0x400000a. [vp9_vaapi @ 0x409da40] Encoding entrypoint not found (19 / 6). 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 [AVIOContext @ 0x40fdac0] Statistics: 0 seeks, 0 writeouts [aac @ 0x40fcb00] Qavg: -nan [AVIOContext @ 0x409f820] Statistics: 32768 bytes read, 0 seeks Conversion failed! 

Die interessanten Bits sind die Eingangspunktwarnungen für das Fehlen der VP9-Codierung auf dieser Plattform, wie durch die Ausgabe von vainfo bestätigt wird:

libva info: VA-API version 0.40.0 libva info: va_getDriverName() returns 0 libva info: Trying to open /usr/local/lib/dri/i965_drv_video.so libva info: Found init function __vaDriverInit_0_40 libva info: va_openDriver() returns 0 vainfo: VA-API version: 0.40 (libva 1.7.3) vainfo: Driver version: Intel i965 driver for Intel(R) Skylake - 1.8.4.pre1 (glk-alpha-71-gc3110dc) vainfo: Supported profile and entrypoints VAProfileMPEG2Simple : VAEntrypointVLD VAProfileMPEG2Simple : VAEntrypointEncSlice VAProfileMPEG2Main : VAEntrypointVLD VAProfileMPEG2Main : VAEntrypointEncSlice VAProfileH264ConstrainedBaseline: VAEntrypointVLD VAProfileH264ConstrainedBaseline: VAEntrypointEncSlice VAProfileH264ConstrainedBaseline: VAEntrypointEncSliceLP VAProfileH264Main : VAEntrypointVLD VAProfileH264Main : VAEntrypointEncSlice VAProfileH264Main : VAEntrypointEncSliceLP VAProfileH264High : VAEntrypointVLD VAProfileH264High : VAEntrypointEncSlice VAProfileH264High : VAEntrypointEncSliceLP VAProfileH264MultiviewHigh : VAEntrypointVLD VAProfileH264MultiviewHigh : VAEntrypointEncSlice VAProfileH264StereoHigh : VAEntrypointVLD VAProfileH264StereoHigh : VAEntrypointEncSlice VAProfileVC1Simple : VAEntrypointVLD VAProfileVC1Main : VAEntrypointVLD VAProfileVC1Advanced : VAEntrypointVLD VAProfileNone : VAEntrypointVideoProc VAProfileJPEGBaseline : VAEntrypointVLD VAProfileJPEGBaseline : VAEntrypointEncPicture VAProfileVP8Version0_3 : VAEntrypointVLD VAProfileVP8Version0_3 : VAEntrypointEncSlice VAProfileHEVCMain : VAEntrypointVLD VAProfileHEVCMain : VAEntrypointEncSlice VAProfileVP9Profile0 : VAEntrypointVLD 

Der VLD-Einstiegspunkt (für Variable Length Decode) für das VP9-Profil 0 ist der am weitesten entfernte Punkt, an dem Skylake in Bezug auf die VP9-Hardwarebeschleunigung ankommt.

Diese mit Kabylake-Testbetten führen diese Verschlüsselungstests durch und melden einen Bericht :-)

2
veikk0

UPDATE AM 3. AUGUST 2017: Laut einer neueren Antwort des Benutzers user unterstützt ffmpeg nun die VP9-Codierung über VAAPI. Ich habe immer noch nicht die nötige Hardware, um dies zu testen, daher ist meine Antwort nur begrenzt hilfreich. Ich lasse meine ursprüngliche Antwort zum Kodieren von VP9 in Software weiter unten.


Aus irgendeinem Grund unterstützt FFmpeg die VP9-Codierung nicht mit Intels QuickSync-Hardware-Encoder, obwohl sie H.264 und HEVC unterstützen . Eine Suche durch das FFmpeg-Quellcode-Repository zeigt, dass es nicht einmal eine Frage der Deaktivierung ist, das Feature wurde noch nicht implementiert. Wenn es jedoch irgendwann in der Zukunft verfügbar wird, sollte es auf ähnliche Weise wie die anderen QuickSync-Encoder verwendet werden können: Ein Switch, der -c:v vp9_qsvanstelle von -c:v libvpx-vp9sollte, sollte die Aufgabe erfüllen.

Die FFmpeg-Befehlszeilenverwendung ist auf allen Plattformen gleich, mit der einzigen bemerkenswerten Ausnahme, dass ich Windows-Benutzer bin, die beim ersten Durchgang einer 2-Pass-Codierung NULanstelle der /dev/nullAusgabe verwendet werden müssen. Aber da Sie 1-Pass und verlustfrei machen, sollte Sie dies nicht beeinträchtigen.

Wenn Sie die Codierung beschleunigen möchten, sollten Sie einen Encoder-Geschwindigkeitswert mit dem -speedSchalter einstellen . Empfohlene Werte sind Zahlen von 0 bis 4, wobei 0 wirklich sehr langsam ist ( -preset placeboin x264 denken, aber schlechter), aber hohe Qualität und 4 sind schnell, während sie von geringerer Qualität sind. ffmpeg verwendet -speed 1standardmäßig einen guten Kompromiss für verlustbehaftete Kodierung. Aber ich habe gerade einen schnellen lossless Codierung Test mit verschiedenen Geschwindigkeitswerten und bemerkte eine 32% ige Reduktion der Dateigröße, wenn sie aus gehen -speed 1zu -speed 0mit lossless - Codierung. Die Kodierungszeit hat sich jedoch verdreifacht. Ob sich also die Verwendung von 0 lohnt, liegt ganz bei Ihnen. Die erzeugte Datei -speed 4war nur 1,1% größer als die von-speed 1und es war 43% schneller codiert. Ich würde also sagen, wenn Sie verlustfrei sind und tun-speed 0ist zu langsam, könnte man auch verwenden -speed 4.

Eine weitere wichtige Steigerung der Codierungsleistung ist das Aktivieren von Multithreading mit dem -threadsSwitch. libvpx verwendet nicht automatisch mehrere Threads. Dies muss vom Benutzer manuell festgelegt werden. Sie sollten auch die Anzahl der Kachelspalten mit dem -tile-columnsSchalter festlegen . Diese Option bewirkt, dass libvpx das Video in mehrere Kacheln aufteilt und diese Kacheln parallel kodiert, um das Multithreading zu verbessern. Empfohlene Zahlen für die Anzahl der Kachelspalten und -fäden finden Sie im Abschnitt "Empfehlungen für das Kacheln und Einfädeln" von der VP9-Kodierungsanleitung Google. Wie Sie sehen, steigt die Anzahl der verwendeten Threads mit der Anzahl der Kacheln. Dies bedeutet, dass Ihr Prozessor bei der Codierung von Video mit einer Sub-HD-Auflösung abhängig von der Anzahl der verfügbaren Prozessorkerne möglicherweise nicht vollständig ausgelastet ist. Wenn Sie hauptsächlich Videos mit niedriger Auflösung codieren, empfiehlt es sich, mehrere Dateien gleichzeitig zu codieren.

Es gibt jedoch noch eine weitere Möglichkeit, die VP9-Codierung zu beschleunigen: Multithreading innerhalb einer einzelnen Spaltenkachel, die mit aktiviert werden kann -row mt 1. Seit dem 4. April (2017, Hallo zukünftige Leute), ist es nicht Teil einer veröffentlichten Version von libvpx, wird aber höchstwahrscheinlich in libvpx 1.6.2 erscheinen. Wenn Sie es vor dem nächsten Release ausprobieren möchten, müssen Sie die letzten git-Versionen von libvpx und ffmpeg aus dem Quellcode kompilieren. Folgen Sie einfach dem FFmpeg-Kompilierungshandbuch für Ihre bevorzugte Distribution. Statt ein Release-Archiv herunterzuladen und zu extrahieren, müssen Sie dies tun git pull https://chromium.googlesource.com/webm/libvpx.

Das veryslowPreset wird nur in x264 und x265 verwendet. libvpx verwendet den -speedSchalter und zusätzlich die -quality best, -quality goododer -quality realtimeOptionen zu definieren, wie viel Zeit der Encoder einen Rahmen verbringen darf kodiert. Die Standardeinstellung ist, -quality goodweil sie -quality bestso langsam ist, dass sie unbrauchbar ist und -quality realtimefür zeitkritische Anwendungen wie Videoanrufe und Livestreaming verwendet werden soll.

Tolles Schreiben und willkommen bei Super User! slhck vor 7 Jahren 0
Danke für die Antwort. Welche FFmpeg-Argumente kann ich verwenden, um VP9 mit VA-API zu kodieren? Ich habe gesehen, dass die FFmpeg-Quelle eine Datei mit dem Namen 'vaapi_vp9.c' hat. Ich werde versuchen, was Sie oben vorgeschlagen haben, um den Prozess zu beschleunigen. Billy vor 7 Jahren 0
VA-API kann sowohl zur hardwarebeschleunigten Codierung als auch zur Decodierung verwendet werden. In diesem Fall wird leider nur die Decodierung durchgeführt. Eine weniger bekannte Tatsache über FFmpeg ist, dass es auch über eine Videowiedergabefunktion verfügt. Google Chrome und die Linux-Version von Firefox verwenden es, um Video und Audio abzuspielen. Das binäre FFmpeg für die Wiedergabe ist "ffplay". (Außerdem habe ich einen Fehler in meinem Kommentar korrigiert: Die Qualitätsschalter sind eigentlich "-Quality Good", "-Quality Realtime" usw., nicht nur "-good" oder "Realzeit".) veikk0 vor 7 Jahren 0
Eigentlich nehme ich das zurück. Es gibt Nachrichtenartikel, die darauf hinweisen, dass die Unterstützung von VP9-Kodierung in der VA-API vorhanden ist. Ich kann jedoch nichts Bestimmtes finden und kann daher nicht gebeten werden, im Moment nach Quellcode zu suchen. Sie sollten wahrscheinlich [hier] (https://gist.github.com/Brainiarc7/95c9338a737aa36d9bb2931bed379219) und [hier] (https://gist.github.com/Brainiarc7/4b49f463a08377530df6cecb8171306a) nachschauen. Ich würde mit der Prüfung beginnen, ob FFmpeg mit "--enable-vaapi" erstellt wurde und wenn ja, "ffmpeg -decoders |" grep vaapi` und `ffmpeg -h encoder =`. Ich habe eine AMD-CPU, daher kann ich das nicht selbst testen. veikk0 vor 7 Jahren 0
Okay danke. Ich werde morgen nachschauen. Billy vor 7 Jahren 0
@ user13178 Bitte sehen Sie die Antwort unten - es ist jetzt möglich, ffmpeg mit Hardware-basierter VP9-Kodierungsunterstützung zu erstellen. Möglicherweise möchten Sie Ihren Beitrag bearbeiten. slhck vor 6 Jahren 0
Hallo @Billy, siehe meine Antwort unten. 林正浩 vor 6 Jahren 0