Per-title и per-scene кодирование: умные битрейтные лестницы

Автор: Николай СапуновОбновлено: август 202614 мин чтения
Содержание статьи +

TL;DR

Битрейтная лестница (bitrate ladder) – это набор пар «разрешение–битрейт», который ваш сервис предлагает зрителям. Раньше для её построения просто копировали фиксированный список из спецификации Apple HLS. Per-title encoding анализирует содержимое каждого видео и строит индивидуальную лестницу под конкретное видео – это обычно позволяет сократить расходы на хранение и трафик на 20–80% при сохранении той же визуальной чёткости. Per-scene encoding (также известное как shot-based или content-adaptive encoding) идёт ещё дальше: он варьирует битрейт внутри одного видео – от сцены к сцене, чтобы, например, спокойный диалог не оплачивал трафик за соседнюю сцену с погоней. В этой статье мы разберём всю математику, алгоритмы, реальные данные об экономии от Netflix, Bitmovin и Mux, а также расскажем, как выбрать подходящий подход для вашего сервиса.

Зачем это нужно

Если вы транслируете видео зрителям, выбор битрейтной лестницы одновременно определяет три вещи: ежемесячный счёт за CDN, качество изображения на разных скоростях интернета и скорость восстановления плеера после обрыва сети. Фиксированная лестница, взятая из спецификации 2017 года, избыточно расходует битрейт на простом контенте (например, вебинарах) и не обеспечивает достаточного качества для сложного (например, спорта) – оба варианта неприемлемы. Продакт-менеджерам и основателям важно понимать этот компромисс, потому что экономия может быть значительной – от 10 до 80% трафика в зависимости от каталога, – и её хватит, чтобы покрыть разработку новой фичи на целый квартал. Инженерам это важно, потому что алгоритмы per-title encoding опираются на математику выпуклых оболочек, машинное обучение и метрики качества вроде VMAF – то, чего старая модель фиксированной лестницы не требовала.

Что такое битрейтная лестница

Прежде чем переходить к «per-title», убедимся, что под «лестницей» мы понимаем одно и то же. В adaptive streaming – технологии, которая позволяет телефону переключаться с HD на SD, когда поезд заезжает в тоннель, – сервис одновременно отдаёт одно и то же видео в нескольких уровнях качества. Каждый уровень имеет определённое разрешение (например, 1920×1080 пикселей) и средний битрейт (например, 5 мегабит в секунду, или 5 Mbps). Вся совокупность таких пар (разрешение, битрейт) и составляет битрейтную лестницу. Во время воспроизведения плеер перемещается по этой лестнице вверх и вниз, выбирая максимально возможный уровень, который поддерживает текущая пропускная способность. Представьте лестницу как размеры кофе в кофейне: один и тот же напиток, разные объёмы – выбор остаётся за гостем.

Спецификация Apple HLS Authoring Specification, которую большинство инженеров до сих пор используют как отправную точку, рекомендует примерно девять–двенадцать уровней для H.264 – например, 145 кбит/с при разрешении 416×234, 1 Мбит/с при 768×432, 4,5 Мбит/с при 1280×720 и 7,8 Мбит/с при 1920×1080. Сама Apple подчёркивает, что это «начальные ориентиры» и что битрейт следует подбирать с учётом конкретного контента, однако на практике многие пайплайны используют эти значения буквально. Это и есть фиксированная лестница битрейтов. Она не различает, работаете ли вы с мультфильмом, трансляцией финала Лиги чемпионов или статичной презентацией – и тратит одинаковое количество битов на все три случая.

Рисунок 1. Фиксированная лестница использует одни и те же уровни битрейта для всех видео. Per-title лестница подстраивается под реальную кривую rate-quality конкретного видео: простой контент требует меньше битрейта, сложный – больше.

Идея Per-Title Encoding

Per-title encoding отказывается от фиксированной лестницы битрейтов и строит новую для каждого поступающего видео. Высокоуровневый подход, опубликованный Netflix в 2015 году в инженерном блоге (и запустивший всю индустрию), состоит из трёх шагов. Сначала видео кодируют в нескольких разрешениях и при разных уровнях качества – получается облако точек (разрешение, битрейт, качество). Затем проводят кривую, соединяющую лучшие из этих точек: максимально достижимое качество при заданном битрейте. Эта кривая называется выпуклой оболочкой (convex hull) – математическая граница, за которой «лучше уже не получится» на данном энкодере и данном контенте. Наконец, ступени лестницы расставляют вдоль этой кривой на тех битрейтах, которые реально использует ваша аудитория.

