image

Данная статья была написана по мотивам статьи Эффективное кодирование видео в Linux c Nvidia NVENC: часть 1, общая, однако имеет свои особенности и в отличие от оригинальной статьи, на момент написания которой не было выпущено патча, о котором пойдет речь дальше, я применил переработанный патч Nvidia Acceleration к FFmpeg 3.0.2, получив помимо энкодера nvenc еще и быстрый фильтр ресайза — nvresize.

В итого я получил возможность аппаратно кодировать видео в H.264 и HEVC при помощи видеокарты Nvidia GTX 960 на достаточно слабом компьютере (Xeon L5420) со скоростью (для H.264), превышающей возможности данного процессора до 10 раз (и в 3 раза относительно Core i7)! Причем на моем любимом Debian 8 Jessie.

Итак, начнем!

Технология


Nvidia NVENC это технология, обеспечивающая кодирование видео в H.264 и HEVC на вычислительных мощностях GPU. Важное замечание: сколь-нибудь качественное и быстрое кодирование на момент написания статьи (май 2016) могут обеспечить только карты второго поколения Maxwell, и для десктопных это: GM206 (GTX 950, GTX 960), GM204 (GTX 970 и GTX 980) (для справки: есть еще дорогие проф.линейки Nvidia Tesla/Quadro/GRID, полный перечень можно найти здесь). Причем NVENC модуль работает с одинаковой скоростью на всех картах и количество CUDA ядер не влияет на производительность, как бы странно это не звучало, поэтому брать старшие версии имеет смысл только если платформа используется (помимо кодирования) для игр, даже более того, карты на GM206 целесообразнее т.к. помимо энкодера, получили еще и аппаратный HEVC декодер. Важное примечание: вся линейка GeForce имеет лицензионное ограничение в 2 одновременных потока. Его можно попробовать обойти методом, указанным во второй части статьи YourChief

Реализация (FFmpeg)


Все многообразие реализаций Nvidia CUDA можно посмотреть по ссылке. От себя хочу сказать что для видео наиболее распространенным является популярный инструмент — FFmpeg. Его мы и будем использовать.

Аппаратное обеспечение


Хоть это и банально, но перечислю минимально необходимый набор аппаратных требований (основан на реальном опыте):
  1. Материнская плата: с поддержкой PCI-E. Рекомендую платформу Intel из-за тесной связи Intel-Nvidia и личной приязни. Да простят меня поклонники AMD!
  2. Процессор: двухядерный, уровня не ниже Core2 Duo. Рекомендую Core i3 и некоторые дешевые Xeon (да-да!).
  3. Память: DDR2/3/4, минимум 2 Гб. Интересный факт, при двух потоках кодирования суммарное потребление памяти у меня ~0.7 Гб.
  4. Видеокарта: любая видеокарта Nvidia 900 Series (Рекомендую GM206: GTX 950, GTX 960 или GM204: GTX 970, GTX 980). 2 Гб или 4 Гб, геймерская или нет — не важно! Главное, следите за габаритами и учтите что у всех моделей GTX 960 что я видел, дополнительное питание подключается сверху.
  5. БП ATX с доп.коннектором питания (6 пин для нашей задачи хватит). Рекомендую мощность не менее 400 Вт.

Программное обеспечение


Дальнейшее повествование опирается на определенный базис из систем, программ и их конкретных версий. Особо отмечу что я специально использовал Debian, а не Ubuntu, для которой есть даже офф. пакеты SDK, т.к. хотел попробовать настроить все в любимом дистрибутиве.
  1. Операционная система: Debian 8 Jessie с дополнительным репозиторием Deb Multimedia
  2. Nvidia CUDA 7.5.18
  3. Nvidia SDK 6.0.1
  4. FFmpeg 3.0.2
  5. Патч Nvidia Acceleration, изменен мной для совместимости с FFmpeg 3.0.2

Сборка


Самый важный из файлов — это первый, с драйвером. Только он и нужен если вы сразу хотите установить пакет после его сборки.
Скачиваем файлы, которые нам понадобятся для дальнейшей работы. Размер ~1.3 Гб.
cd /usr/src
wget 'http://developer.download.nvidia.com/compute/cuda/7.5/Prod/local_installers/cuda_7.5.18_linux.run'
wget 'https://developer.nvidia.com/video-sdk-601' -O 'video-sdk-601.zip'
wget 'http://developer.download.nvidia.com/compute/redist/ffmpeg/1511-patch/cudautils.zip'
wget 'http://ffmpeg.org/releases/ffmpeg-3.0.2.tar.bz2'
wget 'http://kuzko.com/dl/ffmpeg_NVIDIA_gpu_acceleration.3.0.2.patch'
MD5 файлов
4b3bcecf0dfc35928a0898793cf3e4c6  cuda_7.5.18_linux.run
24af45272ed2881f88ed534d3211b584  video-sdk-601.zip
f3f890bd314a568c47191810453cad2c  cudautils.zip
7db5efb1070872823143e1365fdfcd53  ffmpeg-3.0.2.tar.bz2
a4f59f92675e02a0fa5c6cd124eda64e  ffmpeg_NVIDIA_gpu_acceleration.3.0.2.patch

SHA1 файлов
0f366a88968b9eee01044de197e27764bc1567d6  cuda_7.5.18_linux.run
e57c7b4cfb298d4c725a0bb4477928e228dabb1c  video-sdk-601.zip
edc818bef432d708466c5454974b9851523a86ba  cudautils.zip
c40731a221fbfaa50671d69fe894bedd664f91e2  ffmpeg-3.0.2.tar.bz2
f305832ed42beeff7d7c26a00f79668b63b322ec  ffmpeg_NVIDIA_gpu_acceleration.3.0.2.patch


