vpxenc

vpxenc кодирует необработанное видео и потоки Y4M в VP8 или VP9, позволяет выбрать WebM либо IVF, управлять битрейтом и качеством, выполнять один или два прохода, настраивать ключевые и AltRef-кадры, многопоточность, тайлы, профили и глубину цвета, а также выводить диагностическую статистику. Инструмент подходит для сценариев, где нужен прямой доступ к возможностям libvpx через командную строку: от пакетной подготовки VP9/WebM до воспроизводимых тестовых кодирований и real-time CBR.

Работа vpxenc строится вокруг одной исходной видеопоследовательности и набора параметров кодера. Программа не заменяет медиаконвертер: она не разбирает произвольные MP4, MKV или MOV как полноценный демультиплексор и не занимается аудиодорожками. На вход ей обычно дают Y4M либо сырой YUV-поток, а если источник хранится в другом контейнере, декодирование и преобразование пиксельного формата выполняют внешним инструментом и передают кадры через файл или канал.

Сильная сторона vpxenc — доступ к параметрам самого VP8/VP9-кодера без промежуточного графического слоя. Можно явно задать режим контроля скорости, пределы квантизатора, размер буфера CBR, расстояние между ключевыми кадрами, глубину преданализа, AltRef, адаптивное квантование, tile columns, row-based multithreading и поведение при кодировании экранного либо зернистого материала. При этом набор допустимых ключей зависит от того, какие возможности включены при сборке libvpx, поэтому при автоматизации полезно проверять локальный вывод vpxenc --help.

Скачать vpxenc

Оценка 9.7Рекомендуем
  • Конвертация видео
  • Сжатие файлов
  • Просто для новичков
Скачать бесплатно на Windows
Лучшая альтернатива
vpxenc
Оценка 8.5
  • Только командная строка
  • Не открывает MP4 напрямую
  • Нет работы с аудио
Скачать vpxenc
Загрузка начнётся после нажатия

Что именно делает vpxenc

vpxenc — командный видеокодер из набора libvpx. Его базовая задача формулируется просто: прочитать последовательность несжатых кадров, пропустить их через VP8- или VP9-кодер и записать полученный видеопоток в WebM либо IVF. В отличие от универсальных программ для транскодирования, он сосредоточен на параметрах кодека. Здесь нет монтажа, дорожки эффектов, встроенного проигрывателя, выбора звуковых кодеков или привычного диалога экспорта. Пользователь управляет теми же сущностями, которые присутствуют в API libvpx: конфигурацией кодера, rate control, GOP, reference frames, профилем, цветовыми характеристиками и параметрами параллелизма.

Типовая форма запуска выглядит так:

vpxenc [параметры] -o output.webm input.y4m

Ключ -o или --output задаёт выходной файл. Кодек лучше указывать явно через --codec=vp8 или --codec=vp9, особенно в скриптах: конкретная сборка может содержать один или оба кодера, а выбор по умолчанию зависит от состава бинарника. Формат контейнера выбирается --webm либо --ivf; при наличии WebM I/O программа обычно пишет WebM, но явный ключ делает команду самодокументируемой.

Важное следствие такой архитектуры — vpxenc не улучшает источник сам по себе. Если исходный MP4 содержит H.264, HEVC, AV1 или другое сжатое видео, сначала нужен декодер. Если необходимо масштабирование сложным фильтром, деинтерлейс, цветокоррекция, шумоподавление специализированным алгоритмом, работа с субтитрами или аудио, эти операции тоже выполняются до vpxenc либо после него. Сам кодер получает уже подготовленные кадры и отвечает в первую очередь за их компрессию.

Какие задачи подходят инструменту

  • кодирование Y4M в VP8 или VP9 с точным контролем параметров;
  • подготовка WebM-видеопотока без аудио;
  • получение IVF для тестов, анализа и последующего мультиплексирования;
  • двухпроходное VBR-кодирование с файлом статистики первого прохода;
  • CBR и режим реального времени с буферными ограничениями;
  • VP9 с высокой битностью, профилями 2/3 и соответствующими форматами исходных кадров, если такая поддержка включена в сборке;
  • сравнительные кодерные эксперименты, где важно фиксировать набор параметров и повторять запуск;
  • подача кадров из FFmpeg или другого декодера по pipe без промежуточного контейнера.

При этом vpxenc не стоит воспринимать как фронтенд для всей медиапроизводственной цепочки. Если нужно открыть ролик, выбрать пресет и получить готовый файл с видео, звуком, метаданными и несколькими дорожками, универсальный транскодер окажется удобнее. vpxenc полезен в другом месте цепочки — там, где контролируется именно VP8/VP9-энкодинг.

Интерфейс: командная строка и служебный вывод

Графических окон у vpxenc нет. Фактический интерфейс — список аргументов и текстовый статус в терминале. Полный перечень параметров вызывается командой vpxenc --help. В нём параметры сгруппированы на общие, глобальные настройки кодера, rate control, двухпроходный rate control, размещение keyframe, а затем отдельные опции VP8 и VP9. Если конкретная функция не скомпилирована в библиотеку, соответствующего пункта в локальном списке может не быть.

Справка vpxenc 1.15.0 с форматом запуска и общими параметрами кодирования
Справка vpxenc 1.15.0 с форматом запуска и общими параметрами кодирования

При добавлении -v или --verbose vpxenc печатает распознанный формат источника, имя выходного файла и структуру фактических параметров кодера. Во время работы строка прогресса показывает номер прохода, количество обработанных кадров, объём накопленного битстрима, скорость и оценку оставшегося времени, когда её можно вычислить. Ключ -q или --quiet, наоборот, отключает обычный прогресс — это удобно в пакетных заданиях, где журнал должен содержать только предупреждения и ошибки.

Для более технической диагностики предусмотрены --psnr, --q-hist=N и --rate-hist=N. Первый выводит PSNR в строке состояния и итоговые значения, два других строят гистограммы квантования и скорости по заданному числу корзин. Есть и --test-decode=off|warn|fatal: кодер может декодировать собственный результат и реагировать на несовпадения как предупреждением либо фатальной ошибкой. Это не заменяет полноценную проверку файла внешними средствами, но полезно для тестовых сборок и автоматизированных прогонов.

Входные данные: Y4M и сырой YUV

Самый удобный вход для vpxenc — Y4M. Заголовок YUV4MPEG2 содержит ширину, высоту, частоту кадров и описание цветовой дискретизации, поэтому программе не приходится угадывать геометрию последовательности. Для сырого YUV таких метаданных нет: это просто байты плоскостей пикселей, и пользователь обязан передать размеры и частоту кадров вручную. Ошибка в одном из этих параметров не починится автоматически — кадры будут интерпретированы с неправильными границами, длина последовательности съедет или кодирование остановится на некорректном размере.

В текущем интерфейсе предусмотрены явные переключатели входного layout: --nv12, --yv12, --i420, --i422, --i444 и --i440. Если сырой источник подаётся без такого ключа, базовым вариантом считается I420. Выбор должен соответствовать реальному расположению и размеру плоскостей; расширение файла .yuv само по себе ничего не говорит о subsampling или порядке компонент.

КлючЧто означает для входаЧто важно проверить
--i420планарный YUV 4:2:0, порядок Y-U-Vширину, высоту и размер кадра 1,5 байта на пиксель при 8 битах
--yv12планарный YUV 4:2:0, порядок Y-V-Uне перепутать плоскости U и V с I420
--nv12Y с чередующейся UV-плоскостью 4:2:0источник действительно должен быть NV12, а не I420
--i422планарный 4:2:2профиль VP9 должен допускать выбранную цветовую структуру
--i444планарный 4:4:4объём исходника значительно больше, профиль должен соответствовать
--i440планарный 4:4:0используется редко; особенно важно не ошибиться в формате

Для raw-входа размеры задаются -w/--width и -h/--height. Частота кадров — --fps=rate/scale, например 30000/1001 для приблизительно 29,97 кадра/с. У Y4M эти параметры обычно читаются из заголовка, хотя при построении сложных пайплайнов всё равно полезно контролировать, какие значения попали в кодер.

Чем FPS отличается от timebase

--fps описывает частоту кадров потока, тогда как --timebase задаёт точность временных меток в виде дроби. Это разные величины. В справке vpxenc для timebase используется представление длительность одного тика в секундах, а базовое значение — 1/1000. Для обычной последовательности с постоянной частотой кадров чаще всего достаточно корректного FPS и стандартной временной базы. Вмешиваться в timebase стоит, когда последующий контейнер, тестовый стенд или синхронизация предъявляют конкретные требования к шкале timestamp.

Нулевая или отрицательная дробь для FPS/timebase недопустима; код проверяет положительность числителя и ненулевой знаменатель. Если в скрипте значения формируются программно, такую проверку лучше выполнять до запуска vpxenc, чтобы не получить остановку уже после подготовки большого временного YUV.

Подача через стандартный ввод

Для источников, которые vpxenc не умеет демультиплексировать, практичен конвейер с внешним декодером. Например, FFmpeg может прочитать MP4 или MKV, декодировать видео, привести его к Y4M и отправить в stdout; vpxenc читает этот поток из stdin. Общая схема выглядит так:

ffmpeg -i input.mp4 -map 0:v:0 -f yuv4mpegpipe - | \
  vpxenc --codec=vp9 --good --cpu-used=2 --webm -o output.webm -

Такой подход не означает, что vpxenc поддерживает MP4 на входе. MP4 разбирает FFmpeg; vpxenc видит уже несжатые кадры. Плюс pipe — отсутствие огромного временного YUV-файла. Минус — сложнее повторно использовать первый этап, а при двухпроходном кодировании источник обычно придётся декодировать заново для второго прохода, если статистика и кадры не кэшируются отдельно.

Выходные форматы: WebM и IVF

vpxenc пишет видеоданные в WebM или IVF. WebM удобен как конечный контейнер для VP8/VP9-видеопотока, но сам vpxenc не превращается из-за этого в многодорожечный мультиплексор: аудио здесь не кодируется и не копируется. Если финальный WebM должен содержать Opus/Vorbis и метаданные, видеодорожку после кодирования можно объединить с аудио внешним muxer.

