Pull to refresh

Эффективное кодирование видео в Linux c Nvidia NVENC: часть 1, общая

Reading time 4 min
Views 28K

Эта статья содержит практические сведения, полезные для организации эффективного кодирования видео на Linux с использованием последних видеопроцессоров Nvidia.
Чем не является эта статья:
  • Не является пособием по выбору технологии аппаратного кодирования или агитацией в пользу описываемой. Кроме Nvidia NVENC есть Intel QuickSync, есть AMD VCE, наверняка есть и ещё что-то. Все эти технологии имеют разные характеристики, которые трудно даже уложить на одну шкалу для сравнения. Тем не менее, я сделал свой выбор.
  • Не является претензией на самый быстрый/качественный способ кодирования. По причинам, указанным выше.

Об NVENC


Nvidia NVENC это технология, позволяющая кодировать видео в H.264 (и H.265 для последних процессоров Maxwell) силами GPU со скоростями несколько сот кадров в секунду (в зависимости от профиля и разрешения). Вендор предоставляет возможность использования этой технологии в виде набора разработчика NVENC SDK.

Реализация


Имеется множество утилит для различных платформ, которые в каком-то виде дают доступ к функционалу SDK. В марте 2015 года вышел релиз ffmpeg, который включил в себя поддержку NVENC. ffmpeg занимает центральное положение среди всего множества свободного и не очень ПО для работы с видео, поэтому с практической точки зрения он наиболее интересен. Этим инструментом можно и обрабатывать видеофайлы (1, 2), и вести потоковое вещание (1, 2). С момента мартовского релиза вышел ещё один, который включил в себя ещё больше опций для кодека nvenc и поддержку H.265 (HEVC).

Сборкой FFmpeg с поддержкой NVENC мы и займёмся.

Развёртывание

Для создания рабочей конфигурации нам потребуется:
  • Одна видеокарта Nvidia на ядре Kepler или Maxwell. На мой взгляд самый интересный выбор это GTX 970 — процессор Maxwell второго поколения (GM204) за 300$.
  • Один линукс типовой (ubuntu 14.04) на компьютере с видеокартой.


Драйверы и рантайм CUDA

Драйверы и библиотеки установить за раз одним пакетом. Из репозитория лучше ничего не использовать.
sudo apt-get update
sudo apt-get -y install axel build-essential dkms
axel 'http://developer.download.nvidia.com/compute/cuda/7_0/Prod/local_installers/cuda_7.0.28_linux.run'
chmod +x cuda_7.0.28_linux.run
sudo ./cuda_7.0.28_linux.run

На все вопросы уважаемого компьютера следует ответить утвердительно. После установки — перезагрузить.

Заголовочные файлы nvenc

Для сборки приложений с nvenc sdk неободимы некоторые заголовочные файлы. Раньше их необходимо было стягивать из виндовой версии SDK. Но прогресс идёт семимильными шагами и теперь этот файл можно стянуть из примеров в линуксовом SDK. Найдите в примерах (были установлены вместе с рантаймом и драйверами на предыдущем шаге) файлы
nvCPUOPSys.h
nvEncodeAPI.h
nvFileIO.h
NvHWEncoder.h
nvUtils.h

и положите их в /usr/include. Они потребуются только один раз, при сборке ffmpeg. На всех машинах они не нужны.

FFMPEG

Начать его сборку лучше с установки всех сборочных зависимостей.
sudo apt-get build-dep libav
sudo apt-get install -y libfdk-aac-dev libopencv-dev

Я мог что-то забыть, что-то может измениться. Чтобы найти недостающий для сборки файл, не стесняйтесь пользоваться apt-file:
$ sudo apt-get install apt-file -y
$ sudo apt-file update
$ apt-file search libxcb-shm.so.0
libxcb-shm0: /usr/lib/x86_64-linux-gnu/libxcb-shm.so.0
libxcb-shm0: /usr/lib/x86_64-linux-gnu/libxcb-shm.so.0.0.0


Скачиваем с сайта последнюю версию ffmpeg, распаковываем, конфигурируем, собираем и устанавливаем:
axel 'http://ffmpeg.org/releases/ffmpeg-2.7.1.tar.bz2'
tar xf ffmpeg-2.7.1.tar.bz2
cd ffmpeg-2.7.1
./configure --cpu=native --enable-pthreads --extra-version=habrahabr.ru --enable-bzlib --enable-libdc1394 --enable-libfreetype --enable-frei0r --enable-gnutls --enable-libgsm --enable-libmp3lame --enable-librtmp --enable-libopencv --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-vaapi --enable-vdpau --enable-libvorbis --enable-libvpx --enable-zlib --enable-libfdk-aac --enable-nonfree --enable-gpl --enable-swscale --enable-libcdio --enable-x11grab --enable-libx264 --enable-libxvid --enable-libopencore-amrnb --enable-version3 --enable-libopencore-amrwb --enable-version3 --enable-libvo-aacenc --enable-version3 --enable-libvo-amrwbenc --enable-version3 --enable-nvenc
make -j5
sudo make install

Собираем с libfdk-aac, он точно предпочтительнее имеющегося кодека aac. Кроме прочего, можно заметить опцию --enable-nvenc. В остальном параметры выбраны по мотивам билдспеки пакета libav в самом дистрибутиве ubuntu. После всех манипуляций должен появиться рабочий ffmpeg в /usr/local/bin/ffmpeg.

Применение

Запуск

Опции запуска все точно такие же, как при софтверном кодировании, но только вместо libx264 видеокодек будет называться nvenc (он же nvenc_h264) для h.264 и nvenc_hevc для h.265.
/usr/local/bin/ffmpeg -i input.mov -vcodec nvenc -b:v 5000k -r 30 ... output.mp4


Производительность и качество

Чтобы произвести 1 час видео в 4х качествах с хорошей точностью транскодинга, нужно или потратить примерно 1 час машинного времени двух шестиядерных ксеонов, или чуть более получаса времени десктопа с такой видеокартой. Качество результатов получается неотличимое от программного кодека x264 с аналогичными установками.

Ограничения

Увы и ах, Nvidia ввела ограничение: на обычных десктопных видеокартах нельзя кодировать больше двух потоков видео одновременно. Снятию этого ограничения будет посвящена моя следующая статья, которая, вероятно, будет интересна немного другому кругу читателей.
Tags:
Hubs:
+16
Comments 21
Comments Comments 21

Articles