В прошлой статье, посвящённой изучению кодирования на HEVC в FFmpeg, мы разобрали большинство функций работы с видео и научились эффективно сжимать видео или ускорять процесс кодирования для различных задач, преимущественно в программном кодировании. На этот раз моё внимание привлекла тема аппаратного кодирования (ГПУ) в FFmpeg. Мне не понравился не только поверхностный, но и откровенно плохой подход к теме в других статьях — некоторые авторы, сами того не замечая, предлагают программное кодирование вместо аппаратного. Поэтому я решил конкретно зарыться в этой теме и затем поделиться своими находками с вами.

Буду рассматривать аппаратные кодеки Nvidia, AMD и Intel.

Разница между аппаратным кодированием и программным



Для начала разберёмся в основных отличиях двух подходов. Аппаратное кодирование использует специализированные компоненты графического процессора (GPU), разработанные для ускорения задач по кодированию и декодированию видео. GPU содержит встроенные блоки, такие как NVENC (у NVIDIA), AMF (у AMD), QSV (у Intel), которые могут быстро и эффективно обрабатывать такие задачи, обеспечивая высокую скорость обработки для больших объёмов данных. Программное кодирование выполняется непосредственно на центральном процессоре (CPU) с использованием программных библиотек и алгоритмов. CPU использует свои универсальные вычислительные ресурсы для выполнения задач преобразования данных. Из этого следует, что в случае аппаратного кодирования даже процессор пятилетней давности будет превосходить его как в актуальности алгоритмов обработки изображения, так и в возможностях самих специализированных блоков. В них реализованы далеко не все алгоритмы сжатия, а некоторые даже разрабатываются отдельно под такую архитектуру, преимущественно для ускорения кодирования стриминга или записи. Однако за счёт очень узкой направленности работы и простоты архитектуры такие блоки могут выполнять вычисления на бешеной скорости, хоть и в ущерб качеству сжатия или размеру файла.

Разница между NVENC, AMF и QSV


Если говорить о количественных характеристиках, на первом месте NVENC с 115 опциями, за ним идёт AMF с 95, а на третьем — QSV с 80 опциями. Это не просто набор избыточных функций: NVENC действительно предлагает более широкие возможности настройки. Однако до программного кодирования с доступными более чем 200 параметрами ещё далеко.


Intel жалеть не стоит. QSV был выпущен в 2011 году, NVENC — в 2012, AMF — в 2016. AMD с разницей в 6 лет смогла достаточно набить руку, чтобы нагнать их.

В профессиональной сфере программное кодирование трудно сравнить с аппаратным. Следует отметить, что все аппаратные кодеры, кроме одного, не поддерживают 12-битное видео, в отличие от программных решений. Это лишь одно из очевидных преимуществ. Аппаратное кодирование нацелено на быстрое кодирование больших объёмов данных, но мы рассмотрим только направление кодирования различных записей без стриминга. Если вы хотите углубиться в медленное программное кодирование с хорошим сжатием на программном кодеке, у меня уже была статья на эту тему, тоже по HEVC (H265).

Как включить аппаратное кодирование в FFmpeg


Простой шаг, на котором многие допускают ошибки. libx265 — это исключительно кодирование на процессоре. Чтобы указать AMD AMF — hevc_amf, NVIDIA NVENC — hevc_nvenc, INTEL QVS — hevc_qvs.

Что рассматриваем?


Я опускаю все параметры, кроме тех, что могут понадобиться при перекодировании записей реальной жизни или игр. Для всего остального есть OBS в большинстве случаев. У меня также нет практики в работе с потоковым видео, поэтому этот сценарий я не смогу раскрыть.
Все команды, приведённые в статье, работают как на Linux, так и на Windows.

Аппаратный кодек AMD AMF


Спустя год после выпуска Radeon R9 300 series, в 2016-м AMD выпустила первый полноценный AMF v1.3.0 примерно в то же время, что и знаковый ROCm: это был год инноваций для AMD.


▍ Quality


Это похоже на родной Preset. С его помощью мы можем указать скорость кодирования по формуле «время / вес и качество». Так же, как и Preset настройка, он влияет на параметры кодирования.

  1. Speed (0)
  2. Balanced (5)
  3. Quality (10)