IVF — простой контейнер для кодированного видеопотока. Он особенно полезен в тестах кодека, при анализе битстрима и в цепочках, где финальное мультиплексирование будет выполнено позднее. Ключ --output-partitions связан именно с IVF: справка прямо указывает, что вывод partitions требует IVF. Если использовать его вместе с WebM, программа не сможет выполнить ожидаемую операцию.

Примеры выбора контейнера:

vpxenc --codec=vp9 --webm -o video.webm input.y4m
vpxenc --codec=vp9 --ivf  -o video.ivf  input.y4m

Расширение файла желательно согласовывать с ключом. vpxenc ориентируется на выбранный режим записи, а не на человеческое ожидание от имени .webm или .ivf. В автоматизации явные --webm/--ivf снижают риск получить содержимое одного типа под расширением другого.

Выбор между VP8 и VP9

Кодек задаётся параметром --codec. Для предсказуемого сценария его лучше всегда писать явно. VP8 и VP9 используют общую основу конфигурации vpxenc — размеры, FPS, rate control, число проходов, keyframe — но имеют разные специфические инструменты. VP8 сохраняет параметры вроде token partitions и собственного screen content mode; VP9 добавляет tiles, row multithreading, расширенные профили, высокую битность, tune-content, TPL и дополнительные режимы адаптивного квантования.

Команды:

vpxenc --codec=vp8 --webm -o output-vp8.webm input.y4m
vpxenc --codec=vp9 --webm -o output-vp9.webm input.y4m

Само переключение кодека не гарантирует одинакового поведения при тех же числовых параметрах. Например, диапазоны и смысл --cpu-used, внутренняя структура reference frames и степень выигрыша от многопоточности различаются. Нельзя бездумно переносить удачную строку VP8 на VP9, оставив все значения прежними. Гораздо надёжнее сохранить общую цель — допустимый битрейт, требование к задержке, целевую совместимость — и настроить специфические ключи заново.

Когда нужен VP8

VP8 остаётся полезен в цепочках, где именно этот формат является требованием получателя или тестового окружения. В vpxenc для него доступны VBR/CBR/CQ, один и два прохода, AltRef, ARNR, контроль квантизатора, --token-parts, фильтрация шумов, --screen-content-mode и прочие настройки. При этом VP8 не имеет VP9-профилей с 10/12-битной глубиной и 4:2:2/4:4:4 в том же смысле, поэтому для high-bit-depth и расширенной цветовой структуры обычно рассматривают VP9.

--token-parts задаёт число независимых coefficient partitions в логарифмической форме: значение 0 соответствует одной, 1 — двум, 2 — четырём, 3 — восьми. Это влияет на параллелизм энтропийной части VP8 и на структуру потока. Повышать значение без причины не стоит: задача параметра — не добавить качество, а изменить степень распараллеливания и декодируемость.

Когда нужен VP9

VP9 в vpxenc предоставляет более широкий набор механизмов для современных задач: tile columns/rows, row-based multithreading, профили 0–3, high bit depth в соответствующей сборке, tune-content=screen и film, TPL, frame-parallel decodability, несколько вариантов AQ, управление Golden/AltRef-интервалами, уровнем битстрима и loop filter. Это делает VP9 основной областью, где работа с vpxenc особенно заметно отличается от простого задать битрейт.

При выборе VP9 следует заранее определить три вещи: допустимую глубину и subsampling, режим контроля скорости и требования к задержке. Именно от них зависят профиль, --bit-depth, число проходов, --lag-in-frames, AltRef, tiles и режим deadline. Если сначала собрать длинную строку из десятков ключей, а потом пытаться понять, почему она не работает в реальном времени или на конкретном декодере, диагностика становится намного сложнее.

Режимы качества и скорости: best, good, rt и deadline

vpxenc разделяет идею сколько времени можно тратить на кадр и конкретные speed features кодера. Общий параметр -d/--deadline принимает время в микросекундах, а удобные именованные варианты --best, --good и --rt переключают готовые классы deadline. Практически чаще работают с именованными режимами, потому что их смысл понятнее и они не привязывают скрипт к вручную выбранному микросекундному пределу.

РежимНазначениеЧто учитывать
--bestмаксимально тщательный режим из трёх общих пресетовможет быть очень медленным; выигрыш относительно хорошего медленного профиля не всегда оправдывает время
--goodобычное файловое кодирование с управляемым компромиссом скорость/эффективностьдальнейшая скорость задаётся --cpu-used и VP8/VP9-специфическими механизмами
--rtрежим для минимизации задержки и real-time сценариевvpxenc принудительно использует один проход; для realtime CBR ненулевой lag игнорируется

В текущем коде, если выбран --rt и одновременно запрошено больше одного прохода, vpxenc предупреждает о конфликте и переводит кодирование в one-pass. Это логично: второй проход требует сначала проанализировать весь материал, что несовместимо с поступающим в реальном времени источником. Аналогично realtime CBR использует нулевой lag-in-frames; явное ненулевое значение отбрасывается с предупреждением.

--cpu-used не является процентом процессора. Это переключатель внутренних скоростных стратегий. Для VP9 текущая справка допускает диапазон от отрицательных служебных значений до положительных, а для нормальной эксплуатации используют неотрицательные значения: чем выше число, тем больше упрощений ради скорости. Конкретная производительность зависит от разрешения, режима, числа потоков и материала, поэтому нельзя обещать фиксированное ускорение в разах.

Rate control: как vpxenc распределяет биты

Параметры входного видео и управления битрейтом в справке vpxenc
Параметры входного видео и управления битрейтом в справке vpxenc

Центральная группа настроек — --end-usage, --target-bitrate, --min-q, --max-q и параметры буфера. --end-usage выбирает режим vbr, cbr, cq или q. Это не просто косметическая метка: режим определяет, что для кодера важнее — средняя скорость потока, соблюдение буферных ограничений либо качество, выраженное через уровень квантования.

РежимЛогикаТипичный сценарий
VBRбитрейт распределяется между простыми и сложными сценами с ориентацией на средний targetфайловое кодирование, где допустимы колебания мгновенной скорости
CBRкодер старается удерживать поток в рамках модели клиентского буфераканалы с ограниченной пропускной способностью и real-time передача
CQцелевой уровень качества сочетается с верхним ограничением по битрейтунабор роликов разной сложности с желаемым качеством и потолком скорости
Qрежим постоянного/фиксированного квантования без обычной битрейтной целиспециальные тесты и кодирование, где важнее заданная шкала quantizer

--target-bitrate измеряется в килобитах в секунду. Это важная деталь при переносе команд из FFmpeg: параметр -b:v у FFmpeg обычно записывается в битах/с с суффиксами k/M, тогда как vpxenc ожидает числовую величину в kbps. Строка --target-bitrate=2500 означает цель около 2500 кбит/с, а не 2500 бит/с.

Целевой битрейт не является гарантией, что каждый фрагмент или весь файл получится строго заданного размера. На отклонение влияют режим, сложность материала, ограничения min-q/max-q, буферы, keyframe, двухпроходный анализ и другие настройки. Особенно легко разрушить rate control, если поставить слишком жёсткие пределы квантизатора: кодер не сможет ухудшить качество достаточно для соблюдения малого битрейта либо, наоборот, не сможет поднять качество на простых сценах.

min-q и max-q

--min-q задаёт лучший допустимый край шкалы, а --max-q — худший. Чем меньше значение управляющего quantizer, тем выше качество и больше расход битов. Эти параметры — именно границы, а не целевое качество сами по себе. Если задать слишком узкий диапазон, rate control лишается свободы и может систематически не попадать в bitrate target.

Для диагностического теста иногда полезно временно расширить диапазон q и проверить, исчезла ли проблема с сильным overshoot или undershoot. Если исчезла, причина была не в контейнере и не в расчёте FPS, а в конфликте битрейтной цели с ограничением качества. После этого пределы можно возвращать постепенно, ориентируясь на реальную задачу.

undershoot и overshoot

--undershoot-pct и --overshoot-pct регулируют допустимое отклонение rate control от цели. Их особенно легко интерпретировать неправильно: это не команды сделай файл на N процентов меньше/больше, а ограничения поведения регулятора. В CBR слишком жёсткие значения могут заставлять кодер чаще ухудшать качество или применять drop/resize, если они разрешены. В VBR они обычно не должны заменять нормальную настройку target-bitrate и диапазона q.

Модель буфера CBR

CBR в vpxenc опирается на виртуальный клиентский буфер. Для него есть три параметра:

  • --buf-sz — общий размер буфера в миллисекундах данных;
  • --buf-initial-sz — стартовый уровень в миллисекундах;
  • --buf-optimal-sz — желаемый рабочий уровень.

Единица миллисекунды означает, что фактическое число битов зависит от target-bitrate. Поэтому переносить те же числа на поток с принципиально иным битрейтом можно, но смысл будет столько же времени запаса, а не тот же объём памяти. При настройке live-трансляции это удобнее: требования к задержке обычно тоже мыслятся во времени.

Если буфер должен соблюдаться любой ценой, vpxenc умеет жертвовать кадрами или пространственным разрешением. За пропуск кадров отвечает --drop-frame: это порог заполнения буфера, ниже которого допускается temporal resampling. За динамическое изменение размеров отвечают --resize-allowed, --resize-width, --resize-height, --resize-up и --resize-down. Такие механизмы применяют осознанно, потому что они меняют временную или пространственную структуру результата, а не просто сильнее сжимают тот же сигнал.

Один и два прохода

Количество проходов задаётся -p/--passes=1|2. В one-pass кодер принимает решения по мере поступления кадров и не имеет полной статистики о будущем материале. В two-pass первый проход собирает данные о сложности и распределении движения, а второй использует их для более осмысленного расходования битов. Для файлового VBR/CQ это обычно даёт более точное управление распределением качества и скорости, особенно на роликах с сильно различающимися сценами.

У VP9 в обычном, не realtime режиме vpxenc при отсутствии явного --passes может выбрать два прохода по умолчанию. В автоматизации на это полагаться не стоит: укажите число прямо. Тогда команда будет одинаково читаема для человека и для системы CI, а изменение поведения конкретной сборки не станет скрытой причиной различий.

Автоматический двухпроходный запуск

