Аппаратное транскодирование видео и аудио Intel i5 Kaby Lake в VP9 и FLAC с использованием ffmpeg

1752
Billy

У меня есть около 30 гигабайт видео (в основном MP4, немного MKV и webm), мне нужно транскодировать в 8-битный VP9 со звуком свободного кодека без потерь (FLAC) в контейнере MKV из различных входных кодеков (аудио AAC; H264, VP8, H265 / HEVC и, возможно, некоторые другие видеокодеки). В моей самой мощной системе транскодирование видео с низким разрешением занимает вдвое больше длины видео. Я использую ffmpegв Linux аргументы ffmpeg -i input -c:v libvpx-vp9 -lossless 1 -c:a FLAC -preset veryslow output.mkvдля перекодирования видео без помощи оборудования. Однако недавно мой друг получил процессор Intel i5 Kaby Lake для своего ПК и предложил мне перекодировать видео. Согласно Википедии и ее ссылкам, новые процессоры Kaby Lake поддерживают аппаратное декодирование всех моих входных кодеков и 8-битное кодирование VP9. Итак, у меня есть два вопроса:

  1. Какие ffmpegаргументы может использовать мой друг для перекодирования видео в VP9 и аудио в FLAC в контейнере MKV? Они работают с Windows? Если нет, то это нормально, так как у него двойная загрузка Windows 10-Linux.

  2. Нужна ли veryslowпредустановка, чтобы получить лучшее сжатие?

Я пытался найти ответ на этот вопрос в другом месте, но смог найти только примеры кодирования кодеков, таких как H264 и JPEG.

1

2 ответа на вопрос

4
林正浩

На сегодняшний день можно создавать FFmpeg с VAAPI, который в поддерживаемых системах позволяет кодировать VP9 на интегрированном графическом процессоре Intel.

Новый кодер, когда ffmpeg компилируется с поддержкой VAAPI, вызывается vp9_vaapi.

Чтобы увидеть доступные параметры, которые можно использовать при настройке кодера, запустите:

ffmpeg -hide-banner -h encoder=vp9_vaapi 

Выход:

Encoder vp9_vaapi [VP9 (VAAPI)]: General capabilities: delay  Threading capabilities: none Supported pixel formats: vaapi_vld vp9_vaapi AVOptions: -loop_filter_level <int> E..V.... Loop filter level (from 0 to 63) (default 16) -loop_filter_sharpness <int> E..V.... Loop filter sharpness (from 0 to 15) (default 4) 

Что произойдет, если вы попытаетесь выполнить это на неподдерживаемом оборудовании, скажем, Skylake?

Смотрите пример выходных данных ниже:

[Parsed_format_0 @ 0x42cb500] compat: called with args=[nv12] [Parsed_format_0 @ 0x42cb500] Setting 'pix_fmts' to value 'nv12' [Parsed_scale_vaapi_2 @ 0x42cc300] Setting 'w' to value '1920' [Parsed_scale_vaapi_2 @ 0x42cc300] Setting 'h' to value '1080' [graph 0 input from stream 0:0 @ 0x42cce00] Setting 'video_size' to value '3840x2026' [graph 0 input from stream 0:0 @ 0x42cce00] Setting 'pix_fmt' to value '0' [graph 0 input from stream 0:0 @ 0x42cce00] Setting 'time_base' to value '1/1000' [graph 0 input from stream 0:0 @ 0x42cce00] Setting 'pixel_aspect' to value '1/1' [graph 0 input from stream 0:0 @ 0x42cce00] Setting 'sws_param' to value 'flags=2' [graph 0 input from stream 0:0 @ 0x42cce00] Setting 'frame_rate' to value '24000/1001' [graph 0 input from stream 0:0 @ 0x42cce00] w:3840 h:2026 pixfmt:yuv420p tb:1/1000 fr:24000/1001 sar:1/1 sws_param:flags=2 [format @ 0x42cba40] compat: called with args=[vaapi_vld] [format @ 0x42cba40] Setting 'pix_fmts' to value 'vaapi_vld' [auto_scaler_0 @ 0x42cd580] Setting 'flags' to value 'bicubic' [auto_scaler_0 @ 0x42cd580] w:iw h:ih flags:'bicubic' interl:0 [Parsed_format_0 @ 0x42cb500] auto-inserting filter 'auto_scaler_0' between the filter 'graph 0 input from stream 0:0' and the filter 'Parsed_format_0' [AVFilterGraph @ 0x42ca360] query_formats: 6 queried, 4 merged, 1 already done, 0 delayed [auto_scaler_0 @ 0x42cd580] w:3840 h:2026 fmt:yuv420p sar:1/1 -> w:3840 h:2026 fmt:nv12 sar:1/1 flags:0x4 [hwupload @ 0x42cbcc0] Surface format is nv12. [AVHWFramesContext @ 0x42ccbc0] Created surface 0x4000000. [AVHWFramesContext @ 0x42ccbc0] Direct mapping possible. [AVHWFramesContext @ 0x42c3e40] Created surface 0x4000001. [AVHWFramesContext @ 0x42c3e40] Direct mapping possible. [AVHWFramesContext @ 0x42c3e40] Created surface 0x4000002. [AVHWFramesContext @ 0x42c3e40] Created surface 0x4000003. [AVHWFramesContext @ 0x42c3e40] Created surface 0x4000004. [AVHWFramesContext @ 0x42c3e40] Created surface 0x4000005. [AVHWFramesContext @ 0x42c3e40] Created surface 0x4000006. [AVHWFramesContext @ 0x42c3e40] Created surface 0x4000007. [AVHWFramesContext @ 0x42c3e40] Created surface 0x4000008. [AVHWFramesContext @ 0x42c3e40] Created surface 0x4000009. [AVHWFramesContext @ 0x42c3e40] Created surface 0x400000a. [vp9_vaapi @ 0x409da40] Encoding entrypoint not found (19 / 6). 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 [AVIOContext @ 0x40fdac0] Statistics: 0 seeks, 0 writeouts [aac @ 0x40fcb00] Qavg: -nan [AVIOContext @ 0x409f820] Statistics: 32768 bytes read, 0 seeks Conversion failed! 

