Как кодировать видео VP9 с помощью ffmpeg и vp9_qsv?

Я пытаюсь использовать ffmpeg для кодирования видео VP9 с помощью vp9_qsv (аппаратная поддержка Intel Quick Sync Video) в Windows 10. Ранее я успешно кодировал видео VP9 с помощью libvpx-vp9, но это использует процессор и работает довольно медленно. Теперь, когда я пытаюсь переключиться на vp9_sqv, я получаю сообщения об ошибках, которые не очень полезны, а также отсутствует документация.

ffmpeg.exe -i input.mp4 -c:v vp9_qsv -c:a copy output.webm

      Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.20.100
  Duration: 00:00:46.74, start: 0.040000, bitrate: 15752 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x1080, 15561 kb/s, 25.02 fps, 25 tbr, 12800 tbn, 50 tbc (default)
    Metadata:
      handler_name    : VideoHandler
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 193 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> vp9 (vp9_qsv))
  Stream #0:1 -> #0:1 (copy)
Press [q] to stop, [?] for help
[vp9_qsv @ 000001b156147b40] Selected ratecontrol mode is unsupported
[vp9_qsv @ 000001b156147b40] Low power mode is unsupported
[vp9_qsv @ 000001b156147b40] Current frame rate is unsupported
[vp9_qsv @ 000001b156147b40] Current picture structure is unsupported
[vp9_qsv @ 000001b156147b40] Current resolution is unsupported
[vp9_qsv @ 000001b156147b40] Current pixel format is unsupported
[vp9_qsv @ 000001b156147b40] some encoding parameters are not supported by the QSV runtime. Please double check the input parameters.
Error initializing output stream 0:0 -- Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height
Conversion failed!

Я попытался указать некоторые вещи, которые он запрашивает, но это приводит к точно таким же ошибкам.

ffmpeg.exe -i input.mp4 -c:v vp9_qsv -preset veryslow -low_power 0 -b:v 800K -c:a copy output.webm

РЕДАКТИРОВАТЬ: Основываясь на предложении Мокубая, я теперь получаю следующее:ffmpeg.exe -init_hw_device qsv=hw -filter_hw_device hw -f rawvideo -pix_fmt yuv420p -s:v 1920x1080 -i input.mp4 -vf hwupload=extra_hw_frames=64,format=qsv -c:v vp9_qsv -c:a copy output.webm

      [AVHWDeviceContext @ 000001d30eccb640] Error setting child device handle: -6

2 ответа

Во-первых, возможно, стоит иметь в виду, что Intel официально не включала поддержку VP9 в своем кодировщике Quicksync до процессоров Tiger Lake. Есть некоторые намеки на то, что его можно будет заставить работать в Linux на процессорах Kaby Lake (7-го поколения) и выше с некоторыми изменениями, но один пользователь, внесший вклад в разработку медиадрайвера Intel, утверждает, что

извините за поздний ответ, мы не будем включать кодирование VP9 на платформах Gen9. Если кто-то все еще этого хочет, он может попробовать PR #717, он добавит поддержку кодирования VP9. но конструкция Gen9 VME не оптимизирована для VP9. поэтому у нас есть опасения по этому поводу.

Gen9 — это большое количество платформ до Tiger Lake, которые сами используют графику Gen 11.

Тем не менее, раздел примеров QSV на вики FFMPEG: Hardware/QuickSync, похоже, предполагает, что вы можете добавить-init_hw_device qsv=hw -filter_hw_device hw -f rawvideo -pix_fmt yuv420p -s:v 1920x1080перед вашим-i input.mp4для инициализации оборудования (при условии, что источник YUV420).

Затем используйте-vf hwupload=extra_hw_frames=64,format=qsvперед вашим-c:vчтобы указать формат, который хочет кодер, хотя у меня нет функционального оборудования для тестирования.

По крайней мере, вики FFMPEG действительно обещает, но даже на процессоре Tiger Lake я не могу заставить ее перекодировать какое-либо видео. Независимо от того, что я пытаюсь, я получаю следующие строки

      [swscaler @ 000001c902edec40] deprecated pixel format used, make sure you did set range correctly
[vp9_qsv @ 000001c97dc7ef40] Selected ratecontrol mode is unsupported
[vp9_qsv @ 000001c97dc7ef40] some encoding parameters are not supported by the QSV runtime. Please double check the input parameters.
Error initializing output stream 0:0 -- Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height
Conversion failed!

Я могу с удовольствием использовать кодировщик h264_qvc, но переключение на vp9_qvc выдает ошибку, и я не могу найти никаких подсказок о том, как указать необходимыеratecontrol.