Самая короткая форма — передать --passes=2 и позволить vpxenc выполнить оба этапа в рамках запуска, если остальная конфигурация и источник позволяют. Для явного управления этапами существуют --pass=1, --pass=2 и --fpf=имя_файла. FPF — файл статистики первого прохода. Такой вариант удобен в распределённых скриптах: анализ можно выполнить отдельно, сохранить статистику, затем запустить второй этап с тем же источником.

Пример структуры двух команд:

vpxenc input.y4m --codec=vp9 --passes=2 --pass=1 \
  --fpf=clip.stats --good --target-bitrate=1800 -o first-pass.webm

vpxenc input.y4m --codec=vp9 --passes=2 --pass=2 \
  --fpf=clip.stats --good --target-bitrate=1800 -o final.webm

Конкретное использование файла первого прохода зависит от версии и сценария; главное правило — второй проход должен получить статистику, собранную для той же последовательности кадров и согласованной конфигурации. Если между проходами изменить монтаж, FPS, пропустить кадры или подать другой цветовой layout, статистика перестанет описывать материал, для которого она была рассчитана.

bias-pct, minsection-pct и maxsection-pct

Для two-pass доступны отдельные параметры распределения битов. --bias-pct меняет склонность алгоритма отдавать дополнительные биты более сложным фрагментам. --minsection-pct и --maxsection-pct ограничивают минимальный и максимальный битрейт участка относительно средней цели. Они полезны, когда обычный VBR создаёт слишком широкий разброс скорости или когда декодер/канал имеет верхний предел на коротких интервалах.

Слишком маленький maxsection-pct способен ухудшить тяжёлые сцены, потому что кодер не сможет выделить им достаточно битов. Слишком большой делает VBR свободнее, но увеличивает пики. Поэтому эти ключи лучше рассматривать как ограничения инфраструктуры, а не как магический способ повысить качество.

corpus-complexity

В современных сборках присутствует --corpus-complexity — параметр для corpus VBR. Его смысл связан с ситуацией, когда сложность оценивается не только в пределах одного клипа, а относительно заранее известной характеристики набора. Для обычного домашнего кодирования он не требуется. Если у вас нет собственной системы вычисления этой метрики и заранее определённого corpus workflow, оставление значения по умолчанию безопаснее ручного подбора.

Ключевые кадры и структура GOP

Для размещения ключевых кадров используются --kf-min-dist, --kf-max-dist и --disable-kf. Максимальная дистанция задаётся в кадрах, поэтому фактический интервал во времени зависит от FPS. Если ролик идёт с 25 кадрами/с, значение 250 соответствует верхней границе примерно десять секунд; при 50 кадрах/с те же 250 кадров — около пяти секунд. При расчёте GOP для сегментации и seek-операций поэтому лучше сначала определиться с временным интервалом, а затем переводить его в кадры.

Меньший GOP облегчает произвольный доступ и ограничивает длину зависимости между кадрами, но ключевые кадры обычно стоят дороже по битам. Слишком большой интервал может повысить эффективность на некоторых материалах, однако ухудшить перемотку и восстановление после потерь. Для WebM, предназначенного под конкретную систему доставки, разумно согласовать kf-max-dist с границами сегментов, а не выбирать число только по качеству.

--disable-kf отключает обычное размещение ключевых кадров и нужен скорее для контролируемых тестов, чем для типового пользовательского файла. Наличие первого intra-кадра и требования контейнера/битстрима всё равно накладывают свои ограничения. Если цель — просто сделать длинный GOP, безопаснее задать большой kf-max-dist, чем полностью отключать механизм без понимания последствий.

AltRef, Golden Frame и lookahead

VP8 и VP9 активно используют reference frames. В vpxenc доступен --auto-alt-ref, а глубина взгляда вперёд контролируется --lag-in-frames. Alternate Reference Frame может быть построен из будущих кадров и не обязательно показывается как обычный кадр; его задача — улучшать предсказание последующих кадров. Чтобы сформировать такой reference, кодеру нужно иметь несколько будущих кадров, отсюда прямая связь с lookahead и задержкой.

Для файлового кодирования большой lag обычно допустим, поскольку латентность не критична. Для интерактивного потока она критична: realtime CBR в текущем vpxenc принудительно обнуляет lag. Это хороший пример того, почему нельзя одновременно требовать максимальный lookahead и минимальную задержку — это физически противоречивые цели.

Параметры --arnr-maxframes, --arnr-strength и --arnr-type относятся к фильтрации вокруг AltRef. arnr-maxframes задаёт предел числа кадров, участвующих в фильтрации, arnr-strength — её силу, а type выбирает вариант фильтра. Увеличение этих значений не является линейным улучшением качества: сильная временная фильтрация может полезно подавить случайный шум, но способна стереть мелкую динамическую фактуру.

Для VP9 есть отдельные границы --min-gf-interval и --max-gf-interval для Golden/AltRef-структуры. Ноль означает внутреннее решение кодера. Если задача не требует воспроизводимой структуры reference frames, оставление автоматического поведения обычно проще. Ручное ограничение оправдано в исследовании, при конкретных требованиях к декодированию или когда нужно синхронизировать поведение с внешним сегментатором.

Golden Frame в CBR

--gf-cbr-boost задаёт дополнительный бюджет Golden Frame в CBR как процент от среднего кадра. Нулевое значение отключает специальный boost. Например, 100 означает возможность выделить Golden Frame примерно вдвое больше среднего бюджета. Такой всплеск должен укладываться в выбранную модель буфера, поэтому параметр нельзя рассматривать отдельно от buf-sz и target bitrate.

Дополнительно для VP9 существует --max-intra-rate и --max-inter-rate, ограничивающие относительный размер I- и P-кадров. Они полезны, если клиент не переносит крупные кратковременные пики, но слишком жёсткое ограничение ключевого кадра может заметно ухудшить качество на смене сцены и затем повлиять на цепочку зависимых кадров.

Многопоточность и масштабирование по CPU

-t/--threads задаёт максимальное число потоков кодера. Это верхняя граница, а не обещание равномерно загрузить все логические ядра. Эффективность зависит от разрешения, кодека, режима, tiles, row-mt, структуры кадра и конкретной платформы. Для маленького кадра десятки потоков часто просто нечем занять; для UHD у VP9 возможностей параллелизма больше.

Важно различать несколько независимых механизмов:

  • --threads — общий лимит рабочих потоков;
  • --tile-columns и --tile-rows — пространственное деление VP9-кадра на tiles;
  • --row-mt — row-based multithreading VP9;
  • --frame-parallel — свойства битстрима, облегчающие параллельное декодирование кадров;
  • для VP8 --token-parts — независимые coefficient partitions.

Эти ключи не взаимозаменяемы. Установка --threads=16 без достаточной внутренней разбивки может дать слабую загрузку CPU. И наоборот, чрезмерное число tiles способно уменьшить эффективность компрессии, потому что некоторые зависимости между частями изображения ограничиваются. Настройка производительности поэтому состоит не в максимизации каждого числа, а в поиске структуры, которая соответствует разрешению и числу ядер.

Tile columns и tile rows

В vpxenc значения --tile-columns и --tile-rows задаются как log2 числа тайлов. Это частый источник ошибок. --tile-columns=0 означает одну колонку, 1 — две, 2 — четыре, 3 — восемь. Это не прямое число колонок. Аналогично работает параметр рядов.

ЗначениеФактическое число tile columns
01
12
24
38

Текущая справка отдельно предупреждает для tile rows: при многопоточности rows рекомендуется оставлять 0. На практике основным способом пространственного распараллеливания VP9 часто становятся колонки и row-mt. Если цель — просто ускорить кодирование, начинать стоит с разумного --threads и --row-mt=1, а tiles добавлять после измерения загрузки и проверки результата.

row-mt и детерминизм

--row-mt=1 включает построчное недетерминированное многопоточное кодирование VP9. Недетерминированное здесь означает, что порядок выполнения параллельных работ может менять отдельные решения кодера и в итоге байтовый битстрим. Если задача — производственное кодирование, это обычно не проблема. Если строится тест, где файлы должны быть побитово идентичны между прогонами, следует учитывать влияние row-mt и многопоточности и при необходимости использовать -D/--debug, который переводит vpxenc в детерминированный режим.

Детерминированность полезна для regression tests, но это не режим лучшего качества. Его цель — повторяемость. При обычной эксплуатации важнее подобрать скорость и качество, а не добиваться идентичности битов между запусками на одном и том же материале.

VP9: профили, глубина цвета и subsampling

VP9 определяет четыре профиля, и в vpxenc они выбираются --profile=0..3. Связь профиля с битностью и цветовой дискретизацией строгая: профиль нельзя назначить произвольно только потому, что номер выше.

Профиль VP9ГлубинаChroma subsampling
08 бит4:2:0
18 бит4:2:2 или 4:4:4
210 или 12 бит4:2:0
310 или 12 бит4:2:2 или 4:4:4

Внутри libvpx проверяется соответствие формата кадра профилю. Если передать I422/I444 с профилем 0, кодер вернёт ошибку о неподдерживаемом формате. Аналогично high-bit-depth кадр должен использовать сборку, в которой включена поддержка высокой битности, и конфигурацию профиля 2 или 3. Поэтому при ошибке invalid image format сначала проверяйте не файл как таковой, а комбинацию --profile, subsampling и bit depth.

bit-depth и input-bit-depth

В сборке с CONFIG_VP9_HIGHBITDEPTH доступны -b/--bit-depth со значениями 8, 10 и 12, а также --input-bit-depth. Первый задаёт глубину кодека/выходного битстрима, второй сообщает фактическую глубину исходных выборок. Это важно, когда внутреннее представление использует 16-битные контейнеры для 10- или 12-битных значений.

Для 10-битного 4:2:0 VP9 типовая связка — профиль 2, bit-depth 10 и input-bit-depth 10. Для 10-битного 4:4:4 — профиль 3. Если high-bit-depth поддержку при компиляции отключили, соответствующих параметров может не быть в --help. Наличие ключа — надёжнее предположений о конкретном бинарнике.

vpxenc input-10bit.y4m --codec=vp9 --profile=2 \
  --bit-depth=10 --input-bit-depth=10 \
  --good --cpu-used=2 --webm -o output-10bit.webm

Для high-bit-depth есть --validate-hbd-input. По умолчанию проверка включена и следит, чтобы значения выборок не выходили за диапазон выбранной глубины. Отключать её имеет смысл только в контролируемом тесте, когда вы точно понимаете происхождение данных; иначе проверка помогает поймать неверно сформированный raw/Y4M раньше, чем повреждение проявится визуально.

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

