Block-based prediction: MB, CTU, SB и superblocks

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

TL;DR

Каждый современный видеокодек сжимает кадр одинаково: он режет кадр на прямоугольники, предсказывает каждый прямоугольник из соседей или из предыдущих кадров и пишет в поток только маленький остаток-разницу. Этот прямоугольник называется macroblock в H.264, coding tree unit (CTU) в HEVC и VVC, и superblock (SB) в VP9, AV1 и черновике AV2 – а единственная содержательная разница между кодеками в том, насколько хитро им разрешено резать этот прямоугольник дальше. H.264 зафиксировал macroblock в размере 16×16; HEVC растянул его до 64×64 c квадродеревом; AV1 пошёл до 128×128 c 10-вариантным деревом; VVC и AV2 добавили тернарные, бинарные и асимметричные разбиения, чтобы выиграть ещё 10–30% битрейта. Статья объясняет блок как универсальную единицу работы внутри энкодера, что меняла каждая генерация и почему компромисс между размером блока и временем кодирования – это решение, которое определяет 80% эффективности сжатия.

Зачем это знать

Если вы строите стриминговый продукт, ваша команда потратит на настройку блочного разбиения больше времени, чем на любую другую ручку энкодера, потому что решение о разбиении одновременно определяет и битрейт выхода, и реальное время кодирования. Счета за облачный транскодинг, бюджеты задержки live-стриминга, кривые «качество против стоимости» – всё это упирается в то, какой размер блока выберет энкодер. Продакт-менеджер, понимающий, что «энкодер ищет в дереве прямоугольников», читает бенчмарк вендора, задаёт правильные вопросы про выбор пресета и не удивляется, когда быстрый пресет стоит на 25% больше битрейта. Основатель, который на совещании по дорожной карте кодеков может спросить «а почему мы всё ещё используем 16×16 блоки в 2026 году», экономит компании месяцы лишней работы с легаси.

Кадр – это сетка прямоугольников

Чтобы сжать кадр, каждый современный кодек начинает с одного и того же механического действия: накладывает на изображение сетку и каждую ячейку обрабатывает как независимую единицу работы. Ячейка – это самый маленький кусок пикселей, который энкодер будет рассматривать целиком. Внутри одной ячейки энкодер делает одно предсказание (от соседей или из более раннего кадра), считает один остаток (ошибку после предсказания) и пишет в поток одно компактное описание.

Представьте, что вы кладёте на стену мозаику. Если на стене ровный синий участок – хватит одной большой плитки. Если на стене лицо – нужны маленькие плитки вокруг глаз и рта и большие на гладких щеках. Решение о разбиении блоков – это и есть выбор размера плитки на лету, по одному кадру, чтобы потратить минимум бит на скучные области и максимум – на сложные.

Стартовый прямоугольник называется по-разному в каждой семье кодеков. В H.264 / AVC это macroblock, сокращённо MB, фиксированно 16×16 пикселей яркости. В H.265 / HEVC и H.266 / VVC это coding tree unit, сокращённо CTU, размером 64×64 в HEVC и 128×128 в VVC. В VP9 и AV1 это superblock, сокращённо SB, размером 64×64 в VP9 и 128×128 в AV1. Названия разные по историческим причинам, но роль одинакова: это самый большой прямоугольник, который энкодер когда-либо обработает как одно решение.

Рисунок 1. Самый большой верхнеуровневый прямоугольник каждой генерации, наложенный на один и тот же кадр. Чем больше стартовый блок, тем больше у энкодера свободы потратить биты эффективно внутри него.

Причина, по которой каждая генерация увеличивала прямоугольник, простая. Большой верхнеуровневый блок позволяет описать гладкий, медленно движущийся участок одним вектором движения и одним крошечным остатком, а не шестнадцатью или шестьюдесятью четырьмя дублирующими копиями того же вектора. Кадр 4K, сжатый macroblocks H.264 16×16, содержит 32 400 macroblocks на кадр; тот же кадр, сжатый superblocks AV1 128×128, содержит 2 025 superblocks на кадр – в пятнадцать раз меньше верхнеуровневых решений. Накладные расходы на блок суммируются быстро; меньше блоков – меньше оверхеда.

