Ffmpeg windows with nvenc

Электрический блогнот

мои заметки на полях

ffmpeg — быстрей, еще быстрее

В давние времена возможностью кодирования видео на уровне железа обладали немногие устройства (в основном цифровые фото/видеокамеры и гаджеты типа Canopus). Но с 2012 года такие гиганты, как Intel и NVIDIA сказали, что теперь и мы сможем заниматься кодированием/раскодированием видеопотока, выделив под это дело отдельный набор микросхем (чип). Intel ввела технологию Quick Sync Video в своих процесорах, а NVIDIA реализовала это, как NVDEC/NVENC чип на своих видеокартах . Этот чип ничем кроме, как сжатием/расжатием видеопотока заниматься не может (на самом деле может еще кое-что). А раз чип берет на себя всю работу по сжатию видео, например, в h.264, то центральный CPU полностью разгружается, открывая перед пользователем очередные горизонты в multimedia. Особенно «горизонты» открылись в стриме, когда нужно было «играть» и «показывать». За «играть» отвечает CPU + основные ресурсы GPU, а за «показывать» отвечал тот самый чип. Еще «горизонты» открылись для пользователей слабых ноутбуков, теперь они могут заниматься обработкой FullHD и 4K видео без томительного ожидания окончания процесса кодирования.

FFMpeg

Преимущества кодирования/декодирования видео мы будем рассматривать на примере FFmpeg. Это популярная бесплатная программа, с открытым исходным кодом, доступная на Linux и Windows. Разработка FFmpeg ведется довольно активно, что указывает на расширение функционала и повышения стабильности программы от релиза к релизу.

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

Попробуем, как говориться, «разогнать» FFmpeg и сделать его еще быстрее.

Что будем кодировать

В качестве теста возьмем известный ролик Buck Bunny. Это 3D компьютерный мультик в 4K разрешении. Детализация просто зашкаливает. Травинки, ворсинки на шкурке, панорамы камерой — все это дает сильную нагрузку на кодек.

Знакомство с кодированием на GPU начнем с NVIDIA и ее технологии NVDEC/NVENC.

NVIDIA NVENC

В 2012 году NVidia в своих видеокартах линейки Kepler установила пару чипов, в которых на аппаратном уровне происходит раскодирование и кодирование видеопотока. На следующей схеме — это блоки NVDEC и NVENC.

NVDEC (video decoder) — тот, кто расжимает сжатое видео. Согласитесь, прежде чем показать видео на экране его полагается для начала разжать. Задача эта не легкая и нагрузку на центральный процессор дает ощутимую. А если видео 4K да еще 60fps, то не всякий процессор с этим справится. NVDEC работает с самыми популярными форматами видео.

NVENC (video encoder) — тот, кто сжимает видео. Жмет в h.264 и HEVC (h.265). Тут все понятно.

Обратите внимание, блоки NVDEC, NVENC располагаются отдельно от CUDA Cores, тем самым не создавая нагрузку на графический процессор, который в данный момент занимается важными делами (например, обрабатывает PhysX и Bullet для любимой компьютерной игры).

Установка

FFmpeg с поддержкой аппаратного кодека NVENC можно легко собрать из исходников, а можно воспользоваться и готовой сборкой для Windows.

Сборка из исходников

Если вы «осмелились» 🙂 собрать FFmpeg из исходников с поддержкой NVENC, то вот вам несколько советов.

    Для сборки нужно очень много dev версий библиотек, ну что-то типа:

и это не все, а только часть. Я когда собирал, сделал список всех установленных пакетов в системе (installed-packages), чтобы потом отфильтровать его по префиксу «dev» и воспользоваться уже готовым списком.

  • Необходимо установить CUDA Toolkit. Ставьте с настройками по умолчанию, в ту директорию, в которую инсталлятор предложит:
  • Скачиваем и устанавливаем Include файлы (понадобятся при сборке). Раньше, чтобы их найти нужно было приложить не мало сил. Теперь все просто:

    Далее, необходимо сделать:

    После этого они установятся в нужную папку и когда будете собирать FFmpeg, configure скрипт их с легкостью найдет.

  • Скачиваем исходники FFmpeg. Рекомендую делать это не через «git clone», а скачать архив исходников с http://ffmpeg.org/releases/. Причем выбирать не самую последнюю версию, а ту которая ближе к версии CUDA SDK (примерно сравните время создания архивов). Это нужно, чтобы избежать конфликтов с совместимостью.
  • Запускаем сборку FFmpeg

    Читайте также:  Windows api and net

    Внимание. После окончания сборки не будет проигрывателя ffplay. Не ищите его. FFplay не поддерживает аппаратное ускорения во время проигрывания video. Четыре года назад был создан баг на эту тему, но воз и ныне там. Но, как выход можно воспользоваться MPV, которые позволяет задействовать мощность GPU при проигрывании видео.

    Готовые пакеты

    FFmpeg содержится в репозитариях всех популярных дистрибутивов Linux. Его можно легко установить через соответствующий менеджер пакет.
    Самые свежие версии FFmpeg для Windows можно скачать с https://ffmpeg.zeranoe.com/builds/.
    Чтобы проверить поддерживает ли ffmpeg аппаратное кодирование на NVIDIA GPU выполните команду:

    и ищите строчку с префиксом nvenc:

    Пример

    Теперь можно запустить аппаратное кодирование через ffmpeg и насладиться скоростью:

    -c:v h264_cuvid — раскодирование видео будет делаться на NVDEC;

    -c:v h264_nvenc — кодировать поток будем на NVENC

    То есть в этом примере мы имеем полное аппаратное декодирование, а затем кодирование. Чтобы удостовериться в том, что графическая карта занимается раскодированием и кодированием видео, запустим:

    enc — загрузка чипа NVENC,

    dec — загрузка чипа NVDEC

    Центральный процессор при этом загружен минимально.

    Кодек NVENC в ffmpeg предоставляет большое количество опций для выбора оптимального метода сжатия: несколько предустановленных профилей, постоянный/переменный битрейт, многопроходное кодирование и еще много других опций полный список, которых можно посмотреть выполнив:

    Условия теста простейшие. Сначала сконвертируем фрагмент видео обычным способом (на CPU), затем сконвертируем на аппаратном кодеке NVENC и сравним времена.

    Программное сжатие видео — 163 сек. Проводилось на всех доступных ядрах и потоках в параллельном режиме на Intel i-7.

    Аппаратное сжатие с использованием технологии NVENC — 73 сек.

    По факту имеем ускорение в 2 раза.

    Intel Quick Sync Video

    Intel в своих процессорах, а точнее в графическом ядре, реализовала технологию «Quick Sync Video», позволяющую аппаратно кодировать/раскодировать видеопоток. Эта технология была представлена в 2011 году и с каждым поколением процессоров производительность QSV возрастала.

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

    QSV поддерживает следующие форматы видео; mpeg2, h.264, hevc. Есть несколько пресетов для аппаратного кодека: veryfast, faster, fast, medium, slow, slower, veryslow. Реализовано многопроходное кодирование. Есть возможность задания точного значения битрейта.

    Установка

    FFMpeg с поддержкой Intel QSV можно собрать из исходников, как под Linux, так и под Windows. Процесс этот довольно простой, поэтому его описание я приводить не буду. Для тех, кто не хочет заморачиваться со сборкой из исходников, в сети есть прекрасный ресурс, где выкладываются самые свежие версии FFMpeg с поддержкой QSV. Рекомендую скачивать статическую версию FFMpeg.

    Чтобы проверить содержит ли скачанная версия FFMpeg поддержку qsv для декодирования/кодирования, выполните:

    Если там будет вот такая строчка с h264_qsv:

    Значит все в порядке и можно приступать к кодированию.

    Пример

    Тест проводился на стареньком ноутбуке ASUS с процессором Intel Core i3.

    Программное сжатие видео — 385 сек

    Аппаратное сжатие с использованием технологии QSV — 91 сек

    Согласитесь, неплохая прибавка (x4) к скорости кодирования на ноутбуке.

    Выводы

    Когда я впервые собрал ffmpeg с поддержкой GPU и попробовал сравнить скорость кодирования с обычным вариантом на CPU, честно говоря испытал какой-то взрыв эмоций. Вот ноутбук, видео кодируется обычно час, но оказывается на этом же ноуте можно сконвертировать за 15-20 минут. Ощущается, как халява. Двух-трехкратное ускорение, просто из ничего! При этом процессор свободен и можно заниматься своими делами и ничего не тормозит.
    Конечно же никакой Америки я не открыл и эта технология давно используется. Тем не менее приятно задействовать все ресурсы ноутбука из которого казалось бы выжато уже все, что можно:-)

    Platform API Availability

    Linux Windows Android Apple Other
    AMD Intel NVIDIA AMD Intel NVIDIA macOS iOS Raspberry Pi
    AMF N N N Y N N N N N N
    NVENC/NVDEC/CUVID N N Y N N Y N N N N
    Direct3D 11 N N N Y Y Y N N N N
    Direct3D 9 (DXVA2) N N N Y Y Y N N N N
    libmfx N Y N N Y N N N N N
    MediaCodec N N N N N N Y N N N
    Media Foundation N N N Y Y Y N N N N
    MMAL N N N N N N N N N Y
    OpenCL Y Y Y Y Y Y P Y N N
    OpenMAX P N N N N N P N N Y
    V4L2 M2M N N N N N N P N N N
    VAAPI P Y P N N N N N N N
    VDPAU P N Y N N N N N N N
    VideoToolbox N N N N N N N Y Y N
    • Y Fully usable.
    • P Partial support (some devices / some features).
    • N Not possible.

    FFmpeg API Implementation Status

    Decoder Encoder Other support
    Internal Standalone Hardware output Standalone Hardware input Filtering Hardware context Usable from ffmpeg CLI
    AMF N N N Y Y N Y Y
    NVENC/NVDEC/CUVID N Y Y Y Y Y Y Y
    Direct3D 11 Y Y F Y Y
    Direct3D 9 / DXVA2 Y Y N Y Y
    libmfx Y Y Y Y Y Y Y
    MediaCodec Y Y N N N N
    Media Foundation N N N N N N N
    MMAL Y Y N N N N
    OpenCL Y Y Y
    OpenMAX N N Y N N N Y
    RockChip MPP Y Y N N Y Y
    V4L2 M2M Y N Y N N N Y
    VAAPI Y Y Y Y Y Y Y
    VDPAU Y Y N Y Y
    VideoToolbox Y N Y Y Y Y Y
    • — Not applicable to this API.
    • Y Working.
    • N Possible but not implemented.
    • F Not yet integrated, but work is being done in this area.
    Читайте также:  Windows cardspace что будет если отключить

    Use with the ffmpeg command-line tool

    Internal hwaccel decoders are enabled via the -hwaccel option. The software decoder starts normally, but if it detects a stream which is decodable in hardware then it will attempt to delegate all significant processing to that hardware. If the stream is not decodable in hardware (for example, it is an unsupported codec or profile) then it will still be decoded in software automatically. If the hardware requires a particular device to function (or needs to distinguish between multiple devices, say if several graphics cards are available) then one can be selected using -hwaccel_device .

    External wrapper decoders are used by setting a specific decoder with the -codec:v option. Typically they are named codec_api (for example: h264_cuvid ). These decoders require the codec to be known in advance, and do not support any fallback to software if the stream is not supported.

    Encoder wrappers are selected by -codec:v . Encoders generally have lots of options – look at the documentation for the particular encoder for details.

    Hardware filters can be used in a filter graph like any other filter. Note, however, that they may not support any formats in common with software filters – in such cases it may be necessary to make use of hwupload and hwdownload filter instances to move frame data between hardware surfaces and normal memory.

    VDPAU

    ​ Video Decode and Presentation API for Unix. Developed by NVIDIA for Unix/Linux systems. To enable this you typically need the libvdpau development package in your distribution, and a compatible graphics card.

    Note that VDPAU cannot be used to decode frames in memory, the compressed frames are sent by libavcodec to the GPU device supported by VDPAU and then the decoded image can be accessed using the VDPAU API. This is not done automatically by FFmpeg, but must be done at the application level (check for example the ffmpeg_vdpau.c file used by ffmpeg.c ). Also, note that with this API it is not possible to move the decoded frame back to RAM, for example in case you need to encode again the decoded frame (e.g. when doing transcoding on a server).

    Several decoders are currently supported through VDPAU in libavcodec, in particular H.264, MPEG-1/2/4, and VC-1.

    VAAPI

    Video Acceleration API (VAAPI) is a non-proprietary and royalty-free open source software library («libva») and API specification, initially developed by Intel but can be used in combination with other devices.

    It can be used to access the Quick Sync hardware in Intel GPUs and the UVD/VCE hardware in AMD GPUs. See VAAPI.

    DXVA2

    ​ Direct-X Video Acceleration API, developed by Microsoft (supports Windows and XBox360).

    Several decoders are currently supported, in particular H.264, MPEG-2, VC-1 and WMV 3.

    DXVA2 hardware acceleration only works on Windows. In order to build FFmpeg with DXVA2 support, you need to install the dxva2api.h header. For MinGW this can be done by ​ downloading the header maintained by VLC and installing it in the include path (for example in /usr/include/ ).

    For MinGW64, dxva2api.h is provided by default. One way to install mingw-w64 is through a pacman repository, and can be installed using one of the two following commands, depending on the architecture:

    To enable DXVA2, use the —enable-dxva2 ffmpeg configure switch.

    To test decoding, use the following command:

    VideoToolbox

    ​ VideoToolbox, only supported on macOS. H.264 decoding is available in FFmpeg/libavcodec.

    Читайте также:  Sp1 обновление sp2 для windows

    To use hardware encoding in macOS, just use the encoder -c:v h264_videotoolbox or -c:v hevc_videotoolbox for H.264 or HEVC respectively. Check ffmpeg -h encoder=. to see encoder options. It’s worth noting that VideoToolbox does not support constant quality (CRF) encoding. Bit rate, -b:v . , is your main lever to balance size vs quality.

    CUDA(NVENC/NVDEC)

    NVENC and NVDEC are NVIDIA’s hardware-accelerated encoding and decoding APIs. They used to be called CUVID. They can be used for encoding and decoding on Windows and Linux. FFmpeg refers to NVENC/NVDEC as CUDA.

    NVENC

    NVENC can be used for H.264 and HEVC encoding. FFmpeg supports NVENC through the h264_nvenc and hevc_nvenc encoders. In order to enable it in FFmpeg you need:

    • A ​ supported GPU
    • Supported drivers for your operating system
    • ​ The NVIDIA Codec SDK or compiling FFmpeg with —enable-cuda-llvm
    • ffmpeg configured with —enable-nvenc (default if the drivers are detected while configuring)

    Note: FFmpeg uses its own slightly modified runtime-loader for NVIDIA’s CUDA/NVENC/NVDEC-related libraries. If you get an error from configure complaining about missing ffnvcodec , ​ this project is what you need. It has a working Makefile with an install target: make install PREFIX=/usr . FFmpeg will look for its pkg-config file, called ffnvcodec.pc . Make sure it is in your PKG_CONFIG_PATH .

    This means that running the following before compiling ffmpeg should suffice:

    After compilation, you can use NVENC.

    You can see available presets, other options, and encoder info with ffmpeg -h encoder=h264_nvenc or ffmpeg -h encoder=hevc_nvenc .

    Note: If you get the No NVENC capable devices found error make sure you’re encoding to a supported pixel format. See encoder info as shown above.

    NVDEC/CUVID

    NVDEC offers decoders for H.264, HEVC, MJPEG, MPEG-1/2/4, VP8/VP9, VC-1. Codec support varies by hardware (see the ​ GPU compatibility table).

    Note that FFmpeg offers both NVDEC and CUVID hwaccel s. They differ in how frames are decoded and forwarded in memory.

    The full set of codecs being available only on Pascal hardware, which adds VP9 and 10 bit support. The note about missing ffnvcodec from NVENC applies for NVDEC as well.

    Sample decode using CUDA:

    Sample decode using CUVID:

    Full hardware transcode with NVDEC and NVENC:

    If ffmpeg was compiled with support for libnpp, it can be used to insert a GPU based scaler into the chain:

    The -hwaccel_device option can be used to specify the GPU to be used by the hwaccel in ffmpeg.

    libmfx

    libmfx is a proprietary library from Intel for use of Quick Sync hardware on both Linux and Windows. On Windows it is the primary way to use more advanced functions beyond those accessible via DXVA2/D3D11VA, particularly encode. On Linux it has some different feature set and helpful for some use-cases desiring maximum throughput.

    OpenCL

    ​ OpenCL can be used for a number of filters. To build, OpenCL 1.2 or later headers are required, along with an ICD or ICD loader to link to — it is recommended (but not required) to link with the ICD loader, so that the implementation can be chosen at run-time rather than build-time. At run-time, an OpenCL 1.2 driver is required — most GPU manufacturers will provide one as part of their standard drivers. CPU implementations are also usable, but may be slower than using native filters in ffmpeg directly.

    OpenCL can interoperate with other GPU APIs to avoid redundant copies between GPU and CPU memory. The supported methods are:

    • DXVA2: NV12 surfaces only, all platforms.
    • D3D11: NV12 textures on Intel only.
    • VAAPI: all surface types.
    • ARM Mali: all surface types, via DRM object sharing.
    • libmfx: NV12 surfaces only, via VAAPI or DXVA2.

    AMD UVD/VCE

    AMD UVD is usable for decode via VDPAU and VAAPI in Mesa on Linux. VCE also has some initial support for encode via VAAPI, but should be considered experimental.

    On Windows, UVD is accessible via standard DXVA2/D3D11VA APIs, while VCE is supported via AMF.

  • Оцените статью