Добавляем репозиторий Deb Multimedia (он требуется если вы хотите получить/использовать FFmpeg, который максимально приближен к тому, который выкладывает Deb Multimedia). Этот репозиторий обязателен для моей сборки!
Для ленивых
Создаем файл с одной строчкой:
echo 'deb http://www.deb-multimedia.org jessie main non-free' > /etc/apt/sources.list.d/deb-multimedia.list
Далее выполняем
apt-get update
И устанавливаем keyring:
apt-get install deb-multimedia-keyring

Теперь обновляем систему и ставим требуемые для сборки драйвера пакеты. Этот шаг также необходим!
Необходимые действия
apt-get update
apt-get -y dist-upgrade
apt-get -y install build-essential dkms ccache pkg-config libglu1-mesa-dev libx11-dev libxi-dev libxmu-dev

Устанавливаем Nvidia Driver, принимаем соглашение (accept), все остальные ответы по-умолчанию. Если предупредят что система не является подходящей, не переживайте, это нормально! Можно передать ключ -silent для быстрой установки, но лучше пройдитесь сами.
Необходимые действия
cd /usr/src
chmod +x cuda_7.5.18_linux.run
./cuda_7.5.18_linux.run

Выбор дальнейшего действия зависит от вас. Вы можете либо довериться мне и скачать готовый deb файл (создан через checkinstall) и пропустить последующие шаги, либо осуществить сборку вручную, установив необходимые библиотеки и собрав пакет самостоятельно через checkinstall.
Я джедай, чего мне бояться?
cd /usr/src
wget 'http://kuzko.com/dl/ffmpeg_3.0.2-nvenc-7.5.18-nvresize-cudautils-20160523-1_amd64.deb'
dpkg -i ffmpeg_3.0.2-nvenc-7.5.18-nvresize-cudautils-20160523-1_amd64.deb
apt-get -f install

Если вы выбрали светлую сторону силы, то давайте продолжим, установим библиотеки, требуемые для сборки (для этого помимо всего прочего и был нужен Deb Multimedia), подготовим заголовочные файлы, cudautils и применим патч:
Необходимые действия
apt-get install -y --force-yes libfdk-aac-dev libopencv-dev libiec61883-dev libavc1394-dev libass-dev libbluray-dev libbs2b-dev libkvazaar-dev libilbc2 libilbc-dev libopenh264-dev libsnappy-dev libsoxr-dev libxv1 libxcb-shape0
cd /usr/src
unzip video-sdk-601.zip;
/bin/cp -prf nvidia_video_sdk_6.0.1/Samples/common/inc/nvCPUOPSys.h /usr/include
/bin/cp -prf nvidia_video_sdk_6.0.1/Samples/common/inc/nvEncodeAPI.h /usr/include
/bin/cp -prf nvidia_video_sdk_6.0.1/Samples/common/inc/nvFileIO.h /usr/include
/bin/cp -prf nvidia_video_sdk_6.0.1/Samples/common/inc/NvHWEncoder.h /usr/include
/bin/cp -prf nvidia_video_sdk_6.0.1/Samples/common/inc/nvUtils.h /usr/include
unzip cudautils.zip
cd cudautils
make
tar zxf ffmpeg-3.0.2.tar.bz2
cd ffmpeg-3.0.2
patch -Np1 -i ../ffmpeg_NVIDIA_gpu_acceleration.3.0.2.patch

Теперь мы готовы выполнить три основных команды по сборке пакета (configure / make / checkinstall).
Отмечу несколько моментов, которые вы можете изменить под себя:
  1. Были добавлены --enable-nvenc и --enable-nvresize (куда же без них!)
  2. Модифицированы --extra-cflags и --extra-ldflags, чтобы включить в себя cudautils
  3. Убраны --enable-opencl (не смог найти библиотеку для него) и --enable-libtesseract (лишний модуль на мой взгляд)
  4. FFmpeg собирается без --enable-shared, хотя ничто не мешает вам его вернуть назад
  5. make -j10 можете менять на специфичное для вашей системы (я использовал build-машину, где threads+2=10)
  6. Зависимости в checkinstall я вставил для того, чтобы при установке с нуля, было достаточно выполнить apt-get -f install и установить требуемые пакеты, а не выискивать через ldd что-же еще нужно установить
  7. Также из-за несовершенства checkinstall пришлось выполнить несколько необязательных действий (удаление конфликтующих dev пакетов и создании папки /usr/share/ffmpeg)
