-
Notifications
You must be signed in to change notification settings - Fork 21
Hardware decoding and encoding on amd64
We can use cheap atom hardware for decoding and encoding in software.
- There is support in ffmpeg and gstreamer (va api): https://en.wikipedia.org/wiki/Intel_Quick_Sync_Video#Linux
- Any somewhat half recent hardware, starting from Sandy bridge (2011) has support for this: https://en.wikipedia.org/wiki/Intel_Quick_Sync_Video#Hardware_decoding_and_encoding
- https://cgit.freedesktop.org/gstreamer/gstreamer-vaapi/tree/README#n55
Install some required packages:
apt install gstreamer1.0-vaapi i965-va-driver vainfo
Let's see what hardware decoding and encoding capabilities our hardware has:
vainfo libva info: VA-API version 1.4.0 libva info: va_getDriverName() returns 0 libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/i965_drv_video.so libva info: Found init function __vaDriverInit_1_4 libva info: va_openDriver() returns 0 vainfo: VA-API version: 1.4 (libva 2.4.0) vainfo: Driver version: Intel i965 driver for Intel(R) Sandybridge Mobile - 2.3.0 vainfo: Supported profile and entrypoints VAProfileMPEG2Simple : VAEntrypointVLD VAProfileMPEG2Main : VAEntrypointVLD VAProfileH264ConstrainedBaseline: VAEntrypointVLD VAProfileH264ConstrainedBaseline: VAEntrypointEncSlice VAProfileH264Main : VAEntrypointVLD VAProfileH264Main : VAEntrypointEncSlice VAProfileH264High : VAEntrypointVLD VAProfileH264High : VAEntrypointEncSlice VAProfileH264StereoHigh : VAEntrypointVLD VAProfileVC1Simple : VAEntrypointVLD VAProfileVC1Main : VAEntrypointVLD VAProfileVC1Advanced : VAEntrypointVLD VAProfileNone : VAEntrypointVideoProc
Our hardware (Sandy Bridge) does not support h264 Baseline decoding or encoding! We have this confirmed by testing!
Luckily, our boxes' h264 streams are high profile:
ffprobe tcp://185.175.218.128:8898/?timeout=2000000 Input #0, mpegts, from 'tcp://185.175.218.128:8898/?timeout=2000000': Duration: N/A, start: 13814.131344, bitrate: N/A Program 1 Metadata: service_name : Service01 service_provider: FFmpeg Stream #0:0[0x100]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(progressive), 1920x1080 [SAR 1:1 DAR 16:9], 59.94 fps, 59.94 tbr, 90k tbn, 119.88 tbc Stream #0:1[0x101]: Audio: aac (LC) ([15][0][0][0] / 0x000F), 48000 Hz, stereo, fltp, 234 kb/s
Prerequisites:
apt install i965-va-driver-shaders
ffmpeg -hwaccel vaapi -hwaccel_output_format vaapi -hwaccel_device /dev/dri/renderD128 -i vaapi_test/h264high_audio.mp4 -c:v h264_vaapi /tmp/output.mp4
https://trac.ffmpeg.org/wiki/Hardware/VAAPI http://www.ffmpeg.org/ffmpeg-codecs.html#VAAPI-encoders
Minimal example:
ffmpeg -hwaccel vaapi -hwaccel_output_format vaapi -hwaccel_device /dev/dri/renderD128 -i tcp://185.175.218.128:8898 -c:v h264_vaapi /tmp/output.mp4
Working source-something script. Note that you need to do hwdownload to get the data to you from the GPU, and it helps if you do the scaling in the card before getting it to the rest. Not sure if FPS and SAR/DAR can be handled in there.
#!/bin/sh confdir="`dirname "$0"`/../config/" . ${confdir}/defaults.sh . ${confdir}/config.sh ffmpeg -y -nostdin -hwaccel vaapi -hwaccel_output_format vaapi -hwaccel_device /dev/dri/renderD128 \ -i "${SOURCE_CAM}" \ -ac 2 \ -filter_complex " [0:v] scale_vaapi=w=$WIDTH:h=$HEIGHT [v2]; [v2] hwdownload,format=nv12,format=yuv420p [v1]; [v1] scale=$WIDTH:$HEIGHT,fps=$FRAMERATE,setdar=16/9,setsar=1 [v] ; [0:a] aresample=$AUDIORATE [a] " \ -map "[v]" -map "[a]" \ -pix_fmt yuv420p \ -c:v rawvideo \ -c:a pcm_s16le \ -f matroska \ tcp://localhost:10000
- http://www.thinkwiki.org/wiki/Category:X220== intel 2xxx cpu == crap h264 encoding
- http://www.thinkwiki.org/wiki/Category:X240== intel 4xxx cpu == ? h264 encoding
- http://www.thinkwiki.org/wiki/Category:X250== intel 5xxx cpu == decent h264 encoding
- https://ark.intel.com/content/www/us/en/ark/products/83254/intel-nuc-kit-nuc5i5ryk.html == intel 5250 cpu == decent h264 encoding
- www.intel.com/content/dam/www/public/us/en/documents/product-briefs/atom-x5-processor-z8300-product-brief.pdf = intel atom x5-z8350 : 4 cores, probably similar or better vaapi performance
We're running wayland, so let's start a weston session:
apt install weston LANG=C weston weston-terminal time gst-launch-1.0 -v filesrc location=/tmp/test_video_only.mp4 ! qtdemux ! vaapidecodebin ! vaapisink fullscreen=true real=2m21.558s user=0m2.238s sys=0m1.516s
Let's compare to non-accelerated:
time mpv /tmp/test.mp4 Playing: /tmp/test.mp4 (+) Video --vid=1 (*) (h264 1920x1080 25.000fps) VO: [gpu] 1920x1080 yuv420p V: 00:02:21 / 00:02:21 (99%) Exiting... (End of file) real 2m21,818s user 0m57,474s sys 0m1,475s
time gst-launch-1.0 -v filesrc location=/tmp/test.mp4 ! qtdemux ! vaapidecodebin ! vaapih264enc rate-control=cbr tune=high-compression ! qtmux ! filesink location=/tmp/testdecode_reencode.mp4 real 0m17.031s user 0m1.738s sys 0m1.386s
This works, but it's not using vaapi h264 decoding:
gst-launch-1.0 filesrc location=/tmp/test.mp4 ! qtdemux name=demux demux.audio_0 ! queue ! decodebin ! audioconvert ! audioresample ! autoaudiosink demux.video_0 ! queue ! decodebin ! autovideosink
Setting gst debug levels might be helpful to discover some pipeline elements:
gst-launch-1.0 --gst-debug-level=2 filesrc location=/tmp/test.mp4 ! qtdemux name=demux demux.audio_0 ! queue ! decodebin ! audioconvert ! audioresample ! autoaudiosink demux.video_0 ! queue ! decodebin ! autovideosink
One can visually examine the pipeline playbin generates:
cd /tmp export GST_DEBUG_DUMP_DOT_DIR='/tmp/' gst-launch-1.0 -v playbin uri=file:///tmp/test.mp4 ls -1 *.dot | xargs -I{} dot -Tpng {} -o{}.png eog *.png