Шпаргалка по сборке FFmpeg с NVENC H.264 и H.265 на последней Ubuntu LTS (18.04). Использование мощи видеокарты от NVIDIA для обработки видео, в моем случае 1080p60 обработалось быстрее в 4 раза чем на процессоре, ну и при этом совершенно не грузило систему (видеокарта тоже даже не нагрелась).
Лирическое отступление
Вот уже пару лет есть работающая схема по добавлению потока RTSP камер наблюдения в HomeKit и вот она. Это плагин для HomeBridge, есть иные костыли, но суть одна, всё завязано на конвертации RTSP потока в RTMP и скармливании его home.app. Самым простым способом сделать это является перекодировка, а так как обычно под рукой линуксоподобная система — ffmpeg (avconv, прочее, но в первую очередь именно ffmpeg).
Для умных домов преимущественно используют Raspberry Pi и оно не может нормально кодировать видео в силу слабого процессора. Сборка ffmpeg (в дистрибутивах Raspbian его нет именно потому что нормальный человек не должен встречаться с такими тормозами) на малинке занимает 40-50 минут и работает оно откровенно плохо, кадры дропаются, малинка греется даже при одном потоке, а если двое хотят одновременно посмотреть камеры происходит коллапс. Даже h264_omx проблему полностью не решает, нужно нормальное железо и это обычный компьютер. Даже вшивый Celeron вполне прилично справляется с задачей, но есть способ еще лучше.
У меня есть ненужная система на Intel(R) Celeron(R) CPU G3930 @ 2.90GHz
и GeForce GTX 1060
, с этим железом можно добиться удивительных результатов малой кровью, не загружая особо процессор и одновременно показывая видео с камер на 7 устройств (может и больше, у меня нету просто столько конечных устройств).
Сейчас мы соберем на последней серверной убунте FFmpeg с аппаратной поддержкой кодирования H.264 и оно будет быстрым, очень быстрым. В тестах видео fullhd кодировалось в 4-6 раз быстрее, чем стандартным кодеком x264 через процессор.
Всякое:
Ставим пакеты
sudo apt install build-essential git yasm unzip wget mc sysstat nasm
libavcodec-dev libavformat-dev libavutil-dev pkgconf g++ freeglut3-dev
libx11-dev libxmu-dev libxi-dev libglu1-mesa libglu1-mesa-dev libx265-dev libnuma-dev
Драйвера:
Ставим CUDA с родного сайта, инструкции тут (но они могли измениться, лучше кликнуть по ссылке)
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
sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub
sudo add-apt-repository "deb http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/ /"
sudo apt-get update
sudo apt-get -y install cuda
reboot
Проверяем что всё работает и драйвера встали
nvidia-smi
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 418.87.00 Driver Version: 418.87.00 CUDA Version: 10.1 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
|===============================+======================+======================|
| 0 GeForce GTX 106... Off | 00000000:01:00.0 Off | N/A |
| 33% 28C P0 28W / 120W | 0MiB / 3019MiB | 0% Default |
+-------------------------------+----------------------+----------------------+
+-----------------------------------------------------------------------------+
| Processes: GPU Memory |
| GPU PID Type Process name Usage |
|=============================================================================|
| No running processes found |
+-----------------------------------------------------------------------------+
Добавляем переменные в PATH. И так каждый раз после перезагрузки для сборки ffmpeg, потом не нужно.
export PATH=/usr/local/cuda-10.1/bin${PATH:+:${PATH}}
export LD_LIBRARY_PATH=/usr/local/cuda-10.1/lib${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
Качаем и ставим NVIDIA video codek SDK (нужна регистрация), указываем свою версию, а не 9.0.20:
unzip Video_Codec_SDK_9.0.20.zip
sudo cp Video_Codec_SDK_9.0.20/Samples/common.mk /usr/local/include/
Ставим FFmpeg
Самое нужное это собсно поддержка nv-codec
git clone https://git.videolan.org/git/ffmpeg/nv-codec-headers.git
cd nv-codec-headers
make
sudo make install
Поддержка H.264. Не уверен что оно нужно на 18.04 (у меня был автоматически установлен), но на всякий случай последняя версия:
git clone https://code.videolan.org/videolan/x264.git
cd x264/
./configure --disable-cli --enable-static --enable-shared --enable-strip
make
sudo make install
sudo ldconfig
Сам FFmpeg:
git clone git://source.ffmpeg.org/ffmpeg.git
cd ffmpeg/
./configure --enable-nonfree --enable-nvenc --enable-libx264 --enable-libx265 --enable-gpl --enable-cuda --enable-cuvid
make
sudo make install
Убеждаемся что мы можем кодировать H.264 и H.265 с помощью видеокарты:
ptath@castle:~/ffmpeg$ ffmpeg -codecs | grep nvenc
ffmpeg version N-94809-g12b909ba31 Copyright (c) 2000-2019 the FFmpeg developers
built with gcc 7 (Ubuntu 7.4.0-1ubuntu1~18.04.1)
configuration: --enable-nonfree --enable-nvenc --enable-libx264 --enable-libx265 --enable-gpl --enable-cuda --enable-cuvid
libavutil 56. 35.100 / 56. 35.100
libavcodec 58. 56.101 / 58. 56.101
libavformat 58. 32.104 / 58. 32.104
libavdevice 58. 9.100 / 58. 9.100
libavfilter 7. 58.102 / 7. 58.102
libswscale 5. 6.100 / 5. 6.100
libswresample 3. 6.100 / 3. 6.100
libpostproc 55. 6.100 / 55. 6.100
DEV.LS h264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (decoders: h264 h264_v4l2m2m h264_cuvid ) (encoders: libx264 libx264rgb h264_nvenc h264_v4l2m2m nvenc nvenc_h264 )
DEV.L. hevc H.265 / HEVC (High Efficiency Video Coding) (decoders: hevc hevc_cuvid ) (encoders: libx265 nvenc_hevc hevc_nvenc )
О да, мы можем =) А теперь тесты:
wget http://download4.dvdloc8.com/trailers/divxdigest/i_am_legend-1080p_blu-ray_trailer.zip
unzip i_am_legend-1080p_blu-ray_trailer.zip
time ffmpeg -i I\ Am\ Legend\ -\ Trailer.mp4 -vcodec libx264 -b:v 5M -acodec copy Output_libx264.mp4
...
real 2m33,211s
user 4m58,844s
sys 0m0,608s
time ffmpeg -i I\ Am\ Legend\ -\ Trailer.mp4 -vcodec libx265 -b:v 5M -acodec copy Output_libx265.mp4
...
real 8m17,279s
user 15m57,109s
sys 0m0,588s
time ffmpeg -i I\ Am\ Legend\ -\ Trailer.mp4 -vcodec h264_nvenc -b:v 5M -acodec copy Output_h264_nvenc.mp4
...
real 0m20,966s
user 0m27,845s
sys 0m0,620s
time ffmpeg -i I\ Am\ Legend\ -\ Trailer.mp4 -vcodec hevc_nvenc -b:v 5M -acodec copy Output_hevc_nvenc.mp4
...
real 0m20,990s
user 0m28,007s
sys 0m0,650s
Собственно мы наблюдаем космическую скорость, особенно когда дело доходит до H.265 — с нашим новым кодеком мы справляемся за 20 секунд вместо 8 с половиной минут через x265 (стоит отметить что процессор — Celeron, на i7 должно быть побыстрей конечно).
Практическое применение — обработка видео со всяких там action-камер, ну и конечно же в системах умного дома на базе HomeKit. В дополнение к малинке ничто не мешает отдельно использовать нормальный сервер исключительно под видео.