Итак, идем за кофе, но только после отработки configure
cd /usr/src
cd ffmpeg-3.0.2
./configure --prefix=/usr --extra-cflags='-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -I../cudautils ' --extra-ldflags='-Wl,-z,relro -L../cudautils ' --cc='ccache cc' --enable-libmp3lame --enable-gpl --enable-nonfree --enable-libvorbis --enable-pthreads --enable-libfaac --enable-libxvid --enable-postproc --enable-x11grab --enable-libgsm --enable-libtheora --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libx264 --enable-libspeex --enable-nonfree --enable-libvpx --enable-libschroedinger --disable-encoder=libschroedinger --enable-version3 --enable-libopenjpeg --enable-librtmp --enable-avfilter --enable-libfreetype --disable-decoder=amrnb --enable-libvo-amrwbenc --libdir=/usr/lib/x86_64-linux-gnu --disable-vda --enable-libbluray --enable-libcdio --enable-gnutls --enable-frei0r --enable-openssl --enable-libass --enable-libopus --enable-fontconfig --enable-libpulse --disable-mipsdsp --disable-mips32r2 --disable-msa --disable-mipsfpu --disable-mipsdspr2 --enable-libvidstab --enable-libzvbi --enable-avresample --enable-libutvideo --enable-libfdk-aac --enable-libx265 --enable-libbs2b --enable-libilbc --enable-libopenh264 --enable-libkvazaar --enable-libsnappy --enable-libsoxr --enable-libiec61883 --enable-vaapi --enable-libdc1394 --disable-altivec --shlibdir=/usr/lib/x86_64-linux-gnu --enable-nvenc --enable-nvresize
make -j10
apt-get -y remove libswscale-dev libavcodec-dev libswresample-dev libavutil-dev
mkdir -p /usr/share/ffmpeg
checkinstall --pkgname=ffmpeg --pkgversion "10:3.0.2-nvenc-7.5.18-nvresize-cudautils-`date +%Y%m%d`" --backup=no --requires='libcdio-paranoia1,libjack0,libasound2,libsdl1.2debian,libdc1394-22,libavc1394-0,libiec61883-0,libvidstab1.0,libbs2b0,libva1,libzvbi0,libx265-79,libx264-148,libvpx1,libvo-amrwbenc0,libutvideo15,libtheora0,libspeex1,libsoxr0,libsnappy1,libschroedinger-1.0-0,libopus0,libopenjpeg5,libopenh264-1,libopencore-amrwb0,libopencore-amrnb0,libmp3lame0,libkvazaar3,libilbc2,libgsm1,libfdk-aac1,libfaac0,libbluray1,libass5,libxcb-xfixes0,libcrystalhd3,libxvidcore4,libxv1,libxcb-shape0' --default

Если в результате вы получили deb файл, то принимайте мои поздравления!
Кстати, checkinstall может и ругнуться при установке пакета. Не страшно. Установите (если не установился) пакет вручную через dpkg -i ffmpeg_3.0.2-nvenc-7.5.18-nvresize-cudautils-20160523-1_amd64.deb и потом apt-get -f install для установки зависимостей.

Параметры nvenc и nvresize


Отчего-то, не все знают какие параметры принимает nvenc и nvresize, а для этого нужно всего лишь запустить ffmpeg с ключом -h:
ffmpeg -h encoder=nvenc_h264
Encoder nvenc_h264 [NVIDIA NVENC h264 encoder]:
    General capabilities: delay 
    Threading capabilities: none
    Supported pixel formats: yuv420p nv12
nvenc_h264 AVOptions:
  -preset            <string>     E..V.... Set the encoding preset (one of slow = hq 2pass, medium = hq, fast = hp, hq, hp, bd, ll, llhq, llhp, default) (default "hq")
  -profile           <string>     E..V.... Set the encoding profile (high, main, baseline)
  -level             <string>     E..V.... Set the encoding level restriction (auto, 1.0, 1.0b, 1.1, 1.2, ..., 4.2, 5.0, 5.1)
  -tier              <string>     E..V.... Set the encoding tier (main or high)
  -cbr               <boolean>    E..V.... Use cbr encoding mode (default false)
  -2pass             <boolean>    E..V.... Use 2pass encoding mode (default auto)
  -gpu               <int>        E..V.... Selects which NVENC capable GPU to use. First GPU is 0, second is 1, and so on. (from 0 to INT_MAX) (default 0)
  -delay             <int>        E..V.... Delays frame output by the given amount of frames. (from 0 to INT_MAX) (default INT_MAX)
  -enableaq          <boolean>    E..V.... set to 1 to enable AQ  (default false)
ffmpeg -h encoder=nvenc_hevc
Encoder nvenc_hevc [NVIDIA NVENC hevc encoder]:
    General capabilities: delay 
    Threading capabilities: none
    Supported pixel formats: yuv420p nv12
nvenc_hevc AVOptions:
  -preset            <string>     E..V.... Set the encoding preset (one of slow = hq 2pass, medium = hq, fast = hp, hq, hp, bd, ll, llhq, llhp, default) (default "hq")
  -profile           <string>     E..V.... Set the encoding profile (high, main, baseline)
  -level             <string>     E..V.... Set the encoding level restriction (auto, 1.0, 1.0b, 1.1, 1.2, ..., 4.2, 5.0, 5.1)
  -tier              <string>     E..V.... Set the encoding tier (main or high)
  -cbr               <boolean>    E..V.... Use cbr encoding mode (default false)
  -2pass             <boolean>    E..V.... Use 2pass encoding mode (default auto)
  -gpu               <int>        E..V.... Selects which NVENC capable GPU to use. First GPU is 0, second is 1, and so on. (from 0 to INT_MAX) (default 0)
  -delay             <int>        E..V.... Delays frame output by the given amount of frames. (from 0 to INT_MAX) (default INT_MAX)
  -enableaq          <boolean>    E..V.... set to 1 to enable AQ  (default false)
Важно: s и size в справке не указаны, хотя vf_nvresize.c их имеет! Еще добавлю что s и size это строки, а не WxH, поэтому надо передавать hd1080, hd720, pal, ntsc и прочие строковые обозначения разрешения. Полный их перечень можно получить тут.
ffmpeg -h filter=nvresize
Filter nvresize
  GPU accelerated video resizer.
    Inputs:
       #0: default (video)
    Outputs:
        dynamic (depending on the options)