Macroblock – H.264 / AVC

Macroblocks были определены в H.261 в 1988 году и без изменений унаследованы MPEG-1, MPEG-2, MPEG-4 Part 2 и H.264. Macroblock всегда 16×16 пикселей яркости, плюс два блока 8×8 цветности под 4:2:0 – про сэмплинг цвета мы писали в статье про цветовые пространства.

В H.264 изменился не размер macroblock, а свобода внутри него. Более ранние кодеки требовали одно предсказание на macroblock. H.264 разрешил резать macroblock на под-блоки для компенсации движения:

  • 16×16 – один вектор движения на весь macroblock.
  • 16×8 или 8×16 – два вектора, по одному на половину.
  • 8×8 – четыре вектора, по одному на четверть.
  • Внутри каждой четверти 8×8: 8×4, 4×8 или 4×4 – до шестнадцати векторов в одном macroblock.

Это называется tree-structured motion compensation, потому что варианты выстраиваются в небольшое двухуровневое дерево. Энкодер выбирает самый дешёвый вариант через процесс под названием rate-distortion optimization, сокращённо RDO, про который мы подробно пишем в статье про mode decision и RDO. Пока достаточно запомнить: энкодер – это поисковый движок, он перебирает разбиения, считает стоимость каждого и оставляет самое дешёвое.

Потолок 16×16 у macroblock устарел. Современный контент – 1080p, 4K, HDR – содержит большие гладкие участки, которые можно было бы описать одним вектором на 64×64. H.264 этого сказать не может: он вынужден повторить тот же вектор в шестнадцати macroblocks. Это главная причина, почему H.264 проигрывает 30–50% битрейта современному кодеку 2026 года на том же контенте.

CTU и квадродерево – HEVC / H.265

HEVC, завершённый в 2013 году, оставил идею macroblock, но выбросил фиксированный размер 16×16. Новый верхнеуровневый прямоугольник – coding tree unit, CTU, размером 16×16, 32×32 или 64×64. Почти все реальные HEVC-энкодеры используют 64×64.

Внутри CTU HEVC ввёл квадродерево (quadtree): рекурсивная структура разбиения, где любой квадратный блок можно разрезать на четыре равные четверти, и любую четверть – снова, до минимума 8×8. CTU 64×64 – это глубина 0; лист 8×8 – глубина 3.

Представьте, что CTU – это торт 64×64. Можно съесть его целиком, можно разрезать на четыре куска 32×32 и для каждого решить, резать ли дальше. Если кусок однородный – оставляем целым. Если на куске мелкая текстура – режем на четыре под-куска 16×16 и так далее. Энкодер выбирает самое дешёвое дерево через RDO.

Почему это работает: на небе 4K HDR можно описать целый патч 64×64 одним вектором и почти нулевым остатком. На лице в том же кадре энкодер дойдёт до 8×8 вокруг глаз, где каждый пиксель меняется покадрово, и оставит 32×32 на щеке, где движение однородное. Суммарная стоимость в битах драматически ниже, чем форсировать 8×8 на весь кадр, а качество идентичное.

Цена – время кодирования. Полный RDO-поиск на глубине 3 HEVC оценивает 1 + 4 + 16 + 64 = 85 кандидатов разбиения на CTU, не считая выборов режима предсказания внутри каждого. Умножьте на 32 400 ÷ 64 ≈ 510 CTU на кадр 1080p, потом на 60 кадров в секунду для live – и получается 26 миллионов оценок разбиения в секунду. Реальные энкодеры используют шорткаты ранней остановки – если 32×32 уже хорошо, не лезть глубже – но полный поиск остаётся верхним пределом качества.

Почему 64×64 оказался sweet spot, а не 128×128: исследования HEVC показали, что 64×64 даёт 95% выигрыша от больших блоков на 1080p, а оставшиеся 5% не окупают сложность. AV1 и VVC всё равно пошли больше, потому что к 2018 году доминирующее разрешение сдвинулось на 4K и 8K.