Интересными битами являются предупреждения точки входа для кодирования VP9, ​​отсутствующего на этой конкретной платформе, что подтверждается выводом vainfo:

libva info: VA-API version 0.40.0 libva info: va_getDriverName() returns 0 libva info: Trying to open /usr/local/lib/dri/i965_drv_video.so libva info: Found init function __vaDriverInit_0_40 libva info: va_openDriver() returns 0 vainfo: VA-API version: 0.40 (libva 1.7.3) vainfo: Driver version: Intel i965 driver for Intel(R) Skylake - 1.8.4.pre1 (glk-alpha-71-gc3110dc) vainfo: Supported profile and entrypoints VAProfileMPEG2Simple : VAEntrypointVLD VAProfileMPEG2Simple : VAEntrypointEncSlice VAProfileMPEG2Main : VAEntrypointVLD VAProfileMPEG2Main : VAEntrypointEncSlice VAProfileH264ConstrainedBaseline: VAEntrypointVLD VAProfileH264ConstrainedBaseline: VAEntrypointEncSlice VAProfileH264ConstrainedBaseline: VAEntrypointEncSliceLP VAProfileH264Main : VAEntrypointVLD VAProfileH264Main : VAEntrypointEncSlice VAProfileH264Main : VAEntrypointEncSliceLP VAProfileH264High : VAEntrypointVLD VAProfileH264High : VAEntrypointEncSlice VAProfileH264High : VAEntrypointEncSliceLP VAProfileH264MultiviewHigh : VAEntrypointVLD VAProfileH264MultiviewHigh : VAEntrypointEncSlice VAProfileH264StereoHigh : VAEntrypointVLD VAProfileH264StereoHigh : VAEntrypointEncSlice VAProfileVC1Simple : VAEntrypointVLD VAProfileVC1Main : VAEntrypointVLD VAProfileVC1Advanced : VAEntrypointVLD VAProfileNone : VAEntrypointVideoProc VAProfileJPEGBaseline : VAEntrypointVLD VAProfileJPEGBaseline : VAEntrypointEncPicture VAProfileVP8Version0_3 : VAEntrypointVLD VAProfileVP8Version0_3 : VAEntrypointEncSlice VAProfileHEVCMain : VAEntrypointVLD VAProfileHEVCMain : VAEntrypointEncSlice VAProfileVP9Profile0 : VAEntrypointVLD 

Точка входа VLD (для декодирования с переменной длиной) для профиля 0 VP9 является самой дальнейшей, к которой Skylake относится с точки зрения аппаратного ускорения VP9.

Они с тестовыми стендами Kabylake, запускают эти тесты кодирования и отчитываются :-)

2
veikk0

ОБНОВЛЕНИЕ 3 АВГУСТА 2017: Согласно более новому ответу пользователя f, ffmpeg теперь поддерживает кодирование VP9 через VAAPI. У меня все еще нет оборудования, необходимого для тестирования, хотя мой ответ будет иметь ограниченную помощь. Я оставлю свой оригинальный ответ о том, как кодировать VP9 в программном обеспечении ниже.


По какой-то причине FFmpeg не поддерживает кодирование VP9 на аппаратном кодере Intel QuickSync, хотя они поддерживают H.264 и HEVC . Поиск в репозитории исходного кода FFmpeg показывает, что это даже не вопрос его отключения, эта функция просто еще не реализована. Но если он станет доступным в какой-то момент в будущем, его следует использовать таким же образом, как и другие кодеры QuickSync: переключатель, аналогичный -c:v vp9_qsvвместо, -c:v libvpx-vp9должен выполнять свою работу.

Использование командной строки FFmpeg одинаково на всех платформах, за одним известным исключением, которое я знаю, поскольку пользователям Windows приходится использовать NULвместо /dev/nullвывода во время первого прохода двухпроходного кодирования. Но так как вы делаете 1-проход и без потерь, это не должно повлиять на вас.