Разница во времени кодирования между параметрами speed и balanced составляет около 3-5%, но эффект оказывает существенное влияние при том же битрейте.

ffmpeg -i "название_видео.mp4" -c:v hevc_amf -quality 0 готовое_видео.mp4

ImgSli. Как видно, при quality=10 распределение микроблоков ухудшается, что приводит к более сильному искажению геометрии по сравнению с quality=0.

▍ GOP


Ещё один интересный параметр, специфичный для аппаратного кодирования. GOP (Graphics Output Protocol) — как и в программном кодировании, при сжатии видео, кодек оперирует структурой из I, P и B-кадров. I (Intra-coded frames) — содержат полные данные об изображении; P (Predictive frames) — содержат данные на основе предсказания изменений от предыдущего кадра; B (Bidirectional frames) — используют данные как предыдущего, так и последующего кадров для предсказания.

При указании значения GOP вы определяете соотношение всех трёх типов кадров при сжатии. Соответственно, меньший размер GOP может улучшить качество, но увеличит объём данных, а большой GOP увеличивает степень сжатия, но может ухудшить качество при воспроизведении быстро меняющихся сцен.

ffmpeg -i "название_видео.mp4" -c:v hevc_amf -gop 60 готовое_видео.mp4

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

▍ RC


RC (Rate Control) — это система управления битрейтом при кодировании видео. Она определяет, как распределять доступную пропускную способность для достижения нужного качества видео в зависимости от выбранного режима.

  1. CBR (Constant Bitrate) — постоянный битрейт. В этом режиме кодек поддерживает фиксированную скорость потока, что гарантирует предсказуемое использование пропускной способности, но может привести к ухудшению качества в сложных сценах.
  2. VBR (Variable Bitrate) — переменный битрейт. В этом режиме поток данных меняется в зависимости от сложности сцены. В простых сценах он уменьшается, в сложных — увеличивается, что позволяет более эффективно использовать пропускную способность и повышать качество.
  3. QVBR (Quality Variable Bitrate) — гибрид VBR, где целевой поток зависит от качества, задаваемого пользователем. Он адаптируется для сохранения постоянного уровня качества, но всё равно не дотягивает до CQP.
  4. CQP (Constant Quantization Parameter) — режим с постоянным параметром квантования. В этом режиме качество видео контролируется напрямую параметром квантования, без фиксированного битрейта. Это полезно, если основной целью является максимальное качество видео, а размер файла не важен.

Я рекомендую использовать CQP в нашем сценарии. Возможные значения — 0-51. Их необходимо указывать с помощью qp_i и qp_p.

ffmpeg -i "название_видео.mp4" -c:v hevc_amf -rc cqp qp_i 20 qp_P21 готовое_видео.mp4

ImgSli

Аппаратный кодек NVENC — Nvidia


В марте 2012 года были представлены видеокарты Nvidia из линейки Kepler (GTX 600) и аппаратный кодек NVENC. Конечно, с того момента он значительно изменился, и это проявляется не только в появлении новых кодеков, но и в инженерных решениях. Так, в 2012 году лимит составлял всего два одновременных потока кодирования видео, а на сегодняшний день уже восемь.


▍ Preset


Стандартный preset. Однако мы пропустим первые 11 настроек, относящихся к стримингу.

  1. P1 (Ultra Fast)
  2. P2 (Fast)
  3. P3 (Medium)
  4. P4 (Slow)
  5. P5 (Very Slow)
  6. P6 (Placebo)
  7. P7 (Lossless)

На деле, разница в скорости кодирования почти отсутствует.

ffmpeg -i "название_видео.mp4" -c:v hevc_nvenc -preset p1 готовое_видео.mp4

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

▍ RC


Выполняет такую же функцию, как и в технологии AMD AMF — отвечает за управление скоростью, известное как Rate Control.

  1. CBR (Constant Bitrate) – постоянный битрейт.
  2. VBR (Variable Bitrate) – переменный битрейт.
  3. CQP (Constant QP) – постоянное качество.

ffmpeg -i "название_видео.mp4" -c:v hevc_nvenc -rc cqp -qp 20 готовое_видео.mp4

▍ B-ref-mode