Рисунок 2. CTU 64×64 HEVC, разрезанный квадродеревом. Гладкие области остаются на 32×32; детализированные дробятся до 8×8. Энкодер выбирает самое дешёвое дерево через RDO.

Superblock и 10-вариантное дерево – VP9 и AV1

VP9, завершённый в 2013 году одновременно с HEVC, ввёл термин superblock для той же идеи, размером 64×64. Структура разбиения была проще, чем чистое квадродерево HEVC: superblock мог разбиться на четыре под-блока 32×32 (классический quadtree split) или на две горизонтальные либо вертикальные половины – вниз до 8×8 (с 4×4 зарезервированным под спец-случаи intra). Этот вариант с четырьмя + горизонтальными/вертикальными иногда называют partial quadtree или R-shaped tree.

AV1, завершённый AOMedia в марте 2018, оставил идею superblock из VP9 и сделал три вещи иначе. Во-первых, удвоил максимальный размер до 128×128. Во-вторых, расширил набор разбиений с четырёх вариантов до десяти. В-третьих, разрешил асимметричные разбиения – три прямоугольника вместо четырёх квадратов – чтобы лучше ложиться на T-образные границы текстур, с которыми квадродеревья работают неуклюже.

Полный набор разбиений AV1 для одного блока, который их все поддерживает:

  • PARTITION_NONE – оставить блок целым.
  • PARTITION_HORZ – две горизонтальные половины (верх + низ).
  • PARTITION_VERT – две вертикальные половины (лево + право).
  • PARTITION_SPLIT – четыре равных квадрата (классический quadtree split). Только этот вариант можно рекурсировать.
  • PARTITION_HORZ_A – три прямоугольника: два маленьких сверху + один широкий снизу.
  • PARTITION_HORZ_B – три прямоугольника: один широкий сверху + два маленьких снизу.
  • PARTITION_VERT_A – три прямоугольника: два маленьких слева + один высокий справа.
  • PARTITION_VERT_B – три прямоугольника: один высокий слева + два маленьких справа.
  • PARTITION_HORZ_4 – четыре тонких горизонтальных полосы (4:1).
  • PARTITION_VERT_4 – четыре тонких вертикальных полосы (1:4).

Четыре T-разбиения – главный трюк. Лицо в профиль, граница здания на фоне неба, вертикальная кромка текста – это паттерны контента, которые квадродерево вынуждено описывать тремя блоками неправильной формы, а AV1 ловит в одно решение. На типичном контенте T-разбиения и 4-полосные вместе дают 3–5% битрейтного выигрыша AV1 над VP9 на той же фиделити.

Есть ограничения. Блоки 128×128 и 8×8 не могут использовать 4:1 и 1:4 разбиения. Блоки 8×8 не могут использовать ни одно T-разбиение. Прямоугольные разбиения, созданные один раз, нельзя дробить дальше – только квадратный исход PARTITION_SPLIT рекурсируется. Поэтому дерево AV1 иногда называют constrained 10-way recursive tree, а не свободным графом разбиений: ограничения и нужны, чтобы декодер оставался обозримым.

Рисунок 3. Десять вариантов разбиения AV1 для одного superblock. Рекурсируется только четырёхквадратный SPLIT; T-разбиения и 4-полосные – терминальные. Расширенный набор ловит границы текстур, с которыми чистое квадродерево справляется неуклюже.

QT + MTT и тернарный split – VVC / H.266

VVC, завершённый JVET как H.266 в июле 2020, выбрал четвёртый путь. Верхнеуровневый прямоугольник – CTU 128×128, как у AV1. Структура разбиения – квадродерево с вложенным multi-type tree, обычно сокращают до QT + MTT или QTMT.

Разбиение идёт в две фазы. Сначала CTU рекурсивно режется квадродеревом на квадраты поменьше – та же рекурсия, что в HEVC. Затем каждый лист квадродерева может быть дополнительно разбит multi-type tree (MTT), который добавляет пять вариантов:

  • Без разбиения – лист квадродерева и есть финальный coding unit.
  • Бинарный горизонтальный split – две горизонтальные половины.
  • Бинарный вертикальный split – две вертикальные половины.
  • Тернарный горизонтальный split – три горизонтальные полосы в пропорции 1:2:1.
  • Тернарный вертикальный split – три вертикальные полосы в пропорции 1:2:1.