--color-space позволяет сигнализировать одно из значений: unknown, bt601, bt709, smpte170, smpte240, bt2020, reserved или sRGB. Это описание цветовой матрицы/пространства в контексте VP9, а не фильтр преобразования. Если вход фактически BT.709, назначение bt2020 не конвертирует пиксели в BT.2020 — оно лишь меняет сигнализацию. Цветовое преобразование нужно выполнить до vpxenc.

sRGB имеет дополнительные ограничения: VP9 требует профиль 1 или 3 и 4:4:4. Поэтому команда с --color-space=sRGB и профилем 0 закономерно должна завершиться ошибкой. Такая строгая проверка полезна: она не позволяет создать заведомо противоречивую комбинацию заголовка и изображения.

target-level

--target-level задаёт VP9 level. Значение 255 отключает ограничение, 0 только ведёт статистику уровня, 1 включает адаптивную подстройку некоторых параметров с учётом размера кадра, а числовые коды 10, 11, 20 и далее соответствуют Level 1.0, 1.1, 2.0 и вплоть до 6.2. Level ограничивает такие характеристики, как скорость обработки luma samples, размер кадра, bitrate и CPB.

Если конечное устройство объявляет конкретный максимум VP9 Level, имеет смысл задавать его осознанно и затем проверять готовый поток. Не следует выбирать маленький level для совместимости, если разрешение/FPS сами по себе превосходят его ограничения: кодер не может отменить физические свойства исходной последовательности.

Настройка VP9 под тип содержимого

Специальные параметры кодирования VP9 в выводе vpxenc --help
Специальные параметры кодирования VP9 в выводе vpxenc --help

--tune-content имеет варианты default, screen и film. Это подсказка кодеру о характере материала. Screen ориентирован на захват интерфейсов, текст и резкие искусственные границы. Film предназначен для материала с плёночноподобной фактурой и может лучше сохранять зерно. Default оставляет обычную стратегию.

Этот параметр полезен только тогда, когда категория действительно соответствует исходнику. Игровой ролик с HUD и естественной 3D-графикой не всегда ведёт себя как классический screen capture; скан плёнки после сильного temporal denoise уже может не требовать film tuning. Правильный способ выбора — кодировать репрезентативный фрагмент и сравнивать артефакты на целевом битрейте, а не назначать режим по имени файла.

Adaptive Quantization

--aq-mode в VP9 переключает адаптивное квантование: 0 — off, 1 — variance, 2 — complexity, 3 — cyclic refresh, 4 — equator360. AQ перераспределяет качество по пространству/времени с учётом свойств содержимого. Это особенно заметно на потоках с ограниченным битрейтом, где равномерный quantizer не всегда даёт лучший воспринимаемый результат.

--alt-ref-aq включает отдельную адаптивную стратегию для alternate reference frames, оценивая их ожидаемую полезность для предсказания будущих кадров. Она может работать одновременно с обычным aq-mode. Включать оба параметра автоматически во все пресеты не обязательно: на конкретной задаче стоит проверять, не меняется ли распределение качества нежелательным образом.

TPL, фильтрация keyframe и frame boost

--enable-tpl управляет temporal dependency model, который помогает оценивать влияние решений текущего кадра на последующие. --enable-keyframe-filtering включает temporal filtering ключевых кадров. --frame-boost разрешает периодический quality boost через снижение frame-level Q. Все три механизма связаны с распределением качества во времени, но действуют на разных уровнях.

При построении собственного пресета разумно сначала получить рабочий результат с базовыми rate control и speed settings, затем менять по одному такому механизму. Иначе при одновременном переключении TPL, AQ, AltRef и frame boost трудно понять, какой параметр отвечает за изменение размера или характер артефактов.

Lossless и loop filter

--lossless=1 включает lossless mode VP9. Он нужен, когда требуется математически без потерь сохранить представление, которое поступило на вход кодера. Это не отменяет потерь, уже возникших раньше: если исходный RGB был преобразован в 4:2:0 до vpxenc, потеря цветового разрешения произошла до lossless-кодирования. Для точного архивирования важно рассматривать всю цепочку пиксельных преобразований.

--disable-loopfilter управляет VP9 loop filter: 0 оставляет фильтр на всех кадрах, 1 отключает его на нереференсных, 2 — на всех. Loop filter является частью кодека и влияет не только на внешний вид, но и на reference pictures. Полное отключение без конкретной причины обычно не является режимом большей резкости: оно может усилить блочные артефакты и изменить дальнейшее предсказание.

Специфические параметры VP8

Специальные параметры кодирования VP8 в выводе vpxenc --help
Специальные параметры кодирования VP8 в выводе vpxenc --help

У VP8 набор специализированных ключей короче, но логика похожа: скорость, reference frames, фильтрация и ограничения rate control настраиваются отдельно от глобальной конфигурации. Текущий vpxenc принимает для VP8 --cpu-used, --auto-alt-ref, --noise-sensitivity, --sharpness, --static-thresh, --token-parts, ARNR-параметры, --tune, --cq-level, --max-intra-rate, --gf-cbr-boost и --screen-content-mode.

--sharpness принимает значения 0–7 и ослабляет действие loop filter по мере роста числа. Он не добавляет детали, отсутствующие во входе; визуально более резкая картинка может одновременно содержать сильнее заметные блоки. --noise-sensitivity включает встроенную temporal noise treatment. Для сложного реставрационного шумоподавления лучше использовать специализированный фильтр до кодера, потому что задача этого ключа гораздо уже.

--static-thresh задаёт порог определения движения, ниже которого блок может считаться статичным. Ненулевое значение способно ускорить кодирование и уменьшить реакцию на слабый шум, но если реальное малое движение ошибочно признано статикой, часть кадра обновится хуже. Для источников с тонкими анимациями, интерфейсом или движущимся зерном этот параметр требует осторожности.

--screen-content-mode предназначен для экранного содержимого. Не следует считать его эквивалентом VP9 --tune-content=screen один к одному: это разные кодеры и разные control IDs, хотя пользовательская цель сходна. При переносе пресета между VP8 и VP9 используйте параметры, документированные именно для выбранного кодека.

tune=psnr и tune=ssim

Общий для VP8/VP9 ключ --tune=psnr|ssim меняет критерий, которому кодер старается отдавать предпочтение при оптимизации. PSNR и SSIM — объективные метрики с разной чувствительностью к видам искажений. Оптимизация под одну не гарантирует улучшения другой и тем более не гарантирует субъективного предпочтения зрителя.

Если задача — лабораторное сравнение по конкретной метрике, tuning помогает согласовать кодер с методикой. Для обычного файла лучше не выбирать SSIM только потому, что название звучит современнее: сначала определите, чем измеряется успешность результата. В статье или отчёте о тесте полезно фиксировать tuning вместе с битрейтом, passes, cpu-used и profile, иначе сравнение трудно воспроизвести.

Диагностика кодирования

vpxenc способен показать достаточно информации, чтобы локализовать большинство ошибок конфигурации до анализа готового файла. Начинать стоит с --verbose. В этом режиме видны версия интерфейса кодера, распознанный тип входа, назначение выхода и значения полей конфигурации. Если неожиданно получился другой размер кадра, не тот target bitrate или нулевой lag, это обычно заметно сразу.

Строка прогресса полезна не только для оценки времени. Сравнивая number of frames in/out, можно заметить пропуски при drop-frame; по размеру bitstream — грубые отклонения rate control; по скорости — влияние cpu-used, threads, tiles и row-mt. При этом одна мгновенная скорость на коротком фрагменте не является надёжным benchmark: прогрев, сложность сцен и первый/второй проход ведут себя по-разному.

PSNR

--psnr просит кодер выводить PSNR. Метрика вычисляется между исходными и реконструированными кадрами кодека, поэтому это удобный быстрый индикатор влияния параметров. Но PSNR нельзя использовать как единственное доказательство визуального качества: два файла с близким PSNR могут отличаться характером артефактов, а психовизуальная оптимизация иногда специально жертвует этой метрикой ради восприятия.

Для корректного сравнения PSNR вход должен быть одинаковым, а измерение — выполнено в одной и той же цветовой структуре. Если один вариант предварительно переведён из 4:4:4 в 4:2:0, а другой нет, часть различия относится к подготовке источника, не к самому rate control.

Гистограмма quantizer

--q-hist=N выводит распределение кадров по N корзинам quantizer. Это помогает понять, упирается ли кодер в min-q или max-q. Если большая доля кадров сконцентрирована у худшего допустимого значения, target bitrate, скорее всего, слишком низок для текущих ограничений. Если всё постоянно лежит у лучшей границы и битрейт сильно недобирается, возможно, задан слишком строгий min-q либо сам материал очень простой.

Гистограмма bitrate

--rate-hist=N показывает распределение скорости по корзинам. Для CBR это полезнее простого среднего размера файла: сеть или декодер обычно страдают от коротких пиков, а не от среднего значения за весь ролик. Если ограничения инфраструктуры жёсткие, сравнивайте гистограмму с выбранными buffer settings и max frame rate limits.

test-decode

--test-decode=warn или fatal включает контроль encode/decode mismatch. В режиме warn несоответствие фиксируется как предупреждение, в fatal процесс останавливается. Это инструмент разработчика и QA, особенно полезный при нестандартной сборке libvpx или проверке новых параметров. Для обычной проверки воспроизводимости файла всё равно нужен независимый декодер и, при необходимости, валидация контейнера.

Практические команды vpxenc

Ниже команды построены как шаблоны. Числа битрейта, GOP и скорости не являются универсальными рекомендациями: их нужно подставлять под разрешение, частоту кадров, содержание и требования к размеру. Главное — взаимосвязь ключей.

VP9 WebM из Y4M

vpxenc input.y4m -o output.webm \
  --codec=vp9 --webm --good --cpu-used=2 \
  --end-usage=vbr --target-bitrate=2500

Это базовое файловое кодирование. Y4M сообщает геометрию и FPS, поэтому их обычно не приходится дублировать. --good включает файловый deadline, cpu-used выбирает скорость, VBR получает target 2500 kbps. Если требуется строго один проход, добавьте --passes=1; если два — --passes=2.

