Ошибка 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, но похоже, что нет. Итак, что я могу сделать, чтобы заставить это работать?


person nameless    schedule 03.08.2017    source источник


Ответы (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, для кодировок на основе AAC LC), как показано выше, с соответствующими настройками кодировщика. переданы энкодерам 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). Как вы заметили, пропуск последнего приведет к сбою инициализации кодировщика.

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

-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 и анемичные первоначальные предложения Cannonlake.

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

person Dennis Mungai    schedule 16.05.2018