В прошлой статье, посвящённой изучению кодирования на 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 лет смогла достаточно набить руку, чтобы нагнать их.
Нет, всё же до AMF(и это библиотека, а VCE — сам аппаратный энкодер) у AMD был VCE (2011 г.).
В профессиональной сфере программное кодирование трудно сравнить с аппаратным. Следует отметить, что все аппаратные кодеры, кроме одного, не поддерживают 12-битное видео, в отличие от программных решений. Это лишь одно из очевидных преимуществ. Аппаратное кодирование нацелено на быстрое кодирование больших объёмов данных, но мы рассмотрим только направление кодирования различных записей без стриминга. Если вы хотите углубиться в медленное программное кодирование с хорошим сжатием на программном кодеке, у меня уже была статья на эту тему, тоже по HEVC (H265).
Как включить аппаратное кодирование в FFmpeg
Простой шаг, на котором многие допускают ошибки. libx265 — это исключительно кодирование на процессоре. Чтобы указать AMD AMF — hevc_amf
, NVIDIA NVENC — hevc_nvenc
, INTEL QVS — hevc_qvs
.
Что рассматриваем?
Я опускаю все параметры, кроме тех, что могут понадобиться при перекодировании записей реальной жизни или игр. Для всего остального есть OBS в большинстве случаев. У меня также нет практики в работе с потоковым видео, поэтому этот сценарий я не смогу раскрыть.
Все команды, приведённые в статье, работают как на Linux, так и на Windows.
Аппаратный кодек AMD AMF
VCE был представлен с серией Radeon HD 7000 22 декабря 2011 года. Позднее в 2016 году был представлен AMF как библиотека для доступа к VCE.
▍ Quality
Это похоже на родной Preset. С его помощью мы можем указать скорость кодирования по формуле «время / вес и качество». Так же, как и Preset настройка, он влияет на параметры кодирования.
- Speed (0)
- Balanced (5)
- Quality (10)
Разница во времени кодирования между параметрами speed
и balanced
составляет около 3-5%, но эффект оказывает существенное влияние при том же битрейте.
ffmpeg -i "название_видео.mp4" -c:v hevc_amf -quality 0 готовое_видео.mp4
ImgSli. Как видно, при quality=10 распределение микроблоков ухудшается, что приводит к более сильному искажению геометрии по сравнению с quality=0.
▍ RC
RC (Rate Control) — это система управления битрейтом при кодировании видео. Она определяет, как распределять доступную пропускную способность для достижения нужного качества видео в зависимости от выбранного режима.
- CBR (Constant Bitrate) — постоянный битрейт. В этом режиме кодек поддерживает фиксированную скорость потока, что гарантирует предсказуемое использование пропускной способности, но может привести к ухудшению качества в сложных сценах.
- VBR (Variable Bitrate) — переменный битрейт. В этом режиме поток данных меняется в зависимости от сложности сцены. В простых сценах он уменьшается, в сложных — увеличивается, что позволяет более эффективно использовать пропускную способность и повышать качество.
- QVBR (Quality Variable Bitrate) — гибрид VBR, где целевой поток зависит от качества, задаваемого пользователем. Он адаптируется для сохранения постоянного уровня качества, но всё равно не дотягивает до CQP.
- CQP (Constant Quantization Parameter) — режим с постоянным параметром квантования. В этом режиме качество видео контролируется напрямую параметром квантования, без фиксированного битрейта. Это полезно, если основной целью является максимальное качество видео, а размер файла не важен.
Я рекомендую использовать CQP в нашем сценарии. Возможные значения — 0-51. Их необходимо указывать с помощью qp_i и qp_p.
ffmpeg -i "название_видео.mp4" -c:v hevc_amf -rc cqp qp_i 20 qp_p 21 готовое_видео.mp4
Аппаратный кодек NVENC — Nvidia
В марте 2012 года были представлены видеокарты Nvidia из линейки Kepler (GTX 600) и аппаратный кодек NVENC. Конечно, с того момента он значительно изменился, и это проявляется не только в появлении новых кодеков, но и в инженерных решениях. Так, в 2012 году лимит составлял всего два одновременных потока кодирования видео, а на сегодняшний день уже восемь.
▍ Preset
Стандартный preset. Однако мы пропустим первые 11 настроек, относящихся к стримингу.
- P1 (Ultra Fast)
- P2 (Fast)
- P3 (Medium)
- P4 (Slow)
- P5 (Very Slow)
- P6 (Placebo)
- P7 (Lossless)
На деле, разница в скорости кодирования почти отсутствует.
ffmpeg -i "название_видео.mp4" -c:v hevc_nvenc -preset p1 готовое_видео.mp4
ImgSli. Невооружённым взглядом видно, что при том же битрейте Placebo оставляет значительно меньше цветовых артефактов и шума по сравнению с Ultra Fast.
▍ RC
Выполняет такую же функцию, как и в технологии AMD AMF — отвечает за управление скоростью, известное как Rate Control.
- CBR (Constant Bitrate) – постоянный битрейт.
- VBR (Variable Bitrate) – переменный битрейт.
- 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, что напихали под одну гребёнку всё подряд.
- veryfast
- faster
- fast
- medium
- slow
- slower
- veryslow
ffmpeg -i "название_видео.mp4" -c:v hevc_qsv -preset 1 готовое_видео.mp4
ImgSli. Вероятно, пресеты перепутаны, так как после нескольких проверок выяснилось, что ultrafast работает лучше, чем veryslow, что не кажется логичным. Основные отличия видны на текстуре участка дерева внизу кадра и неправильной геометрии левой руки. Эти объекты оставались в поле зрения не более двух кадров, вероятно, это влияние низкого значения B кадров
▍ Методы управления битрейтом
В Intel QSV нет нормальной реализации CQP, которым мы ранее всегда пользовались. Точнее, она существует, но разобраться в этом даже мне сложно. Поэтому остаются только методы постоянного и переменного битрейта.
- CBR (Constant Bitrate) — постоянный битрейт. Распределение потока данных по всему видео одинаковое, это обеспечивает предсказуемость веса файла, но не гарантирует стабильного качества. Если значение битрейта окажется недостаточно высоким, то в сложных сценах могут появиться артефакты. В этом случае придётся повышать битрейт, из-за чего файл будет весить больше на участках видео, не требующих этого, что нелогично при задаче сжатия видео.
ffmpeg -i "название_видео.mp4" -c:v hevc_qsv -b:v 4M готовое_видео.mp4
- 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 — аппаратное ускорение позволяет использовать специализированные блоки графических процессоров.
- cuda — использует CUDA (NVIDIA GPU).
- qsv — Intel Quick Sync Video (QSV).
- dxva2 — Microsoft DirectX Video Acceleration 2 (только Windows).
- vaapi — Video Acceleration API (Linux, поддержка Intel и AMD).
- vdpau — Video Decode and Presentation API for Unix (Linux, поддержка старых видеокарт NVIDIA).
- videotoolbox — API от Apple для macOS и iOS).
ffmpeg -hwaccel cuda -i "название_видео.mp4" -c:v hevc_nvenc готовое_видео.mp4
Заключение
Аппаратное кодирование в FFmpeg представляет собой интересный и полезный инструмент, особенно в сценариях, где необходима быстрая обработка больших объёмов видео, таких как архивирование или создание контента. Несмотря на его ограничения и меньшее количество настроек по сравнению с программным кодированием, использование специализированных блоков GPU позволяет значительно сократить время кодирования. Тем не менее, важно понимать, что у каждого метода есть свои достоинства и недостатки, и выбор между аппаратным и программным кодированием должен основываться на конкретных потребностях проекта и желаемом качестве конечного продукта.
© 2024 ООО «МТ ФИНАНС»
Автор: Realife