VP9 из сырого I420

vpxenc input.i420 -o output.webm \
  --codec=vp9 --i420 --width=1920 --height=1080 \
  --fps=30000/1001 --good --cpu-used=2 \
  --target-bitrate=3500

У raw-файла обязательно заданы width, height и FPS. Если перепутать 1920×1080 с 1920×1088, каждая граница кадра сместится, и результат будет повреждён. То же касается ошибочного выбора YV12 вместо I420.

Двухпроходный VP9 VBR

vpxenc input.y4m -o output.webm \
  --codec=vp9 --passes=2 --good --cpu-used=1 \
  --end-usage=vbr --target-bitrate=1800 \
  --kf-max-dist=240

Два прохода дают кодеру статистику всего клипа. kf-max-dist ограничивает максимальную длину GOP в кадрах. Для сегментированного видео число нужно привязать к FPS и длительности сегмента, а не копировать из чужого пресета.

Constrained Quality

vpxenc input.y4m -o output.webm \
  --codec=vp9 --passes=2 --good --cpu-used=1 \
  --end-usage=cq --cq-level=32 --target-bitrate=4000

CQ задаёт желаемый quality level, но target bitrate становится ограничением сверху, а не обычной VBR-целью. Лёгкие сцены могут использовать заметно меньше 4000 kbps, если выбранное качество достигается меньшим потоком; тяжёлые ограничиваются указанным максимумом и границами quantizer.

Realtime CBR

vpxenc input.y4m -o realtime.webm \
  --codec=vp9 --rt --passes=1 --cpu-used=6 \
  --end-usage=cbr --target-bitrate=1500 \
  --buf-sz=1000 --buf-initial-sz=500 --buf-optimal-sz=600

В real-time режиме критичны задержка и буфер. Ненулевой lag для realtime CBR будет проигнорирован. Реальные значения cpu-used и буфера выбирают по мощности машины и допустимой латентности. Если кодер не успевает, повышают speed setting, уменьшают нагрузку, разрешают drop/resize или снижают сложность входа — просто увеличение threads не всегда решает проблему.

VP9 lossless

vpxenc input.y4m -o lossless.webm \
  --codec=vp9 --lossless=1 --webm

Lossless сохраняет входное YUV-представление без потерь кодека. Если до этого выполнялась конверсия RGB→YUV420, субдискретизация уже необратима. Для проверки пиксель в пиксель декодируйте результат в тот же YUV layout и сравнивайте именно с тем потоком, который поступал в vpxenc.

10-битный VP9 4:2:0

vpxenc input10.y4m -o output10.webm \
  --codec=vp9 --profile=2 --bit-depth=10 --input-bit-depth=10 \
  --good --cpu-used=2 --color-space=bt2020

Такой шаблон подходит только если сборка поддерживает VP9 high bit depth и вход действительно 10-битный 4:2:0. color-space=bt2020 корректен лишь когда пиксели подготовлены для BT.2020; ключ сам не выполняет преобразование из BT.709.

8-битный VP9 4:4:4

vpxenc input444.y4m -o output444.webm \
  --codec=vp9 --profile=1 --i444 \
  --good --cpu-used=2

Профиль 1 нужен для 8-битного 4:2:2/4:4:4. Совместимость с аппаратными декодерами для таких профилей может быть уже, чем у 8-битного 4:2:0 Profile 0, поэтому профиль выбирают по реальной необходимости, а не ради формально большей цветовой детализации.

Экранный контент VP9

vpxenc capture.y4m -o screen.webm \
  --codec=vp9 --tune-content=screen \
  --good --cpu-used=3 --end-usage=cq --cq-level=28 \
  --row-mt=1

Screen tuning сообщает кодеру, что в кадре много синтетических границ и элементов интерфейса. Уровень CQ в примере демонстрационный. Для текста малого кегля и тонких линий проверяйте не только среднюю метрику, но и читаемость контрастных контуров после декодирования.

Зернистый материал VP9

vpxenc film.y4m -o film.webm \
  --codec=vp9 --tune-content=film \
  --good --cpu-used=1 --passes=2 \
  --end-usage=vbr --target-bitrate=5000

Film tuning ориентирован на сохранение зерноподобной структуры. Он не синтезирует новое зерно и не заменяет denoise/grain management. Если источник сильно зашумлён цифровым шумом, а не плёночным зерном, предварительная обработка может дать более предсказуемый результат.

IVF для анализа

vpxenc input.y4m -o stream.ivf \
  --codec=vp9 --ivf --good --cpu-used=2

IVF упрощает использование битстрима в тестовых инструментах. Если потом нужен обычный пользовательский файл с аудио, его следует remux в подходящий контейнер внешней программой.

Кодирование фрагмента по кадрам

vpxenc input.y4m -o sample.webm \
  --codec=vp9 --skip=300 --limit=600 \
  --good --cpu-used=2

--skip пропускает первые N входных кадров, --limit останавливается после N обрабатываемых кадров. Это удобно для быстрых сравнений на одинаковом отрезке. Если в исходнике 30 fps, skip 300 означает примерно 10 секунд, но при дробной частоте лучше считать точно.

Тихий пакетный режим

vpxenc input.y4m -o output.webm \
  --codec=vp9 --quiet --good --cpu-used=2

--quiet убирает обычный progress. Ошибки при этом не следует полностью перенаправлять в /dev/null: в автоматизации stderr нужно сохранять, иначе при неуспешном запуске останется только отсутствующий или неполный файл без объяснения причины.

Как подготавливать источник через FFmpeg

Связка FFmpeg + vpxenc полезна, когда исходный ролик находится в обычном медиаконтейнере. FFmpeg выполняет демультиплексирование, декодирование и фильтры, а vpxenc — VP8/VP9 compression. Пример с Y4M pipe:

ffmpeg -i input.mkv -map 0:v:0 -vf scale=1920:-2 \
  -pix_fmt yuv420p -f yuv4mpegpipe - | \
  vpxenc - --codec=vp9 --profile=0 --good --cpu-used=2 \
  --passes=1 --webm -o video.webm

Здесь масштабирование и преобразование в yuv420p принадлежат FFmpeg. Профиль 0 в vpxenc соответствует 8-битному 4:2:0. Если убрать -pix_fmt yuv420p и фильтр выдаст другой layout, профиль нужно согласовать с ним.

После кодирования аудио можно добавить отдельным шагом, не перекодируя VP9:

ffmpeg -i video.webm -i input.mkv \
  -map 0:v:0 -map 1:a:0 -c:v copy -c:a libopus final.webm

Эта команда приведена для объяснения рабочего процесса; она относится уже к FFmpeg, а не к функциям vpxenc. Такой раздел важен, потому что иначе легко ошибочно ожидать от vpxenc input.mp4 того, чего его интерфейс не обещает.

Ошибки vpxenc и способы их устранить

Большинство проблем с vpxenc относится не к повреждённой программе, а к несогласованной конфигурации: сырой формат описан не тем ключом, профиль не соответствует chroma subsampling, requested feature отсутствует в сборке, two-pass статистика не совпадает с материалом либо одновременно заданы режимы с противоположными требованиями к задержке. Удобный порядок диагностики — сначала сократить команду до минимально рабочей, затем добавлять параметры группами.

Unrecognized argument to --codec

Если имя кодека не распознано, проверьте vpxenc --help и блок Included encoders. Сборка может содержать только VP8, только VP9 или оба. Правильные имена для штатных интерфейсов — vp8 и vp9. Не передавайте сюда названия FFmpeg encoder wrappers вроде libvpx-vp9: это имя другого интерфейса.

В скрипте не стоит угадывать наличие VP9 по имени исполняемого файла. Один и тот же vpxenc строится с разными configure options. Если операция зависит от конкретного кодека, проверяйте его наличие один раз при развёртывании окружения.

Invalid number of passes или Invalid pass selected

--passes принимает только 1 или 2, --pass — тоже 1 или 2. Если указан --pass=2, а число passes меньше, текущий код vpxenc делает предположение, что пользователь имел в виду два прохода, и повышает passes с предупреждением. Полагаться на такое исправление в продакшен-скрипте не стоит: задавайте обе величины согласованно.

Нет размера кадра

vpxenc специально не использует библиотечный размер по умолчанию: width и height должны быть прочитаны из входного заголовка либо заданы командной строкой. Если Y4M повреждён или raw-вход запущен без -w/-h, кодер не имеет корректной геометрии. Для raw-последовательности дополнительно проверьте, что размер файла кратен размеру одного кадра с учётом subsampling и bit depth.

Для 8-битного I420 размер одного кадра равен width × height × 1,5 байта. Для I444 — width × height × 3. Для high-bit-depth внутреннее хранение исходника может использовать 16-битные слова, поэтому расчёт должен соответствовать фактическому формату файла, а не только 10 бит как абстрактному числу.

Цвета выглядят неправильно

Первое подозрение — выбран не тот raw layout. I420 и YV12 имеют одинаковую 4:2:0 структуру, но U/V расположены в разном порядке. Если их перепутать, геометрия кадра останется нормальной, но оттенки будут резко неверными. NV12, напротив, хранит chroma interleaved, поэтому чтение его как I420 нарушит уже сам layout плоскостей.

Вторая причина — неверная color-space сигнализация. --color-space не преобразует значения. Если пиксели BT.601 пометить как BT.709, декодер применит другую матрицу, и цвет/яркость изменятся. Правильный порядок: сначала преобразовать пиксели внешним фильтром, затем сигнализировать то, что получилось.

Invalid image format для VP9

Проверьте профиль. Profile 0 — только 8-bit 4:2:0, Profile 1 — 8-bit 4:2:2/4:4:4, Profile 2 — 10/12-bit 4:2:0, Profile 3 — 10/12-bit 4:2:2/4:4:4. В libvpx эта совместимость валидируется. Нельзя заставить profile 0 принять I444 просто указанием --i444.

Отдельно проверьте high-bit-depth support. Если в --help отсутствуют --bit-depth и --input-bit-depth, бинарник, вероятно, не собран с нужной опцией. В таком случае проблема не решается другим значением профиля — нужен подходящий билд.

Ошибка при sRGB

Для VP9 sRGB требует profile 1 или 3 и 4:4:4. Если source 4:2:0, использование --color-space=sRGB противоречит правилам битстрима. Сначала определите, действительно ли нужен sRGB signalling. Для обычного YUV-видео чаще уместны bt709/bt2020 или другое реальное пространство источника.

