Как кодировать видео 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 (на поддерживаемых платформах):
Этот ответ расширяет ответ выше с некоторыми изменениями:
- Обратите внимание, что для оболочки кодировщика режим пониженного энергопотребления является обязательным (на данный момент). Невозможно установить это (через опцию частного кодека
-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:N (т.е. один входной сигнал используется для обеспечения нескольких выходных данных). Также используется сложная цепочка фильтров, а также подчиненные мультиплексоры, вызывающие базовые мультиплексоры.
На Intel Icelake и более поздних версиях вы можете использоватьvp9_qsv
оболочка кодировщика со следующими известными ограничениями (на данный момент), протестированными в Linux:
(а). Вы должны включитьlow_power mode
поскольку только путь декодирования VDENC предоставляетсяiHD
водитель на данный момент.
(б). Вариант кодирования 1 и extra_data не поддерживаются MSDK.
(с). Заголовок IVF будет вставлен в MSDK по умолчанию, но он не нужен для FFmpeg и по умолчанию остается отключенным.
См. примеры ниже, где принимается один входной сигнал и создается несколько выходных данных с помощьюtee
Рабы мультиплексора звонятsegment
мультиплексоры:
- Если вам нужно деинтерлейсить, вызовите фильтр, как показано:
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"
- Без деинтерлейсинга:
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 передавались соседнему фильтру в сложной цепочке фильтров.
Предупреждения:
- При использовании QuickSync, независимо от входных форматов и используемой оболочки кодера QSV, можно ожидать немного более высокой нагрузки на ЦП, особенно на процессорах меньшего размера, таких как
Intel Atom® x7-E3950 Processor
. Те же накладные расходы значительно снижаются на более мощных процессорах настольного класса и процессорах с поддержкой IrisPro. - Для аппаратного кодирования на основе VP9 я все равно настоятельно рекомендую использовать
vp9_vaapi
вместо этого используется оболочка кодера, и с оговорками (связанными с использованием B-кадров и режимами управления скоростью). VAAPI в целом более стабилен, чем QSV.
Использованная литература:
- См. параметры кодировщика, включая поддерживаемые методы управления скоростью:
ffmpeg -h encoder=vp9_qsv
- На
vpp_qsv
использование фильтра, см.:
ffmpeg -h filter=vpp_qsv
Предупреждение:
Обратите внимание, что SDK требует как минимум 2 потока для предотвращения взаимоблокировок, см. этот блок кода.