Если вы хотите ускорить кодирование, то самое очевидное, что вы должны попробовать - установить значение скорости кодирования с помощью -speedпереключателя. Рекомендуемыми значениями являются числа от 0 до 4, причем 0 действительно очень медленный (думаю, что -preset placeboв x264, но хуже), но высокое качество и 4 быстрые при низком качестве. ffmpeg использует -speed 1по умолчанию, что является хорошим соотношением скорости и качества для кодирования с потерями. Однако я только что провел быстрый тест на кодирование без потерь с различными значениями скорости и заметил, что размер файла сократился на 32% при переходе -speed 1к -speed 0кодированию без потерь. Время кодирования утроилось, так что стоит ли использовать 0, зависит только от вас. Файл, созданный пользователем, -speed 4был только на 1.1% больше, чем файл, созданный-speed 1хотя, и это было закодировано на 43% быстрее. Так что я бы сказал, что если вы делаете без потерь и -speed 0слишком медленно, вы могли бы также использовать -speed 4.

Другим важным повышением производительности кодирования является включение многопоточности с помощью -threadsкоммутатора; libvpx не использует автоматически несколько потоков, поэтому пользователь должен установить это вручную. Вы также должны установить количество столбцов плитки с помощью -tile-columnsпереключателя. Эта опция заставляет libvpx разделять видео на несколько фрагментов и кодировать эти фрагменты параллельно для лучшей многопоточности. Рекомендованные числа для количества столбцов и потоков листов можно найти в разделе «Рекомендации по составлению листов и потоков» руководства Google по кодированию VP9., Как вы можете видеть, количество используемых потоков увеличивается с количеством плиток, что означает, что в зависимости от количества доступных ядер ЦП ваш процессор может не быть полностью насыщенным при кодировании видео с разрешением ниже HD. Если вы в основном кодируете видео с низким разрешением, вы можете рассмотреть возможность кодирования нескольких файлов одновременно.

Однако существует еще один способ ускорить кодирование VP9: многопоточность в пределах одного столбца, который можно включить с помощью -row mt 1. По состоянию на 4 апреля (2017, привет, будущие люди), он не является частью выпущенной версии libvpx, но, скорее всего, будет в libvpx 1.6.2. Если вы хотите попробовать это до следующего выпуска, вам нужно скомпилировать последние версии git libvpx и ffmpeg из исходного кода. Просто следуйте руководству по компиляции FFmpeg для вашего дистрибутива, но вместо того, чтобы загружать и распаковывать релиз-архив, делайте git pull https://chromium.googlesource.com/webm/libvpxвместо этого.

Что касается veryslowпресета, он используется только в x264 и x265. libvpx использует -speedпереключатель и дополнительно параметры -quality best, -quality goodили -quality realtime, чтобы определить, сколько времени кодировщику разрешено тратить на кодирование кадра. По умолчанию это -quality goodпотому, что -quality bestон настолько медленный, что его -quality realtimeнельзя использовать и он предназначен для приложений, критичных ко времени, таких как видеовызовы и прямая трансляция.

Отличная рецензия и добро пожаловать в Super User! slhck 7 лет назад 0
Спасибо за ответ. Какие аргументы FFmpeg я могу использовать для кодирования VP9 с помощью VA-API? Я видел, что у источника FFmpeg есть файл с именем 'vaapi_vp9.c'. Я постараюсь, что вы предложили выше, чтобы ускорить процесс. Billy 7 лет назад 0
VA-API может использоваться как для аппаратного ускорения кодирования, так и для декодирования, и в этом случае, к сожалению, это только декодирование. Менее известный факт о FFmpeg состоит в том, что он на самом деле также имеет функцию воспроизведения видео; Google Chrome и версия Firefox для Linux используют его для воспроизведения видео и аудио. Двоичный файл FFmpeg для воспроизведения представляет собой `ffplay`. (Кроме того, я исправил ошибку в своем комментарии: переключатели качества на самом деле являются `-quality good`,` -quality realtime` и т. Д., А не просто `-good` или` -realtime`.) veikk0 7 лет назад 0
На самом деле, я забираю это обратно. Есть новостные статьи, в которых говорится о наличии поддержки кодирования VP9 в VA-API, но я не могу найти ничего определенного, и меня сейчас не просят покопаться в исходном коде. Вы, вероятно, должны взглянуть [здесь] (https://gist.github.com/Brainiarc7/95c9338a737aa36d9bb2931bed379219) и [здесь] (https://gist.github.com/Brainiarc7/4b49f463a08377530df6cecb8171306a). Я бы начал с проверки, был ли FFmpeg собран с помощью `--enable-vaapi` и, если да, запустил` ffmpeg -decoders | grep vaapi` и `ffmpeg -h encoder =`. У меня есть процессор AMD, поэтому я не могу проверить это сам. veikk0 7 лет назад 0
Хорошо спасибо. Я посмотрю в те завтра. Billy 7 лет назад 0
@ user13178 Пожалуйста, посмотрите ответ ниже - теперь возможно собрать ffmpeg с аппаратной поддержкой кодирования VP9. Вы можете [редактировать] свой пост. slhck 6 лет назад 0
Здравствуйте @Billy, смотрите мой ответ ниже. 林正浩 6 лет назад 0

Похожие вопросы