FFMPEG Hwaccel ошибка с hwupload

В настоящее время я пытаюсь использовать vaapi hwaccelleration на FFMPEG.

В моей команде у меня есть hwaccel на vaapi, hwaccel_output_fomrat на vaapi, -hwaccel_device на /dev/dri/renderD128, так же как -vf как format=nv12, hwupload и как видео кодек -c:v на h264_vaapi,

Когда я сейчас пытаюсь запустить его, я получаю сообщение об ошибке

grep stderr: [hwupload @ 0x30bb660] A hardware deveice reference is required to upload frames to. [Parsed_hwupload_1 @ 0x30bb560] Query format failed for 'Parsed_hwupload_1': Invalid argument

Можно ли где-нибудь определить ссылку на аппаратное устройство? Я думал, что это то, что я делаю с hwaccel_device, но, похоже, нет. Так что я могу сделать, чтобы заставить это работать?

1 ответ

Вам нужно будет правильно инициализировать ваш аппаратный ускоритель, как показано в документации ниже (может быть, мы должны создать запись вики для этого вовремя?):

Предположим следующий фрагмент:

ffmpeg -re -threads 4 -loglevel debug \
-init_hw_device vaapi=intel:/dev/dri/renderD128 -hwaccel vaapi -hwaccel_output_format vaapi -hwaccel_device intel -filter_hw_device intel \
-i 'udp://$ingest_ip:$ingest_port?fifo_size=9000000' \
-vf 'format=nv12|vaapi,hwupload' \
-c:v h264_vaapi -b:v $video_bitrate$unit -maxrate:v $video_bitrate$unit -qp:v 21 -sei +identifier+timing+recovery_point -profile:v main -level 4 \
-c:a aac -b:a $audio_bitrate$unit -ar 48000 -ac 2 \
-flags -global_header -fflags +genpts -f mpegts 'udp://$feed_ip:$feed_port'

Куда:

(А). VAAPI доступен, и мы свяжем узел DRM /dev/dri/renderD128 на сеанс кодирования, и

(Б). Мы принимаем ввод UDP, где $ingest_ip:$port_ip соответствует известному входному потоку UDP, соответствующему парам IP и портов соответственно, с определенным размером fifo (как указано '?fifo_size=n' параметр).

(С). Кодирование в выходной поток udp, упакованный как транспортный поток MPEG (см. Используемый мультиплексор, mpegts), с необходимыми параметрами, соответствующими выходному IP и парам портов соответственно.

(Г). Определены битрейты видео ($video_bitrate$unit где $unit может быть либо K, либо M, как вам удобно) и битрейт аудио ($audio_bitrate$unit где $unit должен быть в K для кодировок на основе LC AAC), как показано выше, с соответствующими настройками кодера, передаваемыми кодировщикам vaapi. Для справки, на момент написания статьи в FFmpeg имеется четыре доступных видеокодера, а именно:

i. h264_vaapi

ii. hevc_vaapi

iii. vp8_vaapi

iii. vp9_vaapi

С отсутствием кодировщика mjpeg (поскольку он "не представляет интереса в этом контексте) и доступ к документации каждого из этих кодировщиков можно получить через:

ffmpeg -hide_banner -h encoder=$encoder_name

куда $encoder_name соответствует кодировщикам в списке выше.

Для VAAPI применяются следующие примечания:

  1. Кодеры VAAPI могут принимать входные данные только в качестве поверхностей VAAPI, поэтому обычно перед ним должен стоять экземпляр hwupload для преобразования обычного кадра в кадр формата vaapi. Обратите внимание, что внутренний формат поверхности будет получен из формата ввода hwupload, поэтому могут потребоваться дополнительные фильтры формата, чтобы все работало, как показано во фрагменте выше:

я. -init_hw_device vaapi=intel:/dev/dri/renderD128 инициализирует аппаратное устройство с именем vaapi (которое может быть вызвано позже через -hwaccel_device а также -filter_hw_device как показано выше) привязан к узлу рендеринга DRM /dev/dri/renderD128, intel: Префикс может быть отброшен, но его часто полезно определить, какой узел рендеринга использовался именем поставщика в среде, где существует более одного устройства с поддержкой VAAPI, например, на установке с Intel IGP и AMD GPU.

II. Обратите внимание на ограничение формата, определяемое -hwaccel_output_format vaapi, Это необходимо для удовлетворения условия в 1.

III. Затем мы выбираем названную реализацию аппаратного ускорения, vaapi, и вызываем ее как для устройства аппаратного ускорения (-hwaccel_device) и устройство, на которое мы будем загружать аппаратные кадры через фильтр hwupload (-filter_hw_device). Отказ от последнего приведет к ошибке инициализации датчика, как вы заметили.

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

-vf 'format=nv12|vaapi,hwupload'

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

v. Теперь для видеокодера (определяется -c:v $encoder_name), передайте свои аргументы по мере необходимости. Вы можете изменить пример, который я предоставил в приведенном выше фрагменте кода, хотя имеет смысл обратиться к документации по кодировщику, как описано ранее, если вам потребуется дополнительная настройка.

Бонус: работа с кодировщиками QSV на базе Intel:

Я включаю этот раздел для дальнейшего использования, для тех, кто использует MSDK с открытым исходным кодом Intel для поддержки QSV от FFmpeg и связанные с ним кодировщики. Смотрите фрагмент ниже:

ffmpeg -re -threads 4 -loglevel debug \
-init_hw_device qsv=qsv:MFX_IMPL_hw_any -hwaccel qsv -filter_hw_device qsv \
-i 'udp://$ingest_ip:$ingest_port?fifo_size=9000000' \
-vf 'hwupload=extra_hw_frames=10,vpp_qsv:deinterlace=2,format=nv12' \
-c:v h264_qsv -b:v $video_bitrate$unit -rdo 1 -pic_timing_sei 1 -recovery_point_sei 1 -profile high -aud 1 \
-c:a aac -b:a $audio_bitrate$unit -ar 48000 -ac 2 \
-flags -global_header -fflags +genpts -f mpegts 'udp://$feed_ip:$feed_port'

Вы можете увидеть сходство.

Кодеры QSV используют отображения в стиле VAAPI (как описано выше), но с дополнительным ограничением, наложенным на фильтр hwupload: hwupload=extra_hw_frames=10 параметр должен быть использован, иначе инициализация кодера не удастся.

Одной из причин, по которой я не могу рекомендовать кодировщики QSV, несмотря на их предположительно лучшее качество вывода, являются их хрупкие отображения, которые часто завершаются с некоторыми из самых бесполезных ошибок, часто не связанных с тем, как кодер вышел из строя. Где возможно, придерживайтесь VAAPI. Полезность QSV (где применимо) предназначена для кодирования с низким энергопотреблением, как в случае с первоначальными предложениями Intel Apollolake и Anemic Cannonlake.

Надеюсь, эта документация будет вам полезна.

Другие вопросы по тегам