Содержание статьи +
- Коротко
- Зачем это нужно
- Лестница «один размер для всех» и почему она не работает
- Переворот: фиксируем качество, отпускаем битрейт
- Как цель по качеству строит лестницу
- Рабочий пример: одна цель, две очень разные лестницы
- Per-shot encoding: та же идея на уровень глубже
- О чём цель по качеству вам не говорит
- CRF, QP и ручка, которая реально попадает в цель
- Где здесь Фора Софт
- Главное
- Что почитать дальше
Коротко
Per-title encoding даёт каждому видео собственную битрейтную лестницу вместо одной фиксированной на весь каталог, и проще всего понять его, перевернув вопрос: перестаньте фиксировать битрейт и отпускать качество в свободное плавание – вместо этого зафиксируйте цель по качеству (обычно оценку VMAF) и отпустите в плавание битрейт, чтобы каждый ролик добрал до неё столько, сколько ему нужно. Цель по качеству определяет лестницу: верхняя ступень – это наименьший битрейт, достигающий целевой оценки (обычно VMAF 93–95), нижние ступени расставлены так, чтобы соседи были достаточно близко и переключение было незаметным, а каждая ступень использует то разрешение, которое набирает наибольший VMAF на своём битрейте, – выпуклую оболочку (convex hull). Per-shot encoding углубляет ту же идею на уровень ниже, выбирая лучшее разрешение и настройку качества для каждого плана (shot), и экономит примерно 30% битрейта при равном качестве по сравнению с одним фиксированным кодированием – ценой двух порядков роста числа кодирований на тайтл. Эта статья – взгляд со стороны качества; механика лестницы со стороны кодека живёт в разделе Video Encoding, а геометрия выпуклой оболочки разобрана в отдельной статье.
Зачем это нужно
Если вы кодируете видео на масштабе, битрейтная лестница – самый большой рычаг, который у вас есть, и над счётом за трафик, и над тем, что реально видит зритель. Эта статья для стриминг- или кодинг-лида, платформенного инженера или технического продакт-оунера, кто слышал «per-title экономит 20%» и хочет понять почему – со стороны измерения, где решение о каждой ступени принимает число, а не угаданный битрейт. Сделайте цель по качеству правильно – и вы перестанете переплачивать за простой контент (мультфильму не нужны 6 Мбит/с) и недодавать сложному (зернистый спорт рассыпается на блоки на тех же 6 Мбит/с). Сделайте неправильно – и вы либо тратите деньги на качество, которого никто не видит, либо отгружаете заметные артефакты, потому что фиксированная лестница ни разу не спросила, достаточно ли хороша картинка. Цель здесь – дать вам управляемую качеством ментальную модель, чтобы выпуклая оболочка, целевое качество и CI-гейт из остального Блока 5 читались как одна система.
Лестница «один размер для всех» и почему она не работает
Начнём с того, что per-title encoding пришёл заменить. Бо́льшую часть истории стриминга сервис выбирал одну битрейтную лестницу – фиксированный список пар «разрешение + битрейт», например 1080p на 5800 кбит/с, 720p на 3000 кбит/с и вплоть до 240p на 300 кбит/с, – и прогонял через неё каждый тайтл. Лестница – это набор рендиций, между которыми плеер адаптивно переключается при изменении пропускной способности; механика этого переключения называется адаптивным битрейтом (ABR), а лестница – его меню.
Фиксированная лестница тихо предполагает одно: что все видео примерно одинаково трудно сжимать. Это предположение неверно, и неверно сильно. Netflix сделал это наглядным, когда вводил per-title encoding в декабре 2015 года: на старой фиксированной лестнице для некоторых трудных тайтлов «даже самый высокий поток на 5800 кбит/с всё ещё показывал блочность», тогда как «для простого контента вроде мультфильмов 5800 кбит/с – намного больше, чем нужно для отличного 1080p-кодирования» (Netflix Technology Blog, Per-Title Encode Optimization, 2015). Та же лестница переобслуживала мультфильм и недообслуживала экшен-сцену. Хуже того: зритель на ограниченном канале, получающий 1750 кбит/с, мог бы смотреть тот мультфильм в полном HD, но фиксированная лестница для всех привязала 1750 кбит/с к стандартному разрешению.
Насколько велика разница между «трудно» и «легко»? Netflix закодировал около 100 своих тайтлов при постоянном качестве и построил график. На битрейте 2 Мбит/с самые трудные тайтлы набирали около 38 дБ PSNR – числа, которое сравнивает сжатый кадр с оригиналом попиксельно, где выше значит ближе к оригиналу, – а самые лёгкие переваливали за 48 дБ при той же настройке (Netflix 2015, по данным Streaming Media, 2016). Десять децибел PSNR – не погрешность округления; это разница между видимой блочностью и картинкой, неотличимой от источника. Для ориентира: Netflix отмечал, что ниже примерно 35 дБ его контент показывает артефакты кодирования, а выше примерно 45 дБ уже нет заметного улучшения. Одна лестница не может стоять в правильном месте для файлов, охватывающих такой диапазон.
Более глубокая проблема не в конкретных числах, а в том, что фиксированная лестница решает держать постоянным. Фиксированная лестница фиксирует битрейт и отпускает качество. Она гарантирует, что ступень 1080p всегда равна 5800 кбит/с, и не даёт никакого обещания о том, насколько хорошо эта ступень выглядит, – что ровно наоборот тому, что кого-либо реально волнует. Никто из смотрящих не хочет гарантированный битрейт; они хотят гарантированную картинку. Это наблюдение и есть вся идея per-title encoding, и легче всего увидеть её, перевернув вопрос.
Переворот: фиксируем качество, отпускаем битрейт
Вот переворот, после которого per-title encoding встаёт на место. Вместо того чтобы фиксировать битрейт и принимать любое выпавшее качество, зафиксируйте качество и примите любой битрейт, нужный для его достижения. Выберите цель – скажем, «верхняя ступень должна выглядеть практически неотличимо от источника», – выразите её числом на перцептивной метрике, и пусть битрейт каждого тайтла встанет туда, куда должен, чтобы добрать до этого числа. Мультфильм достигает цели на 2 Мбит/с; спортивный ролик требует 7 Мбит/с для той же цели. Одно обещание качества, разные битрейты – потому что контент разный.
Это и есть per-title encoding, определённый со стороны качества: выбор битрейтной лестницы каждого тайтла так, чтобы каждая ступень выполняла цель по качеству, а не по битрейту. Метрика, которая делает это практичным, – VMAF (Video Multi-method Assessment Fusion), перцептивная метрика качества, которую Netflix построил и выложил в open source, с оценкой от 0 до 100, где выше значит, что кодирование выглядит для человеческого глаза ближе к оригиналу (полностью разобрана в статье про VMAF). VMAF важен здесь потому, что он обучен отслеживать мнение человека, поэтому «цель VMAF 95» – это утверждение о том, как видео выглядит, а не о том, сколько бит оно тратит. PSNR подошёл для исходной демонстрации 2015 года, но именно перцептивная метрика придаёт цели по качеству тот смысл, который вам нужен.
Это самое важное предложение в статье, так что стоит сказать его прямо: в per-title encoding цель по качеству – это вход, а битрейт – выход. Всё остальное – сколько ступеней, какое разрешение, какое значение CRF – это машинерия для эффективного достижения этой цели. Как только вы это удержали, остальной per-title encoding – лишь аккуратная бухгалтерия.
Это же проводит границу для статьи. Механика того, как кодировщик производит конкретную ступень – построение битрейтной лестницы, настройки кодера, посценная обвязка, – принадлежит статье про per-title в разделе Video Encoding. Эта статья остаётся на стороне измерения: как число качества решает, какой должна быть лестница. Мы измеряем результат; за тем, как сжимать, – ссылка наружу.
Как цель по качеству строит лестницу
Превращение цели по качеству в реальную лестницу – это процесс из трёх шагов: задать верхнюю ступень, расставить ступени под ней и выбрать разрешение для каждой. Самое ясное публичное прохождение этого – у Яна Озера, выведенное из метода Netflix (Streaming Learning Center, 2021); логика ниже следует ему и называет, откуда берётся каждое число.
Шаг 1 – задать верхнюю ступень от цели по качеству
Верхняя ступень – это рендиция наивысшего качества, которую вы предлагаете, та, что получает зритель с запасом пропускной способности. В управляемой качеством лестнице вы не выбираете её битрейт; вы выбираете её оценку и находите наименьший битрейт, который её достигает. Широко используемая целевая полоса – VMAF 93–95, и оба конца восходят к субъективным исследованиям, а не к фольклору.
Нижний конец, 93, идёт из исследования RealNetworks, которое сопоставило VMAF с оценками людей на 4K-роликах: примерно на VMAF 93 сервис «может быть уверен, что оптимально обслуживает подавляющее большинство своей аудитории контентом, который либо неотличим от оригинала, либо с заметными, но не раздражающими искажениями» – это средняя оценка (MOS) между 4 и 5 (Rassool, VMAF Reproducibility, IEEE, 2017). Верхний конец, 95, идёт из исследования учёных из Университета RheinMain и стримингового сервиса Joyn: они нашли, что VMAF 95 – наименьшая оценка, «на которой видеосигнал в среднем субъективно неотличим от оригинального видеосигнала» (Kah et al., SPIE, 2021). Берите 93, если примете «заметно, но не раздражает», 95 – если хотите «неотличимо». В любом случае битрейт, который её достигает, – это выход измерения тайтла, а не число, которое вы задаёте заранее.
«Частая ошибка: верхняя ступень выше VMAF 95. Если ваша высшая ступень набирает 97 или 98, вы тратите трафик на качество, которого ни один зритель не увидит. Несколько субъективных исследований ставят потолок полезного качества около 95 для просмотра на большом экране; выше него лишние биты покупают разницу ниже порога человеческого восприятия. Лекарство – не «кодировать на высоком качестве», а найти наименьший битрейт, достигающий цели, и остановиться. На трудном 4K-ролике одна эта поправка может сэкономить пару мегабит в секунду на самой смотримой ступени.»
Практическая оговорка: некоторые тайтлы настолько трудны, что достижение VMAF 95 пробило бы вменяемый потолок битрейта. Поэтому большинство сервисов задают максимальный битрейт верхней ступени (скажем, 6 Мбит/с для 1080p H.264) и принимают чуть меньшую оценку на редком ролике, которому нужно больше. Цель – это ориентир, а не контракт, ради которого вы себя разоряете.
Шаг 2 – расставить ступени так, чтобы переключение оставалось незаметным
Ниже верхней ступени каждая нижняя существует, чтобы плеер на меньшей полосе всё равно получал лучшую возможную картинку для своего канала. Расстановкой управляют два правила, и хорошая лестница соблюдает оба.
Правило качества идёт из того, насколько тонко зритель воспринимает разницу в VMAF. Исследование RheinMain/Joyn нашло, что зрители не могут уверенно отличить две рендиции, когда их оценки VMAF в пределах примерно 2 баллов; дальше различия становятся видимыми (Kah et al., 2021). Поэтому, если вы хотите, чтобы адаптивные переключения были незаметны, соседние ступени должны отстоять не более чем примерно на 2 VMAF. Удержите это рядом с более грубой и более известной величиной: рекомендация Netflix 2017 года, что около 6 баллов VMAF – это одно едва заметное различие (JND), изменение, которое большинство зрителей замечает чаще, чем в половине случаев. Два балла консервативны (переключения незаметны); шесть баллов – порог, на котором переключение становится очевидным. Выбирайте шаг внутри этой полосы в зависимости от того, насколько вам важна плавность переключений против числа ступеней.
Правило битрейта идёт из механики ABR и тянет в другую сторону. Давняя рекомендация Apple (Technical Note TN2224, позже свёрнутая в HLS Authoring Specification) гласит, что соседние битрейты должны отстоять в 1,5–2 раза. Слишком близко – и вы добавляете рендиции, едва различающиеся, умножая стоимость кодирования и хранения без пользы; слишком далеко – и плеер может застрять на низкой ступени, когда у него была полоса на гораздо лучшую. Частый компромисс – умножать битрейт каждой ступени примерно на 0,6 при движении вниз, давая шаг около 1,66×.
Эти два правила взаимодействуют. Правило качества говорит «не давай соседям разойтись больше чем на ~2 VMAF»; правило битрейта говорит «не сближай их теснее ~1,5× по битрейту». На лёгком контенте обычно связывает правило битрейта (нужно мало ступеней); на трудном связывает правило качества (нужно больше ступеней, чтобы держать шаги маленькими). Поэтому число ступеней само по себе per-title. Тот же анализ RheinMain/Joyn показал, как далеко это может зайти: чтобы держать каждого соседа в пределах 2 VMAF на всём диапазоне, идеальная лестница может потребовать 13 ступеней для платного сервиса (нижний предел VMAF 70) или 21 для бесплатного (нижний предел VMAF 55) – гораздо больше, чем отгружает большинство сервисов, и это осознанный компромисс по стоимости, а не недосмотр.
Шаг 3 – выбрать разрешение для каждой ступени: выпуклая оболочка
Последний шаг отвечает на вопрос, который фиксированная лестница никогда не задавала: на данном битрейте какое разрешение выглядит лучше? Ответ – не всегда «самое высокое». На низком битрейте кодированию 1080p приходится размазывать свои немногие биты по вчетверо большему числу пикселей, чем кодированию 540p, поэтому оно часто выглядит хуже – более блочно, более размыто, – чем меньшее разрешение, растянутое под экран. На высоком битрейте более высокое разрешение вырывается вперёд, потому что у него наконец есть биты, чтобы отрисовать лишнюю детализацию.
Постройте качество против битрейта для нескольких разрешений – и получите по одной кривой на разрешение, пересекающие друг друга. Верхняя огибающая всех этих кривых – линия, которая на каждом битрейте следует за тем разрешением, что сейчас выигрывает, – это выпуклая оболочка (convex hull). Каждая ступень per-title-лестницы лежит на этой оболочке: вы выбираете битрейт из шагов 1 и 2, затем берёте разрешение, чья кривая наверху на этом битрейте. Это геометрия за per-title encoding, и она получает собственный полный разбор с рабочим графиком в статье про выпуклую оболочку – здесь достаточно знать, что «лучшее разрешение на ступень» – это измеренный результат, а не догадка.
Рабочий пример: одна цель, две очень разные лестницы
Числа делают экономию осязаемой. Возьмём два тайтла и дадим им одно и то же обещание качества – верхнюю ступень на VMAF 95 – и посмотрим, как расходятся битрейты.
Тайтл A, анимационная короткометражка. Плоские заливки цвета, чистые края, мало движения: легко сжимать. Перебор кодирований находит, что 1080p достигает VMAF 95 примерно на 2,0 Мбит/с; дальше кривая плоская, так что лишние биты не покупают ничего. Верхняя ступень: 1080p, 2,0 Мбит/с.
Тайтл B, зернистый ночной футбольный ролик. Плёночное зерно, быстрое движение, толпа: трудно сжимать. То же разрешение 1080p не достигает VMAF 95 до примерно 7,5 Мбит/с. Верхняя ступень: 1080p, 7,5 Мбит/с.
Теперь сравним оба со старой фиксированной лестницей, которая для всех привязала ступень 1080p к 5800 кбит/с. Для тайтла A фиксированная лестница потратила 5,8 Мбит/с на ступень, которой нужно было лишь 2,0, – впустую 3,8 Мбит/с, около 66% перерасхода на самой смотримой рендиции, на качество за порогом, который заметил бы любой зритель. Для тайтла B 5,8 Мбит/с фиксированной лестницы вообще не дотягивали до цели; она отгрузила заметно худшую ступень, чем 7,5 Мбит/с, которых реально требовал контент. Одна лестница, два провала в противоположных направлениях – и одна цель по качеству чинит оба, потому что задаёт каждому тайтлу единственный важный вопрос: что нужно, чтобы выглядеть вот настолько хорошо?
Сопутствующий построитель лестницы по целевому качеству выполняет ровно этот расчёт на вашей собственной сетке измерений: дайте ему точки «VMAF против битрейта» по разрешениям для ассета, целевую оценку и правило расстановки – и он вернёт per-title-лестницу и экономию битрейта против фиксированной лестницы, которую вы зададите. Он воспроизводит оба тайтла выше в режиме --demo.
Per-shot encoding: та же идея на уровень глубже
Целый тайтл не одинаково труден. В фильме есть тихая диалоговая сцена и затем взрыв; в матче – статичный предматчевый план и затем быстрый прорыв. Per-title encoding выбирает одну лестницу на весь тайтл, а значит, идёт на компромисс – тратит битрейт взрыва на диалог, или наоборот. Per-shot encoding убирает этот компромисс, выбирая рецепт кодирования на каждый план (shot), а не на тайтл.
Техника выросла из Dynamic Optimizer – пошотового фреймворка, который Netflix развернул в 2018 году. Идея держится на одном допущении: кадры внутри одного плана разделяют пространственно-временные характеристики – похожее движение, похожую детализацию, – поэтому план и есть естественная единица оптимизации. Для каждого плана и заданного целевого битрейта Dynamic Optimizer определяет оптимальное разрешение и настройку квантования, которые укладываются (но не превышают) этот битрейт, максимизируя VMAF плана, строя оптимальную по «скорость-искажение» выпуклую оболочку на каждый план, а не на тайтл (Netflix, Dynamic Optimizer, 2018; Katsavounidis et al., 2018). Цель оптимизации – сама перцептивная метрика: система буквально выбирает настройки, чтобы максимизировать измеренное качество на осознанном по качеству битрейте.
Выигрыш реален. Измеренное при равном VMAF, пошотовое динамическое оптимизирование снизило битрейт примерно на 28% для x264, 34% для x265 и 38% для VP9 против кодирования с постоянным качеством в опубликованном сравнении Netflix (Katsavounidis et al., 2018) – примерно 30% экономии поверх или вместо тех ~20%, которые даёт один per-title. Тот же контент, то же воспринимаемое качество, на треть меньше бит.
Эта экономия не бесплатна, и стоимость – причина, по которой per-shot не автоматически правильный ответ. Оптимизация каждого плана означает кодирование каждого плана много раз – на нескольких разрешениях и точках качества, – чтобы найти его выпуклую оболочку. Netflix сообщал, что пошотовая оптимизация увеличила число единиц кодирования «более чем на два порядка на одно кодирование, на тайтл», что вскрыло реальные узкие места в его параллельном пайплайне кодирования (Netflix, Optimized shot-based encodes, 2018). Стократный рост числа кодирований по карману, когда тайтл посмотрят десятки миллионов раз; его труднее оправдать для длинного хвоста каталога с горсткой просмотров. Решение экономическое – вычисления на кодирование сейчас против трафика, сэкономленного за время жизни просмотров тайтла, – и это ровно тот компромисс, который статья про бизнес-обоснование переводит в деньги.
О чём цель по качеству вам не говорит
Управляемая качеством лестница – мощный инструмент, и, как у любого решения на основе метрики, у него есть слепые зоны. Назвать их – это разница между «пользоваться числом» и «быть им обманутым».
Оценка бессмысленна без своей модели. «VMAF 95» – это не одно. VMAF поставляется с несколькими моделями – модель по умолчанию, настроенная под телевизор, модель для телефона, модель для 4K, – и одно и то же кодирование набирает по-разному под каждой. Лестница, построенная для гостиных-телевизоров по модели по умолчанию, может быть неверна для мобильной аудитории, которой нужна модель для телефона. Всегда называйте модель вместе с целью и сопоставляйте её с тем, как смотрят контент. Нюансы выбора модели разобраны в VMAF в деталях.
Усреднение (mean-pooling) прячет плохие планы. Одиночная оценка VMAF тайтла обычно – это среднее его покадровых оценок, а среднее может быть отличным, пока несколько планов ужасны. Двухчасовой фильм на VMAF 95 всё ещё может содержать тридцатисекундную зернистую сцену на VMAF 80, которую среднее тихо поглощает. Per-shot encoding помогает здесь именно потому, что оценивает каждый план, но если вы гейтите per-title-лестницу по одному среднему, вы можете отгрузить видимый провал внутри «отличного» числа. Смотрите на нижний перцентиль, а не только на среднее – рассуждение в пулинге покадровых оценок.
Сравнение между разрешениями – ловушка измерения. Каждая ступень per-title-лестницы на своём разрешении, но VMAF определён против эталона того же размера. Чтобы сравнить ступень 540p с источником 1080p, нужно увеличить декодированный кадр 540p обратно до разрешения источника перед оценкой – так и считается кросс-разрешенческий VMAF. Пропустите этот шаг – и числа окажутся не на одной шкале, а выпуклая оболочка, которую вы из них строите, будет неверной.
Оптимизировать под метрику – не то же, что под зрителя. Если ваша лестница награждает VMAF, а кодировщик может поднять VMAF трюком с резкостью или контрастом, который на деле не улучшает воспринимаемое качество, вы получите более высокое число и ни одного более довольного зрителя – метрика становится целью и перестаёт быть хорошей мерой. Это достаточно частая беда, чтобы Netflix построил специальную контрмеру – модель без выигрыша от улучшения (no-enhancement-gain), разобранную в VMAF-NEG. Относитесь к любой цели по качеству как к прокси, который можно обыграть, и проверяйте её против глаза на выборке. Более широкий каталог того, где объективные метрики вводят в заблуждение, – в где врут объективные метрики.
CRF, QP и ручка, которая реально попадает в цель
Остаётся один практический вопрос: раз вы знаете битрейт и разрешение ступени, как кодировщик производит её на нужном качестве? Честный ответ – вы редко командуете целью по качеству напрямую; вы командуете настройкой, которая её производит. Две релевантные настройки – QP (параметр квантования) и CRF (постоянный коэффициент качества) – обе это режимы постоянного качества, которые держат выбранное качество примерно ровным и дают битрейту меняться со сложностью сцены, что ровно то поведение, которого хочет цель по качеству. Netflix использовал тестовые кодирования с постоянным QP, чтобы картировать сложность каждого тайтла в 2015-м, затем отметил, что «перешёл на CRF» примерно с тем же результатом (David Ronca, Netflix, 2016).
В реальном per-title-пайплайне переборный анализ предсказывает значение CRF (или QP), которое сажает каждое разрешение около его целевого битрейта, часто в связке с потолком битрейта, чтобы трудная сцена не убежала, – приём под названием capped CRF. Детали этих режимов управления битрейтом – чем различаются CBR, VBR, CRF и capped CRF и когда какой использовать – это механика со стороны кодека, и она живёт в статье про управление битрейтом в разделе Video Encoding. Для взгляда со стороны измерения важно помнить, что CRF – это ручка, которой вы приближаете цель по качеству, а VMAF – то, чем вы проверяете, что реально в неё попали. Настройка предсказывает; метрика подтверждает.
Где здесь Фора Софт
Фора Софт строит видеософт с 2005 года – стриминг и OTT, видеоконференции, e-learning, телемедицину и видеонаблюдение, – и битрейтная лестница одна из первых вещей, которые мы настраиваем, когда счёт за трафик клиента или качество картинки становятся проблемой. Мы подходим к ней со стороны качества, описанной здесь: выбираем цель VMAF под платформу и контент, измеряем каждый ассет, чтобы найти наименьший битрейт, её достигающий, и строим лестницу из выпуклой оболочки, а не из скопированного списка битрейтов. Для каталога OTT или e-learning экономия – в основном трафик и хранение; для конференц- или surveillance-продукта, где контент живой и нет эталонного источника для оценки, то же мышление о цели по качеству смещается к безэталонным методам и другой части пайплайна. Наша методология бенчмарков Блока 7 применяет ту же дисциплину «сначала измерь, потом решай» к нашим собственным тестам кодеков, так что лестницы, которые мы рекомендуем, стоят на числах, а не на привычке.
Главное
- Per-title encoding даёт каждому тайтлу свою лестницу вместо одной фиксированной на весь контент.
- Ментальный переворот: фиксируйте цель по качеству (оценку VMAF) и отпускайте битрейт, а не наоборот.
- Верхняя ступень – наименьший битрейт, достигающий VMAF 93–95; выше 95 трафик впустую.
- Соседи в пределах ~2 VMAF для незаметного переключения, в 1,5–2 раза по битрейту для ABR.
- Per-shot экономит ~30% при равном качестве ценой роста числа кодирований в 100+ раз.
- Оценке нужны её модель и нижний перцентиль; метрика проверяет, кодировщик приближает.