Тернарный 1:2:1 – это новая геометрическая идея, которую внёс VVC. Многие границы текстуры в реальном контенте сидят на отметках 1/4 или 3/4 блока, а не на 1/2. Бинарный split ставит границу не туда; тернарный – точно. Тернарный split даёт VVC ещё 3–7% битрейта над чистым бинарным деревом на том же контенте.

Геометрическая гибкость идёт по цене времени. Энкодер VVC должен оценить полную QT-рекурсию и все пять MTT-вариантов и их комбинации. Литература по сокращению сложности показывает, что исчерпывающий поиск разбиения VVC в 5–10 раз медленнее HEVC на том же контенте, и основная часть времени уходит на MTT. Поэтому внедрение VVC идёт медленнее любого современного кодека: энкодер сложно сделать real-time даже на специализированном кремнии.

VVC, как и AV1, разделяет дерево разбиения для luma и chroma в intra-слайсах – функция называется dual tree, и она позволяет chroma использовать большие блоки там, где luma уходит в мелкие. Это ловит ещё 1–2% битрейта на HDR и 10-битном контенте, где chroma естественно более гладкая, чем luma.

КодекГодВерхнеуровневый блокМинимальный блокВарианты разбиенияПримерная сложность энкодера
H.264 / AVC2003macroblock 16×164×44 + вложенные 4 (tree-structured MC)1× (база)
H.265 / HEVC2013CTU 64×648×8 (transform 4×4)чистое квадродерево5–10×
VP92013superblock 64×648×8 (intra 4×4)quadtree + horz/vert4–8×
AV12018superblock 128×1284×410-вариантное дерево15–40×
VVC / H.2662020CTU 128×1284×4QT + бинарные + тернарные (MTT)30–80×

Таблица 1. Дизайн блочного разбиения в современных видеокодеках. Сложность энкодера дана для full-search референсных энкодеров; продакшен-энкодеры (x265, libaom, VTM) сокращают её в 5–50× через early-termination, теряя 1–3% качества.

Почему большие блоки выигрывают на высоком разрешении

Простое правило из теории сжатия: чем больше избыточная область в изображении, тем больший блок может её эффективно описать. До 720p большинство избыточных областей меньше 64×64 пикселей, потому что камера агрессивно сглаживает вход – macroblocks 16×16 ловят основную часть выигрыша. На 1080p 64×64 ловит больше. На 4K один блок 128×128 может описать 5-сантиметровый патч кожи или неба одним вектором движения и почти нулевым остатком.

Конкретное число: бенчмарки NETINT 2024 на 4K 60fps HDR-корпусе показали, что AV1 со superblocks 128×128 выигрывает у AV1, форсированного в 64×64, 4.8% битрейта при равном VMAF – целиком за счёт эффективности больших блоков. Та же сравнительная пара на 1080p SDR даёт только 1.1% разницы, потому что больших избыточных участков меньше.

Следствие: чем выше разрешение и битовая глубина, тем дороже не иметь больших блоков. Поэтому AV2 в черновике на май 2026 года в некоторых конфигурациях расширяет блоки до 256×256 для 8K и высокой частоты кадров. Поэтому же hardware H.264 энкодеры для камер 4K практически исчезли из новых продуктовых линеек – потолок macroblock стоит слишком дорого на современных разрешениях.

Энкодер – это поисковый движок. Цена в практике

Каждая история про блочное разбиение заканчивается в одном месте: энкодер ищет. Чем больше дерево разбиения, тем больше поиск, тем дольше кодирование, тем выше стоимость секунды видео.