B-frames (B-кадры), о которых я рассказывал в прошлой статье, представляют собой кадры, предсказывающие движение между кадрами, что позволяет более эффективно сжимать видео по сравнению с хранением полных данных о каждом кадре. Интересно, что AMF предоставляет удобное управление I, P и B кадрами (GOP), но не позволяет управлять B-кадрами отдельно. На практике это оказывается не так полезно, как подобный переключатель, ведь одновременное существование GOP и QCP, усложняет> управление качеством картинки.

Доступны следующие режимы работы:

  • 0 (disabled): B-кадры не используются как опорные. Это означает, что B-кадры не могут ссылаться на другие B-кадры, и кодирование основывается только на I и P-кадрах.
  • 1 (each): Каждый B-кадр используется как референсный. Это позволяет B-кадрам ссылаться как на предыдущие, так и на последующие кадры, улучшая качество сжатия.
  • 2 (middle): В этом режиме только половина B-кадров используется в качестве опорных. Например, при наличии 4 последовательных B-кадров только 2 из них становятся референсными, что упрощает процесс декодирования.

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

ffmpeg -i "название_видео.mp4" -c:v hevc_nvenc -b_ref_mode 1 готовое_видео.mp4

ImgSli. Наиболее заметные артефакты на этом кадре: лицо человека в верхнем левом углу – там кодек оставил красное пятно; предметы на лавке вверху справа практически потеряли свою геометрию при стандартных настройках b_ref_mode. Таким образом, отсутствие этого параметра может приводить к появлению различных типов артефактов, связанных с размытием во время движения

Аппаратный кодек Intel QSV


Intel Quick Sync Video (QSV) была представлена в эпоху постоянных прорывов: 9 января 2011 года вместе с архитектурой процессоров Sandy Bridge и новой интегрированной графикой Intel HD 2000.



▍ Preset


Наиболее стандартный вариант, относительно того, что имеется сейчас в программных кодеках. Других пресетов нет, в отличие от Nvidia, что напихали под одну гребёнку всё подряд.

  1. veryfast
  2. faster
  3. fast
  4. medium
  5. slow
  6. slower
  7. veryslow

ffmpeg -i "название_видео.mp4" -c:v hevc_qsv -preset 1 готовое_видео.mp4

ImgSli. Вероятно, пресеты перепутаны, так как после нескольких проверок выяснилось, что ultrafast работает лучше, чем veryslow, что не кажется логичным. Основные отличия видны на текстуре участка дерева внизу кадра и неправильной геометрии левой руки. Эти объекты оставались в поле зрения не более двух кадров, вероятно, это влияние низкого значения B кадров

▍ Методы управления битрейтом


В Intel QSV нет нормальной реализации CQP, которым мы ранее всегда пользовались. Точнее, она существует, но разобраться в этом даже мне сложно. Поэтому остаются только методы постоянного и переменного битрейта.


  1. CBR (Constant Bitrate) — постоянный битрейт. Распределение потока данных по всему видео одинаковое, это обеспечивает предсказуемость веса файла, но не гарантирует стабильного качества. Если значение битрейта окажется недостаточно высоким, то в сложных сценах могут появиться артефакты. В этом случае придётся повышать битрейт, из-за чего файл будет весить больше на участках видео, не требующих этого, что нелогично при задаче сжатия видео.

    ffmpeg -i "название_видео.mp4" -c:v hevc_qsv -b:v 4M готовое_видео.mp4

  2. VBR — (Variable Bitrate) — переменный битрейт. Позволяет изменять битрейт в зависимости от сложности сцены в видео. Алгоритм старается поддерживать заданный средний битрейт, но может увеличивать поток данных до указанного максимума, если это необходимо. Этот режим хорошо подходит для стриминга видео, но в сценариях архивирования он оказывается менее эффективным по сравнению с CQP (Constant Quality).

    Ключевое отличие CQP в том, что он сохраняет заданный уровень качества, изменяя битрейт в зависимости от содержания. Например, в одном фрагменте видео битрейт может составлять 2 Мбит/с для лёгкой сцены, а в другом — 5 Мбит/с для сложной.

    Попытка воспроизвести эффект CQP с помощью VBR, задав средний битрейт 0 Мбит/с и максимальный 100 Мбит/с, не приведёт к сжатию видео также эффективно. На самом деле, такой подход может полностью исключить сжатие и увеличить размер файла.

    В целом, VBR в архивировании видео — это неудачный выбор, и его реализация оставляет желать лучшего. В этом контексте CQP демонстрирует значительно лучшие результаты, особенно при необходимости качественного сжатия.

    ffmpeg -i "название_видео.mp4" -c:v hevc_qsv -maxrate 4M -bufsize 10M готовое_видео.mp4