--webm specified but webm is disabled

Эта ошибка буквально означает, что конкретный vpxenc собран без WebM I/O. Решения два: использовать --ivf и затем мультиплексировать поток внешним инструментом либо установить/собрать вариант libvpx с WebM I/O. Переименование .ivf в .webm не создаст контейнер WebM.

output-partitions не работает

--output-partitions требует IVF. Если нужен этот режим, добавьте --ivf и используйте соответствующий файл. Для обычного WebM такой ключ не нужен. Это один из случаев, когда сообщение справки точнее любой попытки подобрать расширение файла.

Битрейт сильно выше target

Проверьте по порядку: режим end-usage, пределы min-q/max-q, наличие lossless, число проходов, max intra/inter rate и буфер. Если max-q слишком хороший, кодер физически не может сильнее квантизовать сложную сцену. Lossless вообще несовместим с ожиданием фиксированного низкого битрейта. В CQ target bitrate является потолком/ограничением режима, а не тем же смыслом, что в обычном VBR.

Для короткого файла крупный keyframe также способен заметно изменить среднее. Смотрите не только final size, но и verbose/rate histogram. Если overshoot связан с несколькими крупными кадрами, помогут ограничения frame rate, GOP или buffer; если повышен весь поток, корректируйте основную rate-control цель.

Битрейт заметно ниже target

В VBR простая последовательность может недобрать цель, особенно если ограничения качества не позволяют тратить биты бессмысленно. В CQ undershoot вообще естественен: как только выбранное качество достигнуто, нет необходимости расходовать весь потолок. Если размер файла должен быть ближе к заданному, используйте режим, соответствующий такой цели, и не ставьте слишком строгий min-q.

Второй проход не принимает статистику

Убедитесь, что --fpf указывает на существующий файл первого прохода, а исходная последовательность не изменилась. Нельзя выполнять pass 1 на полном ролике, затем pass 2 на отрезке со --skip или другим FPS. Также следите за параллельными задачами: если несколько encode jobs используют одно и то же имя FPF в общей папке, они могут перезаписать статистику друг друга.

Кодирование в realtime не успевает

Сначала измерьте скорость именно на тяжёлой сцене, а не на заставке. Затем повышайте --cpu-used, включайте подходящий row-mt/tiles для VP9, увеличивайте threads до разумного уровня, уменьшайте разрешение или сложность фильтров до vpxenc. Если инфраструктура допускает, можно включить drop-frame или spatial resize. Two-pass здесь не поможет: realtime автоматически сводится к одному проходу.

Также исключите pipe как узкое место. Если FFmpeg декодирует и масштабирует медленнее необходимого FPS, vpxenc будет простаивать независимо от числа threads. В конвейере нужно измерять каждый этап отдельно.

CPU загружен не полностью

Неполная загрузка не всегда означает ошибку. На небольшом разрешении потоков может быть больше, чем параллельной работы. Для VP9 включите --row-mt=1, попробуйте tile columns, проверьте число threads. Но если при этом скорость уже превышает требование real-time, добить 100% CPU не является самоцелью. Дополнительный параллелизм может ухудшить compression efficiency.

Результат между запусками отличается побитово

Многопоточные режимы, особенно row-mt, могут быть недетерминированными. Если требуется побитовая воспроизводимость теста, используйте -D/--debug и минимизируйте источники недетерминизма. При этом визуально и статистически эквивалентные битстримы не обязаны совпадать byte-for-byte в обычном производственном кодировании.

Файл без звука

Это ожидаемое поведение. vpxenc кодирует видео. Он не читает аудиодорожку из исходного контейнера и не добавляет её к WebM. Подготовьте звук отдельно и выполните mux после кодирования. Если нужен один инструмент, который сам откроет MP4, перекодирует видео и аудио и соберёт контейнер, используйте универсальный транскодер с libvpx.

vpxenc не открывает MP4/MKV/MOV

Обычные медиаконтейнеры нужно предварительно декодировать в Y4M/raw. Самый удобный вариант — pipe из FFmpeg, GStreamer или собственной программы. Это архитектурное ограничение, а не отсутствие кодека для MP4: контейнер и видеокодек — разные уровни.

Повреждённый результат после pipe

Убедитесь, что producer и vpxenc согласованы по формату. Y4M предпочтительнее raw pipe, потому что несёт заголовок. Для raw producer должен выдавать строго нужный layout, а vpxenc — знать width/height/FPS. Также не направляйте диагностический stdout сторонней программы в тот же pipe, что и видеоданные: поток должен содержать только Y4M/YUV.

Слишком большой временный YUV

Несжатое видео занимает много места. Необязательно сохранять его на диск: используйте Y4M pipe. Если нужен two-pass и декодирование дорогое, компромисс — один раз сохранить промежуточный Y4M/YUV на быстрый диск, выполнить оба прохода и удалить файл после успешной проверки. Выбор зависит от того, что дороже в вашей системе: повторное декодирование или дисковый I/O/ёмкость.

Предупреждения мешают пакетному заданию

--disable-warnings отключает предупреждения о потенциально неправильной конфигурации, а -y/--disable-warning-prompt оставляет предупреждения, но не задаёт интерактивный вопрос. Для автоматизации безопаснее второй вариант: журнал сохранит сигнал о сомнительных настройках, а job не зависнет в ожидании ввода.

Полное отключение warning лучше применять только после того, как команда стабилизирована и предупреждение сознательно принято. Иначе можно скрыть полезный признак конфликта параметров.

Систематический выбор параметров

Вместо копирования длинной чужой команды полезно пройти конфигурацию слоями. Такой подход уменьшает число взаимных конфликтов и делает итоговую строку объяснимой.

  1. Определите вход. Y4M или raw; для raw — layout, width, height, FPS, bit depth.
  2. Выберите codec/profile. VP8 или VP9; для VP9 профиль должен соответствовать depth/subsampling.
  3. Выберите контейнер. WebM для прямого файла, IVF для тестовой/промежуточной работы.
  4. Выберите цель rate control. VBR, CBR, CQ или Q.
  5. Определите passes и latency. Файловый two-pass или one-pass/realtime.
  6. Настройте speed. deadline, cpu-used, threads, row-mt/tiles.
  7. Задайте GOP/reference. kf-max-dist, lag, AltRef, при необходимости GF limits.
  8. Добавьте content-specific опции. tune-content, AQ, film/screen, lossless.
  9. Включите диагностику. verbose, PSNR, q/rate hist на тестовом фрагменте.
  10. Только затем фиксируйте пресет. Сохраните полную команду вместе с информацией о сборке.

Такой порядок удобен ещё и тем, что любой сбой локализуется по слою. Если базовое Y4M→VP9 работает, а после включения profile 3 появляется ошибка, проблема относится к цветовому формату/bit depth. Если всё ломается только после CBR-буфера, исследовать контейнер уже не нужно.

Справочник основных параметров

ПараметрНазначениеЗамечание
-o, --outputвыходной файлобязателен для каждого выходного stream
--codecвыбор VP8/VP9используйте явное значение в скриптах
-p, --passes1 или 2 проходаrealtime сводится к одному проходу
--passконкретный этапполезен при раздельном two-pass
--fpfфайл статистикидолжен соответствовать тому же источнику
--limitограничить число кадровудобно для тестового фрагмента
--skipпропустить первые кадрызначение в кадрах, не секундах
--best/--good/--rtкласс deadlineзадаёт компромисс качество/скорость/latency
--quietне печатать progressошибки всё равно нужно логировать
--verboseпоказать параметрыпервый инструмент диагностики
--psnrPSNR-статистикаметрика, а не субъективная оценка
--q-histгистограмма quantizerпомогает увидеть упор в q limits
--rate-histгистограмма bitrateполезна для контроля пиков
--test-decodeпроверка mismatchрежимы off/warn/fatal
--webmписать WebMтребует WebM I/O в сборке
--ivfписать IVFудобен для анализа и промежуточных потоков

Глобальные параметры входа и кодера

ПараметрЧто задаётПрактический смысл
--nv12вход NV12Y-плоскость плюс interleaved UV
--yv12вход YV124:2:0 с порядком Y-V-U
--i420вход I4204:2:0 с порядком Y-U-V; raw-вариант по умолчанию
--i422вход I422для VP9 требует подходящего профиля
--i444вход I444для VP9 Profile 1/3 в зависимости от depth
--i440вход I440редкий формат; особенно важна проверка профиля
-t, --threadsмаксимум потоковне гарантирует линейное масштабирование
--profilebitstream profileдля VP9 связан с bit depth и subsampling
-w, --widthширинаобязательна для raw, если не читается из формата
-h, --heightвысотаобязательна для raw
--fpsчастота кадровдробь rate/scale
--timebaseточность timestampотдельна от FPS; стандартно 1/1000
--stereo-mode3D layoutmono, left-right, bottom-top, top-bottom, right-left при WebM I/O
--error-resilienterror resiliency flagsдля потоков, где потери важнее небольшой эффективности
--lag-in-frameslookaheadувеличивает доступ к будущим кадрам и задержку

Параметры rate control

ПараметрЧто контролируетТипичная ошибка
--end-usagevbr/cbr/cq/qожидать одинакового смысла target bitrate во всех режимах
--target-bitrateцель в kbpsпередать число как будто это бит/с
--min-qлучший допустимый quantizerслишком высокий нижний предел лишает простые сцены качества
--max-qхудший допустимый quantizerслишком низкий максимум мешает попасть в малый bitrate
--undershoot-pctдопуск undershootвоспринимать как прямой процент размера файла
--overshoot-pctдопуск overshootставить крайне жёстко без настройки буфера
--buf-szёмкость rate buffer, мспутать миллисекунды с байтами
--buf-initial-szначальное заполнение, мсвыбирать больше общей ёмкости
--buf-optimal-szцелевое заполнение, мснастраивать отдельно от target bitrate
--drop-frameпорог temporal resamplingне учитывать потерю кадров
--resize-allowedразрешение spatial resamplingвключить и неожиданно получить изменение размера
--resize-width/heightцелевой размер при resizeне согласовать с downstream
--resize-up/downпороги масштабированияслишком частое переключение при нестабильном буфере