Рабочий пример. Энкодер x265 на пресете medium, кодирующий 4K HDR на современном CPU, идёт примерно с 8 кадрами в секунду в реальном времени. Тот же контент с x265 на placebo – самом медленном пресете, который делает почти исчерпывающий поиск разбиения – идёт около 0.4 кадра в секунду, в двадцать раз медленнее, ради дополнительных 4–7% битрейтной эффективности. Тот же контент с libaom-av1 на cpu-used=2 идёт около 0.6 fps; на cpu-used=6 идёт около 30 fps с штрафом 12–18% битрейта.

Компромисс жёсткий и неизбежный: каждый шорткат пресета – это разбиение, которое энкодер не оценил. Шорткат может быть «если RD-стоимость родительского блока низкая, не лезть глубже» или «если предыдущий кадр выбрал тут 32×32, попробуй 32×32 первым и выйди рано, если хватает». Это и есть early termination эвристики, и современные энкодеры ими набиты. Это же – самая активная область академических исследований 2024–2026, где решения о разбиении, управляемые нейросетями, становятся обычным делом в облачных транскодинг-пайплайнах.

Для стримингового продукта практические рекомендации:

  • Для VOD, который кодируется один раз и стримится миллионы раз – берите самый медленный пресет, который вписывается в бюджет. Каждый процент сэкономленного битрейта умножается на зрителей.
  • Для live, который кодируется один раз и смотрится один раз – берите самый быстрый пресет, который держит планку качества. Латентность и CPU доминируют над эффективностью.
  • Для ABR-лесенок (читать дальше) – верхняя ступень лесенки (самое высокое качество, что вы отдаёте) заслуживает более медленного пресета, чем нижняя, потому что зрители верхней ступени потребляют больше всего байт.

Типичная ошибка – форсировать маленькие CTU/superblocks на современном контенте

Удивительное количество продакшен-пайплайнов сознательно ограничивают CTU или superblock 32×32 или 16×16, считая, что это экономит время кодирования. Это работает наоборот. Маленькие верхнеуровневые блоки заставляют энкодер кодировать больше заголовков блоков, больше векторов движения, больше сигнализации разбиения на кадр – а RDO-поиск над плоской структурой из множества маленьких блоков не быстрее глубокого поиска над меньшим числом больших. Результат – штраф 5–10% битрейта при том же качестве без экономии времени кодирования. Если в вашем пайплайне есть флаг --ctu-size 16, проведите аудит. Эта настройка почти всегда живёт там, потому что давно ушедший инженер перенёс её из конфига H.264 эпохи 2010 года и больше не пересматривал предположение.

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

Мы пишем код блочного уровня энкодеров, тюнингуем шорткаты разбиения x264 / x265 / libaom / VPP и поставляем облачные транскодинг-пайплайны с 2005 года – в видеостриминге, OTT и Internet TV, видеоконференциях, e-learning, телемедицине, видеонаблюдении и AR/VR. Команды, которые мы собираем, разбираются и в кремнии – Nvidia NVENC, Intel QSV, NETINT VPU, AMD VCE, кастомные FPGA – и в эвристиках разбиения софтверных энкодеров, лежащих за каждым выбором пресета. Когда клиент просит сократить счёт AWS Elemental на 30% без потери VMAF, ответ почти всегда живёт внутри дерева разбиения.

Ключевое

  • Каждый современный кодек сжимает кадры, разрезая их на прямоугольники и предсказывая каждый отдельно – вопрос только в том, как устроены разбиения.
  • Верхнеуровневый прямоугольник называется macroblock (H.264, 16×16), CTU (HEVC 64×64, VVC 128×128) или superblock (VP9 64×64, AV1 128×128).
  • Большие верхнеуровневые блоки экономят битрейт на высоком разрешении: один вектор движения описывает крупный гладкий патч.
  • AV1 использует 10-вариантное дерево разбиения с T-разбиениями и 4-полосными; VVC использует квадродерево, вложенное в multi-type tree с тернарным split.
  • Поиск разбиения – главный вклад в время кодирования; каждый шорткат пресета – это разбиение, которое энкодер не оценил.
  • Ограничение размера CTU/superblock на современном контенте – штраф 5–10% битрейта без экономии времени; проверьте конфиг на легаси-флаги.

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

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

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