▍ ExtBrc


External Bitrate Control — специфичная для Intel технология контроля битрейта при помощи внешних средств по отношению к базовому алгоритму битрейта.

ImgSli. Алгоритм существенно улучшил качество сцены даже при использовании CBR. Детализация улучшилась практически повсюду: листья возле колчана стрел стали отчётливее, как и низ рукояти лука с перчаткой левой руки. Переход тени на спине персонажа теперь практически незаметен. Кроме того, распределение макроблоков стало более ровным: почти исчезли искажения прямых линий, что особенно заметно на голове персонажа.

Ускорение предварительной обработки видео


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


▍ Hwaccel


Hardware acceleration — аппаратное ускорение позволяет использовать специализированные блоки графических процессоров.

  1. cuda — использует CUDA (NVIDIA GPU).
  2. qsv — Intel Quick Sync Video (QSV).
  3. dxva2 — Microsoft DirectX Video Acceleration 2 (только Windows).
  4. vaapi — Video Acceleration API (Linux, поддержка Intel и AMD).
  5. vdpau — Video Decode and Presentation API for Unix (Linux, поддержка старых видеокарт NVIDIA).
  6. videotoolbox — API от Apple для macOS и iOS).

ffmpeg -hwaccel cuda -i "название_видео.mp4" -c:v hevc_nvenc готовое_видео.mp4

Заключение


Аппаратное кодирование в FFmpeg представляет собой интересный и полезный инструмент, особенно в сценариях, где необходима быстрая обработка больших объёмов видео, таких как архивирование или создание контента. Несмотря на его ограничения и меньшее количество настроек по сравнению с программным кодированием, использование специализированных блоков GPU позволяет значительно сократить время кодирования. Тем не менее, важно понимать, что у каждого метода есть свои достоинства и недостатки, и выбор между аппаратным и программным кодированием должен основываться на конкретных потребностях проекта и желаемом качестве конечного продукта.

© 2024 ООО «МТ ФИНАНС»

Telegram-канал со скидками, розыгрышами призов и новостями IT ?

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


  1. ajijiadduh
    11.11.2024 09:22

    Как видно, при quality=10 распределение микроблоков ухудшается, что приводит к более сильному искажению геометрии по сравнению с quality=0.

    никак не видно, потому что jpeg


    1. Realife Автор
      11.11.2024 09:22

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


      1. ajijiadduh
        11.11.2024 09:22

        чтобы было просто сразу видно - png


  1. AlexeyK77
    11.11.2024 09:22

    Классная статья, спасибо!

    Я недавно выбирал себе новый ноутбук и выбрал специально интел, т.к. на практике в давинчи резолв втройка интела гораздо лучше поддерживает аппаратное кодирование H265 на актуальных на сегодня режимах съемки (10/12bit 4:2:2)

    Источник: https://www.pugetsystems.com/labs/articles/What-H-264-and-H-265-Hardware-Decoding-is-Supported-in-DaVinci-Resolve-Studio-2122/


  1. AndreyAf
    11.11.2024 09:22

    Аппаратное кодирование работает на уровне системных библиотек? там не нужна запущенная графическая сессия с видеодрайвером X11? и работает ли это кодирование одновременно с несколькими процессами ffmpeg?


    1. CherryPah
      11.11.2024 09:22

      Графическая сессия не нужна.


  1. takezi
    11.11.2024 09:22

    Я как то сравнивал software/nvenc по VMAF 0.6.1, и качество у nvenc заметно ниже на самом высоком его пресете, чем при кодировании cpu. И что еще интересней у nvenc не такая уж большая разница между h264/hevc/av1, большее значение имеет битрейт. Если место не проблема, то nvenc вполне себе хорош своей скоростью, но при равном битрейте проигрывает software энкодеру качеством.