Параметры VP9

ПараметрФункцияКлючевая деталь
--cpu-usedскоростная стратегиябольшее положительное значение обычно быстрее
--auto-alt-refавтоматические AltRef2+ включает multi-layer AltRef, допустимы значения до 6
--tile-columnsчисло колонок tilesзначение задаётся как log2
--tile-rowsчисло рядов tilesтоже log2; при threads > 1 справка советует 0
--row-mtrow-based MTускоряет параллелизм, может быть недетерминированным
--enable-tpltemporal dependency modelвлияет на решения rate/distortion во времени
--enable-keyframe-filteringtemporal filtering keyframe0/1
--losslesslossless VP9не возвращает потери, внесённые до кодера
--frame-parallelframe parallel decodabilityсвойство структуры декодирования
--aq-modeadaptive quantization0 off, 1 variance, 2 complexity, 3 cyclic refresh, 4 equator360
--alt-ref-aqAQ для AltRefможет работать вместе с обычным AQ
--frame-boostperiodic Q boost0/1
--max-intra-rateпредел I-frameпроцент от средней целевой скорости
--max-inter-rateпредел P-frameпроцент от средней цели
--gf-cbr-boostбюджет Golden Frameактуален для CBR
--tune-contentdefault/screen/filmхарактер материала, не фильтр
--color-spaceсигнализация пространстване преобразует пиксели
--min-gf-intervalминимальный GF/ARF interval0 оставляет встроенное поведение
--max-gf-intervalмаксимальный GF/ARF interval0 оставляет встроенное поведение
--target-levelVP9 level255 off, 0 stats, коды 10..62 — levels
--disable-loopfilterрежим loop filter0 все кадры, 1 off на non-reference, 2 off везде
--validate-hbd-inputпроверка high-bit-depth samplesпо умолчанию включена
--bit-depth8/10/12 битдоступен при high-bit-depth сборке
--input-bit-depthфактическая глубина входасогласовывается с profile и source

Работа в скриптах и пакетном кодировании

vpxenc хорошо подходит для автоматизации именно потому, что все параметры находятся в командной строке. Но воспроизводимый скрипт должен фиксировать не только набор ключей. На результат влияют версия libvpx, параметры сборки, число потоков и архитектурные оптимизации. Если файлы создаются для тестовой базы, рядом с командой стоит сохранять вывод vpxenc --help или хотя бы строку с версией кодера.

Надёжный wrapper выполняет несколько проверок до старта: существует ли вход, доступен ли нужный encoder, поддерживается ли WebM I/O, есть ли high-bit-depth keys при необходимости, свободно ли имя stats-файла, не существует ли уже output, если перезапись запрещена. После завершения проверяют exit code и фактическое наличие ненулевого выходного файла. Это проще и надёжнее, чем пытаться распознать успех только по последней строке progress.

Уникальные имена статистики two-pass

При параллельной обработке каждому ролику нужен собственный FPF. Хорошая схема — производить имя из идентификатора задания или безопасного имени исходника: work/clip-001.vpx.stats. Не используйте один глобальный firstpass.stats для всех процессов. Даже если jobs стартуют с небольшим разносом, один может перезаписать файл, пока другой уже читает его для второго прохода.

Отмена и промежуточные файлы

При принудительном завершении output может существовать, но быть неполным. Скрипт должен писать сначала во временное имя, например output.webm.part, и переименовывать в окончательное только после нулевого exit code. Для двухпроходной работы статистику тоже удобно держать во временном каталоге и удалять только после успешного pass 2.

Логи

Для отладки полезно сохранять stderr отдельно от данных pipe. Если vpxenc получает Y4M через stdin, его собственный журнал не должен смешиваться с видеопотоком producer. В shell это обычно решается стандартным разделением stdout/stderr. На production можно включить --quiet, но warnings и fatal messages оставить в файле задания.

Параллельные encode jobs

Один процесс с большим --threads не всегда эффективнее нескольких независимых процессов. Для набора коротких роликов throughput иногда выше при меньшем числе threads на job и нескольких jobs параллельно. Однако это уже задача планировщика: память, cache, disk I/O и pipe producers могут стать общим узким местом. vpxenc предоставляет thread limit, но не распределяет ресурсы между несколькими процессами.

Ограничения vpxenc, которые важно знать заранее

Первое ограничение — вход. vpxenc не является универсальным demux/decode frontend. Он ориентирован на Y4M и сырой YUV. Это делает поведение прозрачным, но требует внешнего этапа для обычных медиаконтейнеров.

Второе — отсутствие аудио. WebM-выход vpxenc содержит закодированное видео; полноценный пользовательский файл с Opus/Vorbis собирается отдельно. Для workflows с несколькими аудиодорожками, субтитрами и метаданными нужен muxer.

Третье — параметры тесно привязаны к возможностям конкретной сборки libvpx. WebM I/O, high bit depth, набор включённых encoders и некоторые оптимизации могут отличаться. Поэтому чужая команда, которая работает на одной машине, может содержать неизвестный ключ на другой.

Четвёртое — программа не выполняет высокоуровневую подготовку картинки. Crop, rotate, complex scaling, colorspace conversion, deinterlace, denoise, subtitles burn-in и подобные операции лучше делать до vpxenc специализированными фильтрами.

Пятое — глубокие параметры кодера не образуют универсальный максимум качества. Tiles, row-mt, AQ, AltRef, TPL, loopfilter, GF limits и q bounds взаимодействуют. Хороший пресет определяется требованиями конкретного материала и системы доставки, а не максимальными числами.

Сравнение vpxenc с аналогами

У vpxenc есть два типа альтернатив. Первый — универсальные frontends, которые используют ту же библиотеку libvpx, но добавляют демультиплексирование, фильтры, аудио и контейнеры. Второй — самостоятельные CLI-кодеры других видеостандартов. Они похожи по рабочей модели несжатые кадры → управляемый видеобитстрим, но создают другой codec и потому не являются взаимозаменяемыми, если получатель требует конкретно VP8/VP9.

ПрограммаЛучше подходит дляГлавное ограничение
vpxencпрямого управления VP8/VP9 и параметрами libvpx через CLIвход в основном Y4M/raw YUV, нет аудиодорожек
FFmpeg + libvpxполного транскодирования файлов с декодированием, фильтрами, аудио и muxчасть опций задаётся через wrapper и отличается по синтаксису от vpxenc
aomencнизкоуровневого кодирования AV1 библиотекой libaomне создаёт VP8/VP9
x264CLI-кодирования H.264/AVC, включая CRF и двухпроходный bitrateне создаёт VP8/VP9
x265CLI-кодирования HEVC/H.265 из raw YUV или Y4Mвыход CLI — HEVC-битстрим, а не VP8/VP9/WebM
SvtAv1EncAppотдельного AV1-кодирования с масштабированием по многим CPU-потокамориентирован на AV1 и не заменяет VP8/VP9 encoder

Практический вывод простой: если конечный формат должен быть VP8 или VP9 и нужен доступ именно к нативным controls libvpx, vpxenc даёт наиболее прямой интерфейс. Если исходник — обычный MP4/MKV и одновременно нужно обработать звук, фильтры и контейнер, FFmpeg с libvpx уменьшает число этапов. aomenc и SVT-AV1 логичны, когда целевой codec — AV1; x264 и x265 — когда инфраструктура требует H.264 или HEVC. Сравнивать эти инструменты только по числу ключей бессмысленно: решающим является требуемый стандарт битстрима и вся цепочка до/после кодера.

Когда выбирать vpxenc вместо FFmpeg с libvpx

Оба варианта могут использовать libvpx, но уровень абстракции отличается. FFmpeg переводит собственные codec options в поля libvpx и одновременно умеет читать десятки контейнеров, декодировать звук, фильтровать изображение и mux результат. vpxenc показывает интерфейс, близкий к reference/sample encoder: названия многих controls совпадают с документацией WebM Project и исходным API.

vpxenc удобнее, когда нужно проверить конкретный control libvpx без вопроса как FFmpeg назвал этот параметр и как пересчитывает единицы. Например, FFmpeg документирует, что его bitrate выражается в bits/s, тогда как --target-bitrate vpxenc — в kbps; buffer size тоже преобразуется между разными единицами. Для воспроизведения кодерного эксперимента нативная команда зачастую прозрачнее.

FFmpeg удобнее, когда вход не является Y4M/raw, нужна работа с несколькими потоками или фильтрами. Он может сам прочитать H.264 из MP4, масштабировать, конвертировать pixel format, передать кадры libvpx и одновременно закодировать Opus. Делать то же через vpxenc можно, но получится связка из двух или более процессов. Это не недостаток качества кодера — просто разный scope инструмента.

Частые вопросы о vpxenc

Можно ли кодировать MP4 напрямую?

Не следует рассчитывать на это как на функцию vpxenc. Его штатный путь — Y4M и raw YUV. MP4 нужно декодировать внешним инструментом, после чего подать Y4M/YUV через файл или stdin. На практике чаще используют FFmpeg: он читает контейнер и отдаёт yuv4mpegpipe.

Можно ли сохранить звук?

Нет, vpxenc занимается видео. Если аудио уже есть в исходнике, его можно извлечь/перекодировать отдельно и затем объединить с VP8/VP9-видео в WebM. Для remux видео можно копировать без повторного кодирования, если выбранный muxer принимает такой поток.

Как узнать, поддерживает ли мой бинарник VP9?

Запустите vpxenc --help и найдите блок Included encoders. Там перечислены включённые encoder interfaces и отмечен default. Этот способ надёжнее имени пакета или предположений о версии.

Почему в справке нет bit-depth?

High-bit-depth опции компилируются условно. Если сборка libvpx создана без VP9 high bit depth, --bit-depth и --input-bit-depth не появятся. Для 10/12-битного кодирования нужен бинарник с соответствующей поддержкой.

Что лучше: один или два прохода?

Это зависит от задачи. Two-pass нужен, когда можно дважды обработать файл и важна более осмысленная раскладка битов по всему клипу. One-pass обязателен для реального времени и удобен для быстрых задач. В realtime vpxenc сам ограничивает число проходов одним. Для коротких тестов разница может быть мала, для неоднородного длинного материала — заметнее.

Что выбрать: VBR, CBR или CQ?