nvresize AVOptions:
  outputs           <int>        ..FV.... set number of outputs (from 1 to 16) (default 1)
  readback          <int>        ..FV.... read result back to FB (from 0 to 1) (default 0)
  size              <string>     ..FV.... set video size (default false)
  s,                <string>     ..FV.... set video size (default false)
  gpu               <int>        ..FV.... Selects which NVENC capable GPU to use. First GPU is 0, second is 1, and so on. (from 0 to INT_MAX) (default 0)
  force_original_aspect_ratio <int>        ..FV.... decrease or increase w/h if necessary to keep the original AR (from 0 to 2) (default 0)

Целесообразность. Ради чего же все это?


Я не буду здесь приводить подробные бенчмарки (если только сообщество не попросит меня провести определенные тесты), их хватает в интернете, да и скорость кодирования непосредственно картой примерно одинакова и больше зависит от исходного видео, разрешения/битрейта кодируемого и дополнительной обработки (кодирование звука, наложение фильтров).
Вот некоторые цифры для тестовой (дешевой и древней!) системы на Xeon L5420 (4 ядра по 2.5 ГГц)
576p исходник, x264, битрейт выставлен в 3000k:
frame= 7500 fps= 58 q=-1.0 Lsize= 107951kB time=00:05:00.00 bitrate=2947.8kbits/s speed=2.32x
576p исходник, nvenc_h264, битрейт выставлен в 3000k:
frame= 7500 fps=804 q=-0.0 Lsize= 116997kB time=00:05:00.00 bitrate=3194.8kbits/s speed=32.2x
На 1080p исходнике (37 мегабит исходных в 10-15 мегабит) скорость 0.42x и 4.2x — Nvidia опять быстрее примерно в 10 раз.
При кодировании 1080p в HEVC на процессор больно смотреть, там цифры 0.08x и ниже, карта же около 3x выдает.

Для системы на Core i7 разница не такая большая, но все равно карта в 3-4 раза быстрее, чем x265 на HEVC 1080p (15000k) и в 13 раз на HEVC 576p (3000k). И это при том, что сам процессор i7 обычно стоит как GTX 960 и дороже.

Что касается качества. Я перфекционист, но считаю что есть множество применений для аппаратного кодирования, т.к. снижение качества на самом деле заметно слабо (смотрел как на проф.мониторе Dell 24", так и на телевизоре 60" — все с близкого расстояния) и только при т.н. pixel хантинге. Зато скорость делает возможным решение задач, которые обычно не способны выполняться в реальном времени на процессоре.

Я сознательно опустил подробности по скорости nvresize, кроме его параметров, т.к. хоть это и очень интересный и быстрый фильтр, но его использование выходит за рамки данной статьи.

Надеюсь, что мой труд не пропадет даром и поможет еще большему количеству людей приобщиться к технологии аппаратного кодирования, обойдя некоторые подводные камни, на решение которых я потратил достаточно много времени. Но это стоило того!

Обновления статьи


  • 25.05.2016: Добавил GTX 950 к списку поддерживаемых, это самый свежий GM206, как и GTX 960 и убрал не соответствующее действительности замечание про Quadro линейку, которая также вышла на базе GM204 и GM206.
Используете ли вы аппаратное кодирование видео?

Проголосовало 167 человек. Воздержалось 64 человека.

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

Поделиться с друзьями
-->