Метрика качества на втором шаге редко бывает «сырым» PSNR (peak signal-to-noise ratio), потому что PSNR плохо коррелирует с тем, как видео воспринимается человеком. Большинство современных пайплайнов используют Video Multi-Method Assessment Fusion (VMAF) – метрику, которую Netflix выпустила в open source в 2016 году. VMAF оценивает видео по перцептивной шкале от 0 до 100, где 93 – уровень broadcast-качества, а 95 – практически неотличимо от оригинала. (Подробнее в нашей статье про метрики качества.)

Зачем нужна выпуклая оболочка? Потому что при одинаковом битрейте – например, 1.5 Mbps – видео в разрешении 1080p может выглядеть хуже, чем 720p. Дополнительные пиксели 1080p требуют битов, которые энкодер вынужден перераспределить из областей, важных для восприятия: границ и лиц. Выпуклая оболочка показывает, какое разрешение оказывается выгоднее при каждом конкретном битрейте. Так, для спокойной анимации 1080p может начать превосходить 720p уже с 1.2 Mbps, а для динамичного хоккейного матча – только с 5 Mbps.

Рисунок 2. Каждое разрешение даёт свою кривую зависимости качества от битрейта. Внешняя огибающая всех этих кривых – выпуклая оболочка – показывает наилучшие возможные результаты, которых может достичь энкодер для данного видео. Ступени «умной» битрейтовой лестницы располагаются вдоль этой огибающей.

Математика экономии битрейта

Возьмём типичный полнометражный фильм продолжительностью 90 минут, транслируемый в разрешении 1080p со скоростью 6 Мбит/с. Общий объём трафика для одного зрителя, досмотревшего фильм до конца:

объём = битрейт × время
      = 6 Mbps × 5,400 секунд
      = 32,400 мегабит
      = 4,050 мегабайт
      ≈ 4.05 GB

Теперь предположим, что анализ по каждому фильму показал: именно этот фильм – допустим, диалоговая драма – достигает VMAF 95 уже при 3,2 Mbps. Новый объём:

объём_новый = 3.2 Mbps × 5,400 с
            = 17,280 Mb
            = 2,160 MB
            ≈ 2.16 GB

Это сокращение исходящего трафика на 47% для данного фильма. Если CDN берёт 1 цент за гигабайт, а фильм набирает 5 миллионов просмотров в год, экономия составит:

экономия = (4.05 − 2.16) GB × 5,000,000 просмотров × $0.01/GB
         = $94,500 в год на одно видео

Это выражение – «умножить дельту на просмотр на количество просмотров на удельную цену» – и есть весь бизнес-кейс per-title encoding в одной строке. Оно же объясняет, почему экономия концентрируется в самых просматриваемых видео: оптимизация даёт одинаковый процентный выигрыш на каждом видео, но абсолютная сумма экономии масштабируется с ростом числа просмотров.

Где Per-Title Не Срабатывает – и Где Начинается Per-Scene

Per-title строит одну лестницу битрейтов на всё видео – то есть каждая часть видео получает одинаковый битрейт в секунду. Такой подход хорошо работает, когда сложность контента примерно одинакова: выпуск новостей, вебинар, ситком со статичной камерой. А вот там, где сложность резко меняется – например, в триллере, где чередуются тёмные диалоги в интерьере и динамичные сцены погони, или в спортивной трансляции, где камера переключается между общим планом поля и крупным планом травы, – он справляется гораздо хуже.

В триллере диалоговая сцена выглядит идеально при 1,5 Мбит/с – движений почти нет, камера неподвижна. Сцена погони требует 8 Мбит/с, чтобы избежать блочности при быстрых панорамах и крупных планах. Метод per-title encoding выбирает один битрейт, например 4 Мбит/с, усредняя нагрузку: диалог перерасходует 2,5 Мбит/с, а погоня недополучает 4 Мбит/с и демонстрирует артефакты. Глаз зрителя цепляется именно за артефакты, а не за экономию на диалогах.

Per-scene encoding (также известный как shot-based encoding или content-adaptive encoding) решает эту задачу, разделяя видео на shots – непрерывные фрагменты съёмки между склейками – и рассчитывая для каждого из них отдельную кодировочную стратегию. Один shot – это непрерывная съёмка без переходов; в большинстве профессионального контента средний shot длится около 4 секунд, так что 60-минутная драма содержит примерно 900 таких фрагментов. Netflix Dynamic Optimizer, запущенный в продакшене в 2018 году, кодирует каждый из этих shots на нескольких уровнях качества, затем применяет лагранжеву оптимизацию ко всему фильму, чтобы подобрать для каждого shot оптимальное качество, минимизирующее общий битрейт при заданном среднем VMAF, после чего всё собирается обратно. Netflix сообщил об дополнительной экономии 17,1% по сравнению с per-title: короткие сцены опускаются до более низких разрешений, а напряжённые сцены получают освободившиеся биты.