VBR — когда важен средний bitrate/размер и допустимы локальные колебания. CBR — когда поток должен вписываться в модель канала и клиентского буфера. CQ — когда важнее держать выбранный quality level, но есть верхняя битрейтная граница. Режим Q нужен для более специальных сценариев с фиксированным quantizer behavior.

Какой cpu-used поставить?

Универсального числа нет. Выберите deadline, затем кодируйте репрезентативный фрагмент несколькими значениями и измеряйте скорость и результат. Для real-time минимальное требование — кодер вместе со всем upstream должен стабильно быть быстрее входного FPS на тяжёлых сценах. Для offline можно уменьшать cpu-used, пока дополнительное время оправдано вашим критерием качества/размера.

Нужно ли всегда включать row-mt?

Нет. Он полезен для VP9 на многопоточных CPU, но меняет характер параллелизма и может делать битстрим недетерминированным между запусками. Для throughput это часто приемлемо; для byte-exact regression tests — нет. Сначала проверьте, является ли CPU загрузка реальным ограничением.

Tile columns — это число колонок?

Нет, значение — логарифм по основанию два. 0 означает одну колонку, 1 — две, 2 — четыре, 3 — восемь. Это же принципиально отличает ключ от интерфейсов, где пользователь задаёт прямое число tiles.

Что даёт auto-alt-ref?

Кодер получает возможность создавать Alternate Reference Frames для улучшения предсказания будущих кадров. Для этого часто нужен lookahead, поэтому AltRef тесно связан с lag-in-frames и не подходит как бесплатное качество для минимальной задержки. В VP9 значения выше 1 позволяют multi-layer AltRef.

Можно ли сделать lossless VP9?

Да, --lossless=1 включает lossless coding VP9. Но lossless относится к YUV-кадрам, которые получает vpxenc. Если до этого цвет был конвертирован, масштабирован или субдискретизирован, эти изменения уже необратимы.

Как кодировать 10-битный 4:2:0?

Нужна high-bit-depth сборка, VP9 Profile 2, --bit-depth=10 и корректное описание input bit depth. Для 10-битного 4:4:4 требуется Profile 3. Всегда сверяйте фактический Y4M/raw layout: один только профиль не преобразует 8-битный вход в осмысленный 10-битный источник.

Почему target bitrate не совпал с итоговым средним?

Target — часть rate-control модели, а не жёсткий размер файла. Квантизаторные границы, режим CQ/VBR/CBR, keyframes, буфер, длина ролика, сложность и один/два прохода влияют на итог. Для диагностики включите verbose, q-hist и rate-hist и проверьте, не упирается ли кодер в ограничения q.

Можно ли использовать vpxenc для live?

Да, для этого есть --rt, CBR, buffer controls, drop-frame и другие механизмы. Но vpxenc не является готовым сервером трансляции: захват, сеть, пакетизация, аудио и transport остаются вне его scope. Кодер должен быть встроен в более широкую pipeline.

Для чего error-resilient?

--error-resilient включает функции, рассчитанные на более устойчивое декодирование при потерях. Они полезны в сетевых сценариях, но могут снижать coding efficiency. Значение нужно выбирать по требованиям транспорта и декодера, а не включать автоматически для локального файла.

Чем q-hist полезнее одного PSNR?

PSNR показывает качество относительно источника в виде метрики, а q-hist показывает внутреннее распределение quantizer. Если качество проваливается на сложных сценах, гистограмма помогает увидеть, что множество кадров достигло max-q. Это даёт причину, а не только итоговый показатель.

Можно ли отключить loop filter ради резкости?

Технически для VP9 есть --disable-loopfilter, но это не простой sharpen. Loop filter участвует в реконструкции reference frames. Полное отключение может повысить видимость block artifacts и изменить дальнейшее предсказание. Используйте этот control для конкретного теста, а не как универсальный пресет.

Почему WebM-выход недоступен в моей сборке?

WebM I/O является опцией сборки libvpx. Если оно отключено, vpxenc прямо сообщает об этом при --webm. Запишите IVF и remux либо используйте сборку с WebM I/O.

Можно ли кодировать только часть ролика?

Да, через --skip и --limit в кадрах. Это удобно для теста presets. При two-pass оба прохода должны использовать тот же отрезок, иначе статистика первого прохода перестанет соответствовать второму.

Нужно ли задавать fps для Y4M?

Обычно Y4M уже содержит frame rate в заголовке. Для raw YUV fps нужно сообщить явно. Если pipeline генерирует нестандартный Y4M, всё равно проверьте заголовок и verbose output, чтобы исключить ошибку producer.

Можно ли передать несколько выходных потоков?

В коде vpxenc присутствует per-stream configuration и разделитель параметров --, который позволяет создавать следующий stream с собственной конфигурацией. Это низкоуровневая возможность, полезная в специальных multi-stream сценариях. Для обычного кодирования один вход → один output проще запускать отдельными командами: так меньше риск перепутать filenames, stats и rate-control параметры.

Практическая стратегия настройки с нуля

Для файлового VP9 начните с Y4M, явных --codec=vp9, --webm, --good, выбранного --cpu-used и одного rate-control режима. Не добавляйте сразу AQ, TPL, GF limits и ручной loop filter. Сначала получите стабильную базу, сохраните команду и короткий test segment.

Затем задайте GOP по требованиям seek/segment. После этого измерьте использование CPU и только при необходимости добавьте --threads, --row-mt=1 и tile columns. Следующим этапом включайте content tuning и AQ, каждый раз сохраняя сравнимый результат. Для VBR/CQ, где допустим второй проход, отдельно оцените, даёт ли two-pass заметную пользу на вашем материале.

Для realtime порядок другой: сначала зафиксируйте resolution/FPS и budget CPU, включите --rt, one-pass CBR, target bitrate и buffer. Добейтесь устойчивой скорости на тяжёлых сценах. Только затем улучшайте качество в оставшемся временном бюджете. Любой lookahead или медленный mode, который периодически выбивает кодер ниже входного FPS, для live-сценария практической пользы не имеет.

Итог по возможностям vpxenc

vpxenc полезен тогда, когда требуется управлять самим процессом VP8/VP9-кодирования, а не всем мультимедийным проектом. Он принимает подготовленные YUV/Y4M-кадры, даёт прямой доступ к rate control, pass-режимам, GOP, AltRef, профилям, high bit depth, tiles, row-mt, AQ, content tuning и диагностике, а результат сохраняет как WebM или IVF. За эту прозрачность приходится платить ручной подготовкой входа и отдельной работой с аудио и mux.

Наиболее устойчивый workflow строится не вокруг максимально длинной команды, а вокруг минимального набора параметров, которые отражают реальные требования: какой codec нужен, какой профиль совместим с пикселями, какая задержка допустима, что важнее — bitrate или quality, и каким ресурсом CPU располагает система. После этого дополнительные controls vpxenc становятся не набором загадочных флагов, а точными инструментами для конкретной цели.

Перенос настроек между vpxenc и FFmpeg

Поскольку FFmpeg умеет использовать libvpx, названия многих настроек имеют прямые соответствия, но единицы и синтаксис не всегда одинаковы. Это особенно важно при переносе пресета из одной среды в другую: совпадающее число не обязательно означает совпадающую конфигурацию. Например, --target-bitrate vpxenc задаётся в кбит/с, а -b:v FFmpeg выражается в бит/с и обычно записывается с суффиксом k или M.

vpxencТипичное соответствие в FFmpeg/libvpxЧто проверить
--target-bitrate-b:vразные единицы записи bitrate
--kf-max-dist-gзначение в кадрах
--kf-min-dist-keyint_minподдержка зависит от выбранного режима
--min-q-qminграница quantizer, не целевое качество
--max-q-qmaxслишком жёсткое значение ломает rate control
--cpu-used-cpu-usedзначение интерпретируется выбранным VP8/VP9 encoder
--auto-alt-ref-auto-alt-refдля multi-layer VP9 допустимы значения больше 1
--lag-in-frames-lag-in-frames / -rc-lookaheadlookahead повышает latency
--tile-columns-tile-columnsзначение log2 числа колонок
--tile-rows-tile-rowsзначение log2 числа рядов
--row-mt-row-mtнужна сборка FFmpeg/libvpx с соответствующей поддержкой

Buffer options требуют ещё большей аккуратности. vpxenc задаёт buf-sz, buf-initial-sz и buf-optimal-sz в миллисекундах данных, а FFmpeg работает с размером буфера в битах и преобразует его к модели libvpx. Поэтому копирование числа 6000 из --buf-sz=6000 в -bufsize 6000 даёт совсем другой физический смысл.

Ещё одно отличие — вход. В FFmpeg -pix_fmt может не только описывать, но и инициировать преобразование через libswscale/filters. В vpxenc ключ --i420 или --i444 в первую очередь сообщает, как читать уже существующие байты. Если raw-файл фактически I420, а указать I444, программа не повысит цветовую дискретизацию — она прочитает поток с неверной геометрией.

Контрольный список перед длительным кодированием

  • Проверьте короткий фрагмент тем же способом декодирования, что будет использован для всего ролика.
  • Для raw входа письменно зафиксируйте width, height, fps, pixel layout и bit depth.
  • Для VP9 согласуйте profile с depth и chroma subsampling до запуска полного job.
  • Убедитесь, что --help конкретного бинарника содержит нужный codec и дополнительные функции.
  • Если нужен WebM, проверьте наличие WebM I/O; если нет — сразу планируйте IVF и remux.
  • Для two-pass назначьте уникальный FPF и одинаковую обработку входа на обоих проходах.
  • Для CBR рассчитайте buffer settings в миллисекундах допустимой задержки, а не копируйте их из чужого профиля.
  • Для high-bit-depth включите validation и проверьте декодированный тестовый кадр до многочасового запуска.
  • Для пакетной работы сохраняйте stderr и exit code, даже если включён --quiet.
  • Не оценивайте итог только по размеру файла: проверьте декодирование, нужный профиль/level и характер артефактов на сложных сценах.

Если эти пункты выполнены, большинство неприятных сюрпризов обнаруживается на минутном тестовом участке, а не после завершения многочасового двухпроходного кодирования. Для vpxenc это особенно важно: программа предоставляет очень низкоуровневый контроль и ожидает, что пользователь сам согласует параметры входа, битстрима и конечной системы воспроизведения.