Комментарии (49)


  1. babylon
    24.05.2016 22:46

    Спасибо за статью.


  1. Prototik
    24.05.2016 23:40

    Никто не встерчался с ошибкой «No NVENC capable devices found»?
    Вроде, моя карточка уже как два поколения должна поддерживать NVENC, но не удалось пока запустить ни один найденый мною пример на аппартаное кодирование видео.


    1. alexkuzko
      24.05.2016 23:44

      Для начала убедитесь что драйвера установлены.
      Я такую ошибку видел когда на голую систему поставил свою сборку ffmpeg, а весь набор с драйверами (7.5.18) забыл установить.

      Также стоит посмотреть точно ли ваша карта поддерживает NVENC? Фактически, там только Kepler и Maxwell и все.


      1. Prototik
        24.05.2016 23:53

        Естественно драйвера установлены.

        Выхлоп CUDA-z


        1. S-ed
          25.05.2016 06:12

          Такая ошибка может быть следствием несовместимого пиксельного формата.
          Попробуйте добавить в строку ключ: -pix_fmt yuv420p
          По умолчанию ffmpeg проверяет yuv444p.
          Для информации используйте
          ffmpeg -h encoder=nvenc_h264
          или
          ffmpeg -h encoder=nvenc_hevc
          (https://trac.ffmpeg.org/wiki/HWAccelIntro)


          1. Prototik
            25.05.2016 14:57

            Теперь падает с OpenEncodeSessionEx failed: 0x2. Нагуглил, что вроде как это из-за ограничения в 2 кодирующих потока на систему, но мне и один то не удаётся закодировать :(

            ffmpeg -h encoder=nvenc_h264
            ffmpeg version 3.0.2 Copyright © 2000-2016 the FFmpeg developers
            built with gcc 6.1.1 (GCC) 20160501
            configuration: --prefix=/usr --extra-cflags=-I/usr/include/nvidia-sdk --extra-cxxflags='-std=gnu++98' --extra-ldflags='-Wl,-rpath -Wl,/opt/intel/mediasdk/lib64' --enable-rpath --enable-gpl --enable-version3 --enable-nonfree --disable-static --enable-shared --enable-avresample --enable-avisynth --enable-chromaprint --enable-decoder=atrac3 --enable-decoder=atrac3p --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gpl --enable-gray --enable-iconv --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcelt --enable-libdc1394 --enable-libdcadec --enable-libfaac --enable-libfdk-aac --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libiec61883 --enable-libilbc --enable-libkvazaar --enable-libmfx --enable-libmodplug --enable-libmp3lame --enable-libnut --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopencv --enable-libopenh264 --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-librubberband --enable-librtmp --enable-libschroedinger --enable-libshine --enable-libsmbclient --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtesseract --enable-libtheora --enable-libtwolame --enable-libutvideo --enable-libv4l2 --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxcb --enable-libxcb-shm --enable-libxcb-xfixes --enable-libxcb-shape --enable-libxvid --enable-libzimg --enable-libzmq --enable-libzvbi --enable-netcdf --enable-nvenc --enable-openal --enable-opencl --enable-opengl --enable-openssl --enable-x11grab
            libavutil 55. 17.103 / 55. 17.103
            libavcodec 57. 24.102 / 57. 24.102
            libavformat 57. 25.100 / 57. 25.100
            libavdevice 57. 0.101 / 57. 0.101
            libavfilter 6. 31.100 / 6. 31.100
            libavresample 3. 0. 0 / 3. 0. 0
            libswscale 4. 0.100 / 4. 0.100
            libswresample 2. 0.101 / 2. 0.101
            libpostproc 54. 0.100 / 54. 0.100
            Encoder nvenc_h264 [NVIDIA NVENC h264 encoder]:
            General capabilities: delay
            Threading capabilities: none
            Supported pixel formats: yuv420p nv12 yuv444p
            nvenc_h264 AVOptions:
            -preset E..V… Set the encoding preset (one of slow = hq 2pass, medium = hq, fast = hp, hq, hp, bd, ll, llhq, llhp, default) (default «medium»)
            -profile E..V… Set the encoding profile (high, main, baseline or high444p) (default «main»)
            -level E..V… Set the encoding level restriction (auto, 1.0, 1.0b, 1.1, 1.2, ..., 4.2, 5.0, 5.1) (default «auto»)
            -tier E..V… Set the encoding tier (main or high) (default «main»)
            -cbr E..V… Use cbr encoding mode (default false)
            -2pass E..V… Use 2pass encoding mode (default auto)
            -gpu E..V… Selects which NVENC capable GPU to use. First GPU is 0, second is 1, and so on. (from 0 to INT_MAX) (default 0)
            -delay E..V… Delays frame output by the given amount of frames. (from 0 to INT_MAX) (default INT_MAX)


            ffmpeg -h encoder=nvenc_hevc
            ffmpeg version 3.0.2 Copyright © 2000-2016 the FFmpeg developers
            built with gcc 6.1.1 (GCC) 20160501
            configuration: --prefix=/usr --extra-cflags=-I/usr/include/nvidia-sdk --extra-cxxflags='-std=gnu++98' --extra-ldflags='-Wl,-rpath -Wl,/opt/intel/mediasdk/lib64' --enable-rpath --enable-gpl --enable-version3 --enable-nonfree --disable-static --enable-shared --enable-avresample --enable-avisynth --enable-chromaprint --enable-decoder=atrac3 --enable-decoder=atrac3p --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gpl --enable-gray --enable-iconv --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcelt --enable-libdc1394 --enable-libdcadec --enable-libfaac --enable-libfdk-aac --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libiec61883 --enable-libilbc --enable-libkvazaar --enable-libmfx --enable-libmodplug --enable-libmp3lame --enable-libnut --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopencv --enable-libopenh264 --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-librubberband --enable-librtmp --enable-libschroedinger --enable-libshine --enable-libsmbclient --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtesseract --enable-libtheora --enable-libtwolame --enable-libutvideo --enable-libv4l2 --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxcb --enable-libxcb-shm --enable-libxcb-xfixes --enable-libxcb-shape --enable-libxvid --enable-libzimg --enable-libzmq --enable-libzvbi --enable-netcdf --enable-nvenc --enable-openal --enable-opencl --enable-opengl --enable-openssl --enable-x11grab
            libavutil 55. 17.103 / 55. 17.103
            libavcodec 57. 24.102 / 57. 24.102
            libavformat 57. 25.100 / 57. 25.100
            libavdevice 57. 0.101 / 57. 0.101
            libavfilter 6. 31.100 / 6. 31.100
            libavresample 3. 0. 0 / 3. 0. 0
            libswscale 4. 0.100 / 4. 0.100
            libswresample 2. 0.101 / 2. 0.101
            libpostproc 54. 0.100 / 54. 0.100
            Encoder nvenc_hevc [NVIDIA NVENC hevc encoder]:
            General capabilities: delay
            Threading capabilities: none
            Supported pixel formats: yuv420p nv12 yuv444p
            nvenc_hevc AVOptions:
            -preset E..V… Set the encoding preset (one of slow = hq 2pass, medium = hq, fast = hp, hq, hp, bd, ll, llhq, llhp, default) (default «medium»)
            -profile E..V… Set the encoding profile (high, main, baseline or high444p) (default «main»)
            -level E..V… Set the encoding level restriction (auto, 1.0, 1.0b, 1.1, 1.2, ..., 4.2, 5.0, 5.1) (default «auto»)
            -tier E..V… Set the encoding tier (main or high) (default «main»)
            -cbr E..V… Use cbr encoding mode (default false)
            -2pass E..V… Use 2pass encoding mode (default auto)
            -gpu E..V… Selects which NVENC capable GPU to use. First GPU is 0, second is 1, and so on. (from 0 to INT_MAX) (default 0)
            -delay E..V… Delays frame output by the given amount of frames. (from 0 to INT_MAX) (default INT_MAX)


            1. alexkuzko
              25.05.2016 15:16

              Так вы в линуксе кодируете или под Windows?


              1. Prototik
                25.05.2016 15:40

                Пути /usr/include, /opt/intel, компилятор GCC 6 вас не смутили? Конечно под линуксом.


            1. tumbler
              25.05.2016 15:43

              --disable-static --enable-shared

              Вот эти два ключа нам мешали запустить кодирование под CentOS, правда ошибка была другая. Попробуйте собрать статически ffmpeg, авось?


            1. S-ed
              26.05.2016 00:10

              Эта ошибка возникает из-за того, что ffmpeg пытается получить доступ к nvenc который в свою очередь запрашивает ключ дающий право кодирования и вероятно не может. На обычных картах ограничение в 2 потока, а вот на профессиональных картах и GRID — таких ограничений нет. И я не знаю искусственные ли они.
              Вот тут выла статья про обход блокировки: https://habrahabr.ru/post/262563/
              А вот тут есть гайд по настройке от самой NVIDIA: http://developer.download.nvidia.com/compute/redist/ffmpeg/1511-patch/FFMPEG-with-NVIDIA-Acceleration-on-Ubuntu_UG_v01.pdf


  1. alexkuzko
    25.05.2016 00:02

    Тут еще поступают противоречивые сведения насчет GTX 950 — вроде как это тоже GM206, т.е. та же самая платформа, как и у GTX 960, но такой ли там NVENC модуль? Если кто есть в Минске с GTX 950 — напишите в личку, было бы интересно проверить.


  1. AterCattus
    25.05.2016 01:01

    >и только при т.н. pixel хантинге
    К сожалению, все еще на «тяжелой» сцене с gpu кодированием (при сопоставимом с cpu вариантом выходном битрейте) видео ряд превращается в развалившуюся картинку размытых блоков.


    1. alexkuzko
      25.05.2016 01:16

      Если можно, дайте ссылку на такое видео и/или фрагмент и какое битрейт поставить. Можно в личку. Интересно закодировать и взглянуть.


      1. AterCattus
        25.05.2016 01:27

        Можно взять хотя бы вот https://www.youtube.com/watch?v=iNJdPyoqt8U (один из 3840x2160) и пережать в 1080p 30fps с битрейтом 6-8 мегабит.
        На 2:57 (сцена с деревьями) самая показательная.

        Пробовали на quadro, grid, tesla… Скорости хорошие (раза в 2-4 быстре cpu), но качество не понравилось.


        1. Denai
          25.05.2016 03:47

          А это не самого ютуба артефакты? Подобные кадры даже после заливки в uncompressed будут на ютубе смотреться ужасно


          1. AterCattus
            25.05.2016 11:18

            В 4k там все сильно лучше. Из него и перегоняем. Гругие примеры роликов нужно искать, а этот я просто по названию запомнил)


            1. Denai
              25.05.2016 11:42
              +1

              Не, я выразился неправильно. Попробую переформулировать. Подобная картинка превращается в кашу в тех местах, где всё остальное выглядит нормально, но причём здесь GPU/CPU? Ютуб пережимает любое залитое видео в свой формат (в частности указанное видео играется из VP9, ну по крайней мере заявляет об этом, если тыкнуть сведения в проигрывателе), значит не критично чем изначально кодировалось, лишь бы было не хуже среднего по ютубу. С другой стороны зелёный лес и прочая трава обычно требуют большего битрейта для нормальной картинки, значит логично ожидать проблем в таких местах, если битрейт не под них настроен. У вас есть сравнение сжатого GPU/CPU при прочих равных? Мне кажется что разница будет только в скорости кодирования, а качество обусловлено особенностями кодеков, а не тем подключался ли при кодировании GPU.


              1. AterCattus
                25.05.2016 11:47

                Так да, я ничего не говорю про то, что у Yt появляется на меньших качествах. Берем с него просто максимальный вариант, у которого проблемная сцена еще нормально смотрится, и сами уже пережимаем через gpu/cpu варианты. И их сравниваем. На ffmpeg с cpu, и на нем же с привлечением gpu. Разница ощутимая по качеству.


                1. Denai
                  25.05.2016 11:54

                  А на уже пересжатые примеры можете ссылку дать? Тут вам будут сильно благодарны. Достаточно 5-10 секунд примера, которые можно на какой-нибудь гуглодиск или подобное скинуть.


                  1. AterCattus
                    25.05.2016 11:59

                    Могу поискать прошлогодние тесты. Сравнивался чистый cpu вариант на E5-2620 v3 против gpu на grid k1, quadro m6000 и tesla k40.


      1. ValdikSS
        25.05.2016 17:43

        alexkuzko, AterCattus, Denai, давайте проведем чистый тест.

        alexkuzko, вот вам Red Velvet — ??(Happiness).mov в Apple ProRes yuv422p10le. Давайте вместе попробуем его скодировать «для просмотра в интернете», чтобы выходной размер скодированного видеопотока получился около 100±10 мегабайт, и визуально сравним, у кого что. Готовое видео должно быть в HEVC YUV 4:2:0. Никаких фильтров, кроме преобразования цветового пространства. Ограничений на опции энкодера нет, выставляйте максимально возможное качество.


        1. AterCattus
          25.05.2016 17:49

          Я пас, у меня тех тестовых карточек уже год, как нет.


        1. ValdikSS
          25.05.2016 22:11
          +1

          У меня получилось как-то так: happiness_psyrd15_2.mkv


        1. alexkuzko
          26.05.2016 00:54
          +1

          Смотрите что у меня получилось, я с первого подхода так сделал, пока не вытягивал максимум.
          сам файл и опции кодирования
          Насколько хорошо получилось уже сказать не могу, глаза слипаются. С утра погляжу подробнее. Если по-быстрому, то очень близки с вашим.


          1. ValdikSS
            26.05.2016 01:31

            Ой, какой плачевный результат, очень надеюсь, что это из-за настроек. Не нужно было так сильно ограничивать битрейт сверху и задавать такой широкий диапазон квантования, а в профиле, вроде как, нужно использовать hq, а не slow (нужно уточнить в справке, ffmpeg -help encoder=nvenc_hevc) Еще, почему-то, предиктор просто отвратительно работает. -g 250 еще добавьте.

            Пока что ваш результат на комплексных сценах (вторая сцена с танцами на фоне пальм) хуже ютубовского H.264, который весит примерно столько же (105 мегабайт).


            1. alexkuzko
              26.05.2016 15:23
              +1

              slow = 2pass
              hq следующий по качеству
              Поменял параметры немного, взгляните еще раз своим орлиным взором и раскритикуйте, не забывая что процессором это кодировалось бы медленнее в 25 раз на Core i7 3.0 (сейчас со скоростью ~0.1x и кодируется там… через час посмотрю что получилось).
              На 00:01:34.225, когда по ключевым переключаешь, второй вариант (002/003) намного лучше. Лица уже не так плывут квадратами.
              Также я сделал 002 (hq) и 003 (slow) с одинаковыми параметрами (те же ссылки, только вместо mkv — txt) кроме профиля — если вы сможете понять какой из них лучше, будет интересно. Они и про времени близки (slow даже чуть быстрее оказался, чем hq) и по качеству.


        1. Denai
          26.05.2016 16:36

          У меня исходный файл за полтора часа не скачался, после чего желание отпало совсем, увы. Ну и через CPU на моём компе не менее часа обрабатывалось бы, а на GPU ~2 минуты. На пересжатых файлах ValdikSS и alexkuzko можно мохнатые ручки певиц на свету, что часто не увидеть на том же ютубе, можно на него ссылку тоже добавить, если он есть?


  1. andrrrrr
    25.05.2016 06:12
    -2

    как то искал чем пережать видео, нашел
    Sony Vegas Pro
    начиная с 11 версии оно умеет видеокарту использовать.
    Option->Preferences->GPU acceleretion of video processing->[OFF|ваша_видеокарта] если нет карты, меняйте драйвера на нее, не все драйвера поддерживают кодирование видео.
    скорость перекодировки заметно увеличивается.


  1. iAlex
    25.05.2016 08:30

    Да нормальный у Вас процессор, да не новый, но еще полетает! У нас такие в продакшене стоят и творят чудеса.

    Приспасибочки за статью и видюшка и железяка под рукой ^_^


  1. vlad_xl
    25.05.2016 10:02

    Хорошая статья. А с Intel Quick Sync подобное не пробовали?
    Интересно было бы сравнить выигрыш в скорости.


    1. alexkuzko
      25.05.2016 10:13

      Лично я не пробовал. Технология мне в целом нравится, но не нравится позиция Intel.
      Они недавно вырезали из SDK поддержку некоторых (да, дешевых и массовых) процессоров и фактически сводят все к тому, что работать технология будет только на серверных чипсетах и процессорах. Почитать можно здесь же на хабре, последняя статья от интела и ссылка на их форум.

      А что касается видеокарты — ее можно поставить в любой компьютер. Если проброс PCI устройств работает в гипервизоре, то и на виртуалке можно поднимать когда нужно (сам пока не пробовал т.к. в целом это стезя Quadro — посмотрите на амазоне виртуалки с GPU — и в случае с одиночной картой и специально выделенным компьютером проще напрямую на сервере работать).


      1. Denai
        25.05.2016 11:47

        У NVENC тоже не всё гладко с поддержкой. На одной версии драйверов работает, на другой ругается что процессор не тот или просто не пишет. Ещё полгода назад у меня работал shadowplay, встроенный в GFexpirience, а сейчас там даже кнопки таковой не вижу. Для записи же сторонним софтом приходится порой драйвера откатывать. Всё под windows, не серверной.


      1. Ubeavis
        25.05.2016 13:26
        +1

        Это не просто стезя Quadro — есть определенный список этих Quadro (описан в документации к драйверу — Maxwell в нем начинается от K2200) — все десктопные и Quadro пониже тоже пробрасываются, но драйвер на них не встает и соответсвенно ничего из описанного не работает.
        И соответсвующие 9-й линейке Quadro тоже есть — M2000 (GM206), M4000 и M5000 (GM204) — почему вы считаете что в них какой-то другой NVENC?


        1. alexkuzko
          25.05.2016 13:42

          Спасибо за комментарий. Я перелопатил гору их документации и запомнились отсылки к тому, что Quadro еще на Kepler. Внесу правку.
          Хотя это интересно только технически, реально они очень дорогие и использовать их только для NVENC это как из пушки по воробьям.


      1. arteast
        25.05.2016 13:43

        Позиция NVidia с тем, что на «дешевых» карточках разрешено одновременно всего 2 потока кодировать чем-то лучше? Причем без внятного определения «дешевых» (дешевые — это все карточки GeForce независимо от цены, и недокументированный список моделей Quadro).


        1. alexkuzko
          25.05.2016 13:46

          Любые ограничения это зло.
          Но одно дело когда ты вообще ничего не можешь, и совсем другое, когда ограничения касаются только проф.использования. Просто для перекодирования хватает и одного потока, второй дает небольшой бонус. Большое количество потоков нужно в первую очередь для ретрансляции.

          По второму вопросу, ограничения очень четкие, без привязки к цене:
          https://developer.nvidia.com/nvidia-video-codec-sdk — вот тут написано что ограничение на 2 потока касается только Desktop and Mobile Computers, т.е. линейке GeForce.


          1. arteast
            25.05.2016 14:06

            Не только. Я проверял Quadro K620 — точно так же 2 потока и всё. Видимо, K620 тоже считается Desktop (и официального списка этих моделей я нигде не нашел).


            1. alexkuzko
              25.05.2016 14:44

              Именно на SDK 6.0? Они в нем исправили проблему с лицензией (что само по себе показывает абсурдность ограничения) и убрали ограничения для тех же K2xxx

              Вообще, текущий список для Quadro:
              Quadro K2000, K2200, K4000, K4200, K5000, K5200, K6000, M4000, M5000, M6000, and newer
              Quadro K2000M, M2000M, K5000M, and newer

              Ваша K620 просто старая судя по всему. У нее ведь даже память DDR3, а не GDDR5 (интересно отчего codename у них одинаковый с K2200 — GM107? Но это уже на совести Nvidia).


              1. arteast
                25.05.2016 15:08

                На последнем SDK 6.0.1 (под Windows). Я не знаю, насколько она старая, но чип внутри, насколько я помню, именно Maxwell. Когда дойдут до нее руки, перепроверю.
                В любом случае NVENC SIP там есть, карточка вроде бы как Quadro, но лицензия урэзанная. Этот список не спасает, поскольку это список тех карточек, которые вообще в принципе nvenc умеют (там ниже и GeForce упомянуты, с явным ограничением в 2 сессии). То есть если K620 умеет, то, значит, она в этом списке есть (видимо, newer).


  1. tumbler
    25.05.2016 10:51
    +1

    HEVC всё-таки это технология будущего, пока что подавляющее большинство железа ее не тянет (даже на декодировании).
    А вот использовать nvenc_h264 — это действительно круто, но с некоторыми ограничениями. Обработка в один поток упирается в CPU на этапе декодирования, при этом nvidia-smi показывает utilization около 10-20% на K1200. Так что добиваться поразительных результатов надо с использованием nvresize и кодированием сразу в несколько качеств. Первый значительно снижает нагрузку на CPU при масштабировании картинки, да еще и распределяет кадры по потокам nvenc, не возвращая их обратно на хост-машину. А насчет нескольких качеств выходит так: исходник h264 1080p преобразуется в набор 240p + 360p + 576p + 720p со скоростью 500-600fps, при этом на GPU utilization encoding и cuda доходит до 100%.


    Правда эффективную параллельную обработку запилить не удается, мешает… ffmpeg! Оказывается, filter_complex при его задействовании упирается при переброске фреймов в одно ядро, причем просто на кодировании звука в aac с разными битрейтами. GPU при этом застревает где-то на 200 fps, CPU тоже свободен (кроме одного ядра). Остается вариант с одинаковым аудиопотоком во всех результатах, плюс ухищрения с "-f tee", чтобы раскидать один и тот же аудиопоток по 4 файлам.


  1. evbevz
    25.05.2016 13:24

    Интересная статья. А можно узнать у автора о качестве картинки при перекодировании из исходника 7-8 мегабит 720р в экстремально низкие битрейты данным способом? Например, в видеобитрейт 200к при разрешении 240х192. Или в видеобитрейт 300к 360х288. Или в 660к 504х404.
    h264_qsv в этих случаях делает неудовлетворительное качество, картинка периодически рассыпается на квадраты.


    1. alexkuzko
      25.05.2016 13:25

      Залейте куда-нибудь семпл (источник), то что получилось у вас (интересно же сравнить) с параметрами, и желаемые битрейты, я сделаю и залью. Посмотрите и сравните.


  1. SchmeL
    25.05.2016 13:25

    надо бы попробовать на openmcu-ru прикрутить…


  1. YourChief
    25.05.2016 13:33
    +1

    Радостно видеть интерес к этой теме со стороны сообщества!

    в отличие от оригинальной статьи, где почему-то упустили этот момент, я применил переработанный патч Nvidia Acceleration к FFmpeg 3.0.2, получив помимо энкодера nvenc еще и быстрый фильтр ресайза — nvresize

    Первая часть этой статьи была написала в июле 2015го, а внедрение на продакшн состоялось в марте. PDF про описываемый патч датирован ноябрём 2015го года, судя по титульному листу.


    1. alexkuzko
      25.05.2016 13:48
      +1

      Надеюсь вы не в обиде ;) Теперь понятно почему «упустили» — этого просто не было. Если хотите, внесу правку в статью.
      Кстати, может вы нашли более человеческий способ убрать ограничение на 2 потока? А свой пробовали с последним SDK?


      1. YourChief
        25.05.2016 14:09

        Не в обиде, конечно. Про правку как пожелаете.

        Других способов лечения лимита не искал даже, так как понятно где он и лучше разбираться с ним адресно. Возможно стоит поискать, где откуда библиотека узнаёт об уже запущенных потоках, но и это не гарантирует простого решения.

        С тех пор я стал заниматься уже совсем другим в другом месте и сейчас такого оборудования нет под рукой.


  1. rumkin
    25.05.2016 17:29

    Почему в опросе нет варианта: нет, но собираюсь?


    1. alexkuzko
      25.05.2016 17:32

      «Хорошая мысля приходит опосля» (с)
      Долго думал что выбрать, а про этот вариант совсем забыл. Частично подходит, «Не кодирую видео», т.к. имеется в виду настоящее время.


  1. klirichek
    26.05.2016 13:18

    > гораздо быстрее, чем x265
    Это вполне очевидно. Или просто циферкой ошиблись?