Рисунок 3. Per-Title применяет один битрейт ко всему видео. Per-Scene анализирует каждый кадр и перераспределяет биты от простых сцен к сложным, не снижая воспринимаемое качество.

Типичная ошибка: резать только по границам GOP

Подвох, на который попадает каждый инженер при первой попытке per-scene encoding: кадры сцены должны начинаться на границах GOP (group of pictures), чтобы плеер мог корректно переключать ступени «лестницы» качества. (Подробнее в статье про GOP-структуру.) Если ваш детектор сцен обнаруживает границу сцены посередине закрытого GOP, у вас остаётся два плохих варианта: разрезать GOP и допустить артефакты декодирования или сдвинуть границу сцены на следующий ключевой кадр и потерять часть оптимизации. Решение, применяемое Netflix, Bitmovin и Mux, – принудительно ставить keyframe на каждой найденной границе сцены в проходе анализа. Это делает каждый shot чуть хуже сжимаемым (теперь он начинается с дорогого I-кадра), но потери от лишних keyframes значительно меньше, чем выигрыш от адаптации под каждую сцену.

Как алгоритмы работают на практике

В 2026 году в продакшене используются три варианта реализации, упорядоченные по сложности:

Тесты перебора кодировок (оригинальный метод Netflix)

Для каждого видео выполняем кодирование во всех комбинациях (разрешение, битрейт): например, пять разрешений × восемь битрейтов = сорок тестовых кодировок, и измеряем VMAF для каждой. По этим сорока точкам строим выпуклую оболочку, выбираем ступени, попадающие в нужный диапазон VMAF, остальные отбрасываем. Это самый точный метод, поскольку напрямую измеряет результат работы энкодера. Но он и самый дорогой: сорок тестовых кодировок требуют на порядок больше вычислений, чем одно финальное кодирование, так что один проход анализа может обойтись дороже, чем весь фиксированный пайплайн. Netflix может себе это позволить, потому что итоговые биты раздаются примерно 270 миллионам подписчиков – амортизация на просмотр делает стоимость практически незаметной.

Lookahead-плюс-один энкод (Bitmovin / классический CAE)

Проводим быстрый первичный анализ файла – например, один проход на пятой скорости в исходном разрешении или CRF-зонд – собираем статистику (motion energy, spatial complexity, шум) и передаём её модели, которая предсказывает оптимальную выпуклую оболочку без перебора всех комбинаций. Модель может быть ручной (как в ранних CAE-системах) или обученной на бенчмарковом датасете (в современных системах). На выходе получаем лестницу той же формы, что и при полном переборе (brute force), но с затратами, эквивалентными всего одному дополнительному кодированию. Bitmovin в публичном datasheet сообщает об экономии до 87% на верхних рендициях и более чем 22%-ном улучшении top-line VMAF при неизменном битрейте.

Neural-Network Inference (Mux Instant Per-Title, ML-CAE)

Прогоняем исходник через свёрточную нейросеть – на выходе сразу получаем готовую лестницу: никаких тестовых кодировок, зондовых проходов, только инференс на сырых кадрах. Обучающие данные – «brute-force» лестницы для десятков тысяч клипов; сеть учится отображать зависимость «как выглядит контент → какой должна быть лестница». Время инференса – миллисекунды, что делает подход применимым для live-стримов, где нет бюджета на зондовый проход. Mux публично описывает этот метод как основу своего instant per-title пайплайна. Точность немного ниже, чем у brute force на out-of-distribution контенте, но разница в скорости – шесть порядков.

МетодСтоимость анализаПодходит для liveТипичная экономия vs фиксированнойГде блистает
Brute-force test encodes10–40× одного кодированияНет20–50%Премиальные VOD-каталоги с большим числом просмотров
Lookahead + CAE-модель~1.2–1.5× одного кодированияНа границе (chunked live)20–40%Средние VOD-библиотеки; live с задержкой в несколько секунд
Neural-network инференсМиллисекундыДа15–35%Live; UGC; очень большие библиотеки

Подробнее о том, какие энкодеры используются ниже по пайплайну после этих методик, см. статью про rate control и шпаргалку по FFmpeg.

Контекстно-зависимое кодирование: ещё одно измерение

Per-title и per-scene подходы ориентированы на анализ самого контента. Юрий Резник из Brightcove, впервые введший этот термин ещё в 2017 году, тогда же отметил: важно учитывать и контекст – особенности устройств, экранов и сетей, на которых видео транслируется. Если 80% зрителей смотрят контент на мобильных устройствах и не доходят до 720p+, то более высокие уровни качества – 4K и 1440p – становятся бесполезной нагрузкой для CDN. А если аудитория сосредоточена в регионе со средней пропускной способностью около 4 Мбит/с, то уровни 8 и 12 Мбит/с обслуживают лишь узкую группу пользователей с оптоволоконным подключением, при этом увеличивая количество кодировок без реальной пользы.

