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 применяются следующие примечания:
- Кодеры 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.
Надеюсь, эта документация будет вам полезна.