Мой пример командной строки, которая работает

.\ffmpeg.exe -init_hw_device qsv=hw -i 'MVI_7664.mov' -vf hwupload=extra_hw_frames=64,format=qsv -c:v h264_qsv -strict Experiment -preset Veryslow -c:вывод копии.mkv -y

но он использует h264, а не VP9. Возможно, мне нужен более новый FFMPEG.

Использование Intel QuickSync (на поддерживаемых платформах):

Этот ответ расширяет ответ выше с некоторыми изменениями:

  1. Обратите внимание, что для оболочки кодировщика режим пониженного энергопотребления является обязательным (на данный момент). Невозможно установить это (через опцию частного кодека-low_power 1) приведет к сбою, после чего среда выполнения MFX распечатает журнал, подобный:
      [vp9_qsv @ 000001b156147b40] Selected ratecontrol mode is unsupported
[vp9_qsv @ 000001b156147b40] Low power mode is unsupported
[vp9_qsv @ 000001b156147b40] Current frame rate is unsupported
[vp9_qsv @ 000001b156147b40] Current picture structure is unsupported
[vp9_qsv @ 000001b156147b40] Current resolution is unsupported
[vp9_qsv @ 000001b156147b40] Current pixel format is unsupported
[vp9_qsv @ 000001b156147b40] some encoding parameters are not supported by the QSV runtime. Please double check the input parameters.
Error initializing output stream 0:0 -- Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height
Conversion failed!

Это связано с тем, что среда выполнения QSV MFX должна согласовать все требования с драйвером устройства (в Linux), прежде чем сеанс MFX сможет успешно зарегистрироваться. Насколько мне известно, на данный момент эта оболочка будет работать только в Linux. Это может измениться в ближайшем будущем.

  1. Все приведенные ниже примеры показывают случай транскодирования 1:N (т.е. один входной сигнал используется для обеспечения нескольких выходных данных). Также используется сложная цепочка фильтров, а также подчиненные мультиплексоры, вызывающие базовые мультиплексоры.

На Intel Icelake и более поздних версиях вы можете использоватьvp9_qsvоболочка кодировщика со следующими известными ограничениями (на данный момент), протестированными в Linux:

(а). Вы должны включитьlow_power modeпоскольку только путь декодирования VDENC предоставляетсяiHDводитель на данный момент.

(б). Вариант кодирования 1 и extra_data не поддерживаются MSDK.

(с). Заголовок IVF будет вставлен в MSDK по умолчанию, но он не нужен для FFmpeg и по умолчанию остается отключенным.

См. примеры ниже, где принимается один входной сигнал и создается несколько выходных данных с помощьюteeРабы мультиплексора звонятsegmentмультиплексоры:

  1. Если вам нужно деинтерлейсить, вызовите фильтр, как показано:
          ffmpeg -nostdin -y -fflags +genpts \
    -init_hw_device vaapi=va:/dev/dri/renderD128,driver=iHD \
    -filter_hw_device va -hwaccel vaapi -hwaccel_output_format vaapi \
    -threads 4 -vsync 1 -async 1 \
    -i 'http://server:port' \
    -filter_complex "[0:v]hwmap=derive_device=qsv,format=qsv,vpp_qsv=deinterlace=2:async_depth=4,split[n0][n1][n2]; \
    [n0]vpp_qsv=w=1152:h=648:async_depth=4[v0]; \
    [n1]vpp_qsv=w=848:h=480:async_depth=4[v1];
    [n2]vpp_qsv=w=640:h=360:async_depth=4[v2]" \
    -b:v:0 2250k -maxrate:v:0 2250k -bufsize:v:0 360k -c:v:0 vp9_qsv -g:v:0 50 -r:v:0 25 -low_power:v:0 2 \
    -b:v:1 1750k -maxrate:v:1 1750k -bufsize:v:1 280k -c:v:1 vp9_qsv -g:v:1 50 -r:v:1 25 -low_power:v:1 2 \
    -b:v:2 1000k -maxrate:v:2 1000k -bufsize:v:2 160k -c:v:2 vp9_qsv -g:v:2 50 -r:v:2 25 -low_power:v:2 2 \
    -c:a aac -b:a 128k -ar 48000 -ac 2 \
    -flags -global_header -f tee -use_fifo 1 \
    -map "[v0]" -map "[v1]" -map "[v2]" -map 0:a \
    "[select=\'v:0,a\':f=segment:segment_time=5:segment_format_options=movflags=+faststart]$output_path0/output%03d.mp4| \
     [select=\'v:1,a\':f=segment:segment_time=5:segment_format_options=movflags=+faststart]$output_path1/output%03d.mp4| \
     [select=\'v:2,a\':f=segment:segment_time=5:segment_format_options=movflags=+faststart]$output_path2/output%03d.mp4"
  1. Без деинтерлейсинга:
          ffmpeg -nostdin -y -fflags +genpts \
    -init_hw_device vaapi=va:/dev/dri/renderD128,driver=iHD \
    -filter_hw_device va -hwaccel vaapi -hwaccel_output_format vaapi \
    -threads 4 -vsync 1 -async 1 \
    -i 'http://server:port' \
    -filter_complex "[0:v]hwmap=derive_device=qsv,format=qsv,split=3[n0][n1][n2]; \
    [n0]vpp_qsv=w=1152:h=648:async_depth=4[v0]; \
    [n1]vpp_qsv=w=848:h=480:async_depth=4[v1];
    [n2]vpp_qsv=w=640:h=360:async_depth=4[v2]" \
    -b:v:0 2250k -maxrate:v:0 2250k -bufsize:v:0 2250k -c:v:0 vp9_qsv -g:v:0 50 -r:v:0 25 -low_power:v:0 2  \
    -b:v:1 1750k -maxrate:v:1 1750k -bufsize:v:1 1750k -c:v:1 vp9_qsv -g:v:1 50 -r:v:1 25 -low_power:v:1 2  \
    -b:v:2 1000k -maxrate:v:2 1000k -bufsize:v:2 1000k -c:v:2 vp9_qsv -g:v:2 50 -r:v:2 25 -low_power:v:2 2  \
    -c:a aac -b:a 128k -ar 48000 -ac 2 \
    -flags -global_header -f tee -use_fifo 1 \
    -map "[v0]" -map "[v1]" -map "[v2]" -map 0:a \
    "[select=\'v:0,a\':f=segment:segment_time=5:segment_format_options=movflags=+faststart]$output_path0/output%03d.mp4| \
     [select=\'v:1,a\':f=segment:segment_time=5:segment_format_options=movflags=+faststart]$output_path1/output%03d.mp4| \
     [select=\'v:2,a\':f=segment:segment_time=5:segment_format_options=movflags=+faststart]$output_path2/output%03d.mp4"

Обратите внимание, что мы используемvpp_qsv filterсasync_depthдля параметра установлено значение 4. Это значительно повышает производительность перекодирования по сравнению с использованиемscale_qsvиdeinterlace_qsv. См. этот коммит на git FFmpeg.

Примечания:

Это будет работать только в Linux с текущей версиейmedia-driverпакет для аппаратного ускорения VAAPI, который ffmpeg выбирает через-init_hw_device vaapi=va:/dev/dri/renderD128,driver=iHD -filter_hw_device va -hwaccel vaapi -hwaccel_output_format vaapiпривязан к узлу DRI/dev/dri/rendereD128. Это значение по умолчанию для систем с одним графическим процессором. Однако это изменится, если будет присутствовать более одного графического процессора. Мы используем VAAPI для аппаратного ускорения, поскольку он более устойчив к ускорению декодирования. Декодирование QuickSync на удивление нестабильно и приводит к ошибкам MFX в нескольких входных файлах.

Мы также получаем контекст QSV черезhwmapфильтр, вызываемый черезhwmap=derive_device=qsv,format=qsvкоторый затем немедленно привязывается кformat=qsvфильтр, указывая, что мы хотим, чтобы кадры QSV H/W передавались соседнему фильтру в сложной цепочке фильтров.

Предупреждения:

  1. При использовании QuickSync, независимо от входных форматов и используемой оболочки кодера QSV, можно ожидать немного более высокой нагрузки на ЦП, особенно на процессорах меньшего размера, таких какIntel Atom® x7-E3950 Processor. Те же накладные расходы значительно снижаются на более мощных процессорах настольного класса и процессорах с поддержкой IrisPro.
  2. Для аппаратного кодирования на основе VP9 я все равно настоятельно рекомендую использоватьvp9_vaapiвместо этого используется оболочка кодера, и с оговорками (связанными с использованием B-кадров и режимами управления скоростью). VAAPI в целом более стабилен, чем QSV.

Использованная литература:

  1. См. параметры кодировщика, включая поддерживаемые методы управления скоростью:
      ffmpeg -h encoder=vp9_qsv
  1. Наvpp_qsvиспользование фильтра, см.:
      ffmpeg -h filter=vpp_qsv

Предупреждение:

Обратите внимание, что SDK требует как минимум 2 потока для предотвращения взаимоблокировок, см. этот блок кода.

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