1

У меня есть около 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.

2 ответа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, запускают эти тесты кодирования и отчитываются :-)

3

ОБНОВЛЕНИЕ 3 АВГУСТА 2017: Согласно новому ответу пользователя 林正浩, 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 предназначен для использования в таких критичных ко времени приложениях, как видеовызовы и прямая трансляция.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .