H264 CPU Hardware Encoding mit Linux
Inzwischen unterstützen verschiedene CPUs die Kodierung von Videos mittels Hardware Encoder. Wie geht das unter Linux und wie schnell läuft es eigentlich?
Inzwischen unterschützen verschiedene CPUs die Kodierung von Videos mittels Hardware Endoder. Ich interessiere mich vor allem für den H264 Encoder um Videos bis Full-HD von MPEG nach H264 zu konvertieren. Welche Geschwindikeit ist von CPU vs CPU Encoder (HW) zu erwarten.
Intel CPU
Intel Prozessoren unterstützen schon sehr lange die Hardware-Encoderung von Videos. Der Name dieser Erweiterung ist Intel "Quick Sync Video" und ist Teil der Intel GPU im Prozessor.
F Prozessoren bzw. Prozessoren ohne Grafikeinheit haben diese Erweiterung nicht!
Als Konvertierungsprogramm kommt unter Linux ffmpeg zum Einsatz. Auf der Projektseite gibt es eine umfangreiche Tabelle mit unterstützten Features aller Intel Prozessorgenerationen.
https://trac.ffmpeg.org/wiki/Hardware/QuickSync
Der H264 Encoder wird bereits ab Sandy Bridge Prozessoren (also 2.Generation) unterstützt. Ich habe einen Laptop mit einem U4600 Haswell Prozessor (4. Generation). Dann hab ich noch einen ThinClient mit einem N3700 Braswell Prozessor. Beide sollten die Aufgabe beweltigen können. Der U4600 Prozessor läuft mit Linux Mint 20.3 Una. Der N3700 Prozessor mit Debian 12 Bookworm.
Installation
Zusätzlich zum ffmpeg Programm wird noch der VAAPI Treiber benötigt.
1sudo apt install vainfo ffmpeg va-driver-all
Nach der Installation kann man sich die VAAPI Iformationen mit vainfo ansehen.
1vainfo
U4600(Haswell/Gen7.5) - Linux Mint 20.3 Una:
1libva info: VA-API version 1.7.0
2libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/iHD_drv_video.so
3libva info: Found init function __vaDriverInit_1_7
4libva error: /usr/lib/x86_64-linux-gnu/dri/iHD_drv_video.so init failed
5libva info: va_openDriver() returns 1
6libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/i965_drv_video.so
7libva info: Found init function __vaDriverInit_1_6
8libva info: va_openDriver() returns 0
9vainfo: VA-API version: 1.7 (libva 2.6.0)
10vainfo: Driver version: Intel i965 driver for Intel(R) Haswell Mobile - 2.4.0
11vainfo: Supported profile and entrypoints
12 VAProfileMPEG2Simple : VAEntrypointVLD
13 VAProfileMPEG2Simple : VAEntrypointEncSlice
14 VAProfileMPEG2Main : VAEntrypointVLD
15 VAProfileMPEG2Main : VAEntrypointEncSlice
16 VAProfileH264ConstrainedBaseline: VAEntrypointVLD
17 VAProfileH264ConstrainedBaseline: VAEntrypointEncSlice
18 VAProfileH264Main : VAEntrypointVLD
19 VAProfileH264Main : VAEntrypointEncSlice
20 VAProfileH264High : VAEntrypointVLD
21 VAProfileH264High : VAEntrypointEncSlice
22 VAProfileH264MultiviewHigh : VAEntrypointVLD
23 VAProfileH264MultiviewHigh : VAEntrypointEncSlice
24 VAProfileH264StereoHigh : VAEntrypointVLD
25 VAProfileH264StereoHigh : VAEntrypointEncSlice
26 VAProfileVC1Simple : VAEntrypointVLD
27 VAProfileVC1Main : VAEntrypointVLD
28 VAProfileVC1Advanced : VAEntrypointVLD
29 VAProfileNone : VAEntrypointVideoProc
30 VAProfileJPEGBaseline : VAEntrypointVLD
N3700(Braswell/Gen8) - Debian 12 Bookworm:
1libva info: VA-API version 1.17.0
2libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/iHD_drv_video.so
3libva info: Found init function __vaDriverInit_1_17
4libva error: /usr/lib/x86_64-linux-gnu/dri/iHD_drv_video.so init failed
5libva info: va_openDriver() returns 1
6libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/i965_drv_video.so
7libva info: Found init function __vaDriverInit_1_8
8libva info: va_openDriver() returns 0
9vainfo: VA-API version: 1.17 (libva 2.12.0)
10vainfo: Driver version: Intel i965 driver for Intel(R) CherryView - 2.4.1
11vainfo: Supported profile and entrypoints
12 VAProfileMPEG2Simple : VAEntrypointVLD
13 VAProfileMPEG2Simple : VAEntrypointEncSlice
14 VAProfileMPEG2Main : VAEntrypointVLD
15 VAProfileMPEG2Main : VAEntrypointEncSlice
16 VAProfileH264ConstrainedBaseline: VAEntrypointVLD
17 VAProfileH264ConstrainedBaseline: VAEntrypointEncSlice
18 VAProfileH264Main : VAEntrypointVLD
19 VAProfileH264Main : VAEntrypointEncSlice
20 VAProfileH264High : VAEntrypointVLD
21 VAProfileH264High : VAEntrypointEncSlice
22 VAProfileH264MultiviewHigh : VAEntrypointVLD
23 VAProfileH264StereoHigh : VAEntrypointVLD
24 VAProfileVC1Simple : VAEntrypointVLD
25 VAProfileVC1Main : VAEntrypointVLD
26 VAProfileVC1Advanced : VAEntrypointVLD
27 VAProfileJPEGBaseline : VAEntrypointVLD
28 VAProfileJPEGBaseline : VAEntrypointEncPicture
29 VAProfileVP8Version0_3 : VAEntrypointVLD
30 VAProfileHEVCMain : VAEntrypointVLD
Leider meldet der N3700 eine Fehler beim Aufruf mit ffmpeg.
1 ffmpeg: i965_encoder.c:1692: intel_enc_hw_context_init: Assertion `encoder_context->mfc_context' failed.
Dann habe ich die non-free Pakete in /etc/apt/sources.list hinzugefügt. Nach einem "apt update", kann man die VAAPI non-free Treiber hinzugfügen.
1sudo apt update
2sudo apt install intel-media-va-driver-non-free i965-va-driver-shaders
1vainfo
1libva info: VA-API version 1.17.0
2libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/iHD_drv_video.so
3libva info: Found init function __vaDriverInit_1_17
4libva error: /usr/lib/x86_64-linux-gnu/dri/iHD_drv_video.so init failed
5libva info: va_openDriver() returns 1
6libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/i965_drv_video.so
7libva info: Found init function __vaDriverInit_1_8
8libva info: va_openDriver() returns 0
9vainfo: VA-API version: 1.17 (libva 2.12.0)
10vainfo: Driver version: Intel i965 driver for Intel(R) CherryView - 2.4.1
11vainfo: Supported profile and entrypoints
12 VAProfileMPEG2Simple : VAEntrypointVLD
13 VAProfileMPEG2Simple : VAEntrypointEncSlice
14 VAProfileMPEG2Main : VAEntrypointVLD
15 VAProfileMPEG2Main : VAEntrypointEncSlice
16 VAProfileH264ConstrainedBaseline: VAEntrypointVLD
17 VAProfileH264ConstrainedBaseline: VAEntrypointEncSlice
18 VAProfileH264Main : VAEntrypointVLD
19 VAProfileH264Main : VAEntrypointEncSlice
20 VAProfileH264High : VAEntrypointVLD
21 VAProfileH264High : VAEntrypointEncSlice
22 VAProfileH264MultiviewHigh : VAEntrypointVLD
23 VAProfilSH264MultiviewHigh : VAEntrypointEncSlice
24 VAProfileH264StereoHigh : VAEntrypointVLD
25 VAProfileH264StereoHigh : VAEntrypointEncSlice
26 VAProfileVC1Simple : VAEntrypointVLD
27 VAProfileVC1Main : VAEntrypointVLD
28 VAProfileVC1Advanced : VAEntrypointVLD
29 VAProfileNone : VAEntrypointVideoProc
30 VAProfileJPEGBaseline : VAEntrypointVLD
31 VAProfileJPEGBaseline : VAEntrypointEncPicture
32 VAProfileVP8Version0_3 : VAEntrypointVLD
33 VAProfileVP8Version0_3 : VAEntrypointEncSlice
34 VAProfileHEVCMain : VAEntrypointVLD
Danch sind die Einträge "VAProfileH264MultiviewHigh: VAEntrypointEncSlice" und "VAProfileH264StereoHigh : VAEntrypointEncSlice" hinzugekommen.
Konvertierung
Beim Aufruf der Konvertierung mit ffmpeg, muss nun der richtige Hardwareencoder angegeben werden. Das erfolgt mit dem Parameter -c:v gefolgt von Namen des Encoders.
Bei Intel ist es h264_vaapi. Beim Rapsberry Pi 4 ist es h264_v4l2m2m.
Bei Intel muss man auch den Pfad zum VAAPI-Device angeben (/dev/dri/renderD128).
Der Input Video im Beispiel ist eine MPEG2-AVI Datei aus einer Fernsehaufzeichnung, sie muss ebenfalls angegeben werden. Das Ziel ist eine mp4-Datei.
Wenn keine Qualitätseintstellungen angegeben werden, wird die Defaulteinstellung genommen. Je nach Encoder sollte man aber eine Datenrate oder Qualität dafür definieren.
Intel (Default Q20):
1time ffmpeg -hwaccel vaapi -hwaccel_output_format vaapi -hwaccel_device /dev/dri/renderD128 -i input.avi -c:v h264_vaapi output.mp4
2time ffmpeg -hwaccel vaapi -hwaccel_output_format vaapi -vaapi_device /dev/dri/renderD128 -i input.avi -codec:v h264_vaapi output.mp4
Raspberry Pi (Average bitrate):
1time sudo ffmpeg -i input.avi -c:v h264_v4l2m2m -b:v 2048k output.mp4
Ergebnis
Prozessor | Speed | Dauer | Dateigröße (kiB) | Datenrate/Qualität |
---|---|---|---|---|
Intel U4600 | x2,4 | |||
Intel U4600 HW | x15 | 3m7s | 760.882 kiB | Default: Q20 |
Intel N3700 | x1,3 | |||
Intel N3700 HW | x2,6 | |||
Pi 4 | x1,2 | |||
Pi 4 HW | x7,3 | 6m25s | 104.191 kiB | |
Pi 4 HW | x7,3 | 6m32s | 639.202 kiB | -b:v 2048k |
Der Geschwindigkeits zwischen Software und Hardwareencoder ist enorm. Bei Intel von 2,4-fache auf 15-fache. Damit wird das 45 Minuten Video in nur 3 Minuten konvertiert.
Am langsamen N3700 Prozessor ist die Leistung des Hardwareencoders sehr gering und es wird nur eine Verdopplung geschafft. Besser als nichts, aber im Vergleich zu richtigen Mobil Prozessor viel zu langsam.
Überraschend schnell ist auch der Raspberry Pi 4 der in weniger als 7 Minuten das Video konvertiert. Er ist zwar langsamer als Intel U4600 aber weit schneller als der vergleichbare Intel N3700 Prozessor.
Nach dem CPU-Vergleich habe ich mir aber auch eine nVidia GPU unter Windows mit der Software Handbrake angesehen. Die konnte das Video noch schneller konvertieren als der Intel Prozessor! Wobei das Programm die Hardwarekodierung mit meiner Desktop Skylake Intel CPU nicht beherrschte.