Контекстно-зависимое кодирование (CAE) берёт лестницу per-title или per-scene и подрезает или сдвигает её на основе аналитики поведения аудитории: удаляет те ступени, которые никто не смотрит, сдвигает оставшиеся ближе к модальному диапазону и пересчитывает целевой VMAF с учётом размера экрана. В работе Резника для SMPTE 2023 года указано дополнительное снижение битрейта на 10–20% по сравнению с per-title, если CAE настроен на реальные данные аудитории, а не на гипотетические. Цена – операционная: требуется обратная аналитика воспроизведения, поступающая в пайплайн кодирования, и необходимость перекодировки при изменении состава аудитории.

Live Streaming Меняет Правила

Per-title придумали для VOD, где файл хранится на диске и его можно анализировать часами. Live меняет сразу три ограничения: нет единого файла для анализа, жёсткий бюджет задержки в несколько секунд и контент может за одну сцену резко перейти от спокойного к хаотичному (вспомните, например, полупропускной отчёт в перерыве, после которого камера возвращается на поле). В продакшене выработались три адаптации:

Chunk-уровневая адаптация. Bitmovin, Mux и AWS Elemental MediaLive поддерживают chunk-уровневый контроль битрейта, при котором лестница битрейтов фиксируется при запуске стрима, но энкодер для каждого сегмента нацеливается на слегка отличающийся битрейт на основе короткого анализа вперёд (lookahead). Экономия обычно составляет 5–15%.

Audience-adaptive encoding. Mux запускает модель, отслеживающую входящую телеметрию плееров, и постепенно корректирует лестницу битрейтов прямо во время стрима – те ступени, которые зрители не выбирают, убираются или заменяются. Такой подход ближе к CAE, чем к per-title.

Online per-scene encoding (OPSE). Исследование лаборатории ATHENA Christian Doppler Laboratory в 2022 году представило подход, при котором каждый входящий фрагмент (chunk) сопоставляется с заранее подготовленной библиотекой типичных сцен, а параметры кодирования берутся из наиболее подходящего соответствия. Обещаемая экономия достигает 25% по сравнению со статическим live-кодированием при дополнительной задержке менее одной секунды.

Для low-latency форматов – LL-HLS или WebRTC – бюджет на lookahead снижается до менее чем секунды, поэтому большинство систем в продакшене сегодня используют тщательно подобранную адаптивную по аудитории фиксированную лестницу с настройкой параметров на уровне потока, а не полноценную оптимизацию по сценам.

Где здесь Фора Софт

Мы разрабатываем стриминговые видеопродукты: OTT- и интернет-ТВ-платформы, где затраты на CDN должны быть предсказуемыми; платформы видеоконференций, где важна каждая миллисекунда пропускной способности; e-learning-системы, где лекции варьируются от записи слайдов до формата «камера + доска»; а также решения для видеонаблюдения и телемедицины, где пропускную способность оплачивает клиент. В каждой из этих сфер оптимальная стратегия per-title или per-scene имеет свою специфику. Лекционная платформа может использовать brute-force per-title ночью при каждом загрузке – лекции редко транслируются в прямом эфире. Для OTT-трансляций спортивных событий требуется neural-inference per-title в сочетании с context-aware обрезкой. В телемедицинских приложениях достаточно context-aware подхода – контент однороден, а сеть нестабильна. Выбор правильной комбинации – один из ключевых шагов, который мы проходим с каждым новым проектом на старте.

Ключевые выводы

  • Битрейтная лестница – это набор пар (разрешение, битрейт), которые предлагает стрим; фиксированная лестница тратит биты на простой контент и обделяет сложный.
  • Per-title encoding строит лестницу под конкретное видео, сэмплируя сетку rate-quality и выбирая оптимальные точки по выпуклой оболочке; типичная экономия – 20–50% при том же качестве.
  • Per-scene (shot-based) кодирование разбивает видео на сцены и назначает каждой свой битрейт, добавляя ещё 10–20% экономии поверх per-title.
  • Существует три варианта реализации: brute-force, lookahead-плюс-модель и инференс на нейросетях – выбор зависит от бюджета и требований к задержке.
  • Context-aware encoding адаптирует лестницу под реальные устройства и сети аудитории и применяется поверх per-title.
  • Live-стримы используют chunk-level или audience-adaptive подходы, поскольку цельного файла для анализа нет.

Что почитать дальше

Строите такую систему?

Подберём параметры кодирования под ваш контент и посчитаем стоимость доставки до старта разработки.