Архитектура гибридного видеокодека

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

TL;DR

Все массовые видеокодеки – от MPEG-2 (1994) до AV1 (2018) и AV2 (2025) – построены по одной и той же внутренней схеме, которую называют блочной гибридной архитектурой. Кодер режет кадр на маленькие блоки, предсказывает каждый блок по уже закодированным соседям или по предыдущим кадрам, вычитает предсказание и оставляет небольшой остаток (residual), а затем преобразует, квантует и кодирует энтропией этот остаток в биты. Декодер выполняет то же предсказание в обратную сторону и прибавляет деквантованный остаток обратно – поэтому внутри кодера всегда сидит полный декодер, чтобы стороны не разъехались. Один раз увидев эту диаграмму, вы будете узнавать её в каждом поколении кодеков последних 35 лет.

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

Если вы строите, покупаете или заказываете видеоинфраструктуру, гибридная архитектура – это та ментальная модель, которая делает все остальные решения понятными. Она объясняет, почему работают bitrate-лестницы, почему CBR и CRF ведут себя по-разному, почему одни потоки лучше справляются с движением, чем другие, и почему железный энкодер стоит столько, сколько стоит. Чтобы воспользоваться этой моделью, не обязательно писать собственный кодек – но именно она нужна, чтобы читать datasheet вендора, оценивать счёт за транскодинг или говорить с инженером-кодеководом, не кивая вежливо на незнакомые слова.

Одна диаграмма, которую нужно запомнить

Блочный гибридный кодек – это архитектура, которая победила. На ней работают H.261, MPEG-1, MPEG-2, H.263, H.264/AVC, H.265/HEVC, H.266/VVC, VP8, VP9, AV1 и пока ещё дорабатываемый AV2. Все стандарты пробовали альтернативные пути – wavelet-кодеки, модельные кодеки, end-to-end нейросетевые кодеки – и каждый раз индустрия возвращалась к одной и той же форме, потому что эту форму трудно обыграть на компромиссе rate-distortion против сложности.

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

Это и есть «гибрид» в слове «гибридный». Предсказание разбирается с корреляцией между сэмплами. Преобразование разбирается с корреляцией, оставшейся внутри остатка. Каждое сжимает то, что у него получается лучше, вместо того чтобы натравливать один инструмент на весь сигнал. Архитектуру называют гибридной с конца 1980-х, когда рабочая группа H.261 в 1988 году утвердила её как рекомендацию.

Рисунок 1. Канонический блок-схема гибридного видеокодера. Каждый кодек от MPEG-2 до AV1 укладывается в эту форму – меняется только содержимое коробок.

Девять стадий, по шагам

Гибридный кодер – это девять стадий подряд, замкнутых обратной связью. Читайте слева направо. Названия стабильны между поколениями; меняется только, насколько хитрó внутри каждой коробки.

Стадия 1 – Разбиение

Кодер получает кадр пикселей – например, 1920×1080 luma-сэмплов плюс две chroma-плоскости – и режет его на прямоугольники, которые называют блоками. MPEG-2 использовал фиксированный 16×16 macroblock. H.264 добавил под-блоки 8×8 и 4×4. HEVC ввёл Coding Tree Unit – корень 64×64, который рекурсивно делится на меньшие квадраты. AV1 использует superblock 128×128, который делится на прямоугольники. Идея одна: крупные блоки на плоских областях, мелкие – на деталях.

Зачем переменный размер? Потому что предсказание работает лучше, когда в блоке одна сущность, а не три. На ресничке 4×4 и на небе 64×64 предсказание получится хорошим; один 16×16 блок, разрезающий обе области, даст плохое. Переменное разбиение позволяет кодеру выбирать локально.

Стадия 2 – Предсказание

Для каждого блока кодер выбирает одну из двух стратегий предсказания. Intra-предсказание синтезирует блок из соседних сэмплов того же кадра: возьмите ряд пикселей сверху, сместите его вниз – и у вас есть догадка для всего, что ниже. Inter-предсказание копирует блок из ранее закодированного кадра и сдвигает его на motion vector: «этот блок выглядит как блок на 7 пикселей правее и 3 пикселя ниже из кадра 40 миллисекунд назад».

Кодер пробует много режимов предсказания, оценивает каждый и оставляет победителя. Современные кодеки имеют 95 intra-режимов (AV1) и десятки inter-режимов с sub-pixel motion vectors. Декодеру сообщается, какой режим выиграл, чтобы он мог воспроизвести то же предсказание.

Стадия 3 – Остаток

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

Большая часть бит в сжатом видеофайле описывает именно остатки, а не предсказания. Типичная H.264-последовательность тратит 60–80 процентов бит на квантованные коэффициенты остатка – в зависимости от битрейта. Чем меньше вы делаете остаток за счёт более точного предсказания, тем меньше тратите бит.

Стадия 4 – Преобразование

Блок остатка прогоняется через математическое преобразование, отображающее пространственные сэмплы в частотные коэффициенты. Самое распространённое – приближение discrete cosine transform (DCT). Преобразование ничего не выбрасывает; оно «поворачивает» остаток так, чтобы энергия сосредоточилась в верхнем-левом углу, где живут низкие частоты. В правом-нижнем углу – высокие частоты – обычно почти нули.

Эта стадия обратима. Зная все коэффициенты точно, можно восстановить остаток точно. Преобразование само по себе не сжимает. Оно переупаковывает.

Стадия 5 – Квантование

Квантование – это то место, где кодек наконец выбрасывает информацию. Каждый коэффициент преобразования делится на шаг квантования и округляется до ближайшего целого. Коэффициент 137, делённый на шаг 8, становится 17. Декодер умножит 17 обратно на 8 и восстановит 136 вместо 137. Ошибка, которую вы только что внесли, постоянна и является источником каждого видимого артефакта сжатия в мире.

Шаг управляется параметром квантования, обычно его называют QP. Низкий QP – маленький шаг – высокое качество – много бит. Высокий QP – большой шаг – низкое качество – мало бит. Все режимы rate-control, которые вы знаете – constant bitrate (CBR), variable bitrate (VBR), constant rate factor (CRF) – это разные политики выбора QP блок за блоком, кадр за кадром.

Стадия 6 – Энтропийное кодирование

После квантования большинство коэффициентов – это нули или маленькие целые числа. Энтропийное кодирование упаковывает это распределение в минимально возможный поток бит, давая короткие коды частым символам и длинные – редким. H.264 ввёл Context-Adaptive Binary Arithmetic Coding (CABAC), который сжимает примерно на 14% плотнее простого кодера в стиле Huffman, который он сменил. AV1 использует multi-symbol arithmetic coder. Принцип тот же: lossless-половина бюджета теории информации.

Энтропийное кодирование обратимо и без потерь. Декодер распакует ровно те символы, которые кодер упаковал.

Стадия 7 – Обратное квантование и обратное преобразование (внутри кодера)

Эта часть удивляет всех, кто впервые смотрит на диаграмму. Кодер запускает декодер в параллель внутри себя. Берёт квантованные коэффициенты, умножает их обратно на шаг (обратное квантование), прогоняет через обратное преобразование и прибавляет результат к предсказанию. Кодер теперь держит восстановленный блок, побитово идентичный тому, что вычислит декодер на принимающей стороне.

Зачем? Потому что следующий блок может захотеть предсказаться от этого восстановленного блока, и если кодер будет предсказывать от оригинальных пикселей, а декодер от восстановленных, стороны разъедутся. Кодер обязан использовать то, что увидит декодер. Этот feedback loop, иногда называемый reconstruction loop или coding loop, и есть то, что не даёт ошибке сжатия накапливаться через тысячи кадров.

Стадия 8 – In-loop фильтрация

У восстановленных блоков по краям видны швы – blocking artifacts – потому что каждый блок квантовался независимо. Deblocking-фильтр сглаживает эти швы. HEVC добавил Sample Adaptive Offset (SAO), который сдвигает значения пикселей, чтобы убрать смещение. AV1 добавил Constrained Directional Enhancement Filter (CDEF) и self-guided Loop Restoration. VVC добавил Adaptive Loop Filter (ALF). Все эти фильтры работают внутри loop – и в кодере, и в декодере – так что следующий кадр предсказывается уже от отфильтрованных пикселей.

In-loop фильтры не делают видео волшебно лучше; они делают опорный кадр, от которого предсказываются будущие кадры, чище – и этот выигрыш накапливается через Group of Pictures (GOP) и снижает общий битрейт при том же качестве примерно на 5–15% в зависимости от контента.

Стадия 9 – Буфер опорных кадров

Отфильтрованные восстановленные кадры попадают в Decoded Picture Buffer – короткую память кодека. Inter-предсказание в будущих кадрах будет тянуться в этот буфер за подходящим блоком. H.264 разрешает до 16 опорных кадров; HEVC и AV1 – аналогично. Буфер ограничен; старые кадры вытесняются.

Буфер плюс стадия предсказания и есть суперсила архитектуры. Сцена «человек говорит на фоне неподвижной стены» нуждается только в битах на движение головы – кадр за кадром, потому что все остальные блоки можно предсказать как «то же самое, что в предыдущем кадре», остаток около нуля.

Конкретный численный пример

Возьмём один 8×8 luma-блок плоского голубого неба. Исходные значения пикселей, после вычитания среднего luma блока, чтобы центрировать вокруг нуля – в основном маленькие числа: пара +2 и −1, вызванные шумом сенсора, остальное нули. Пройдём через loop с округлёнными цифрами.

Исходный остаток (после вычитания intra-предсказания), блок 8×8:

 1  0  0 -1  0  0  1  0
 0  1 -1  0  0  1  0  0
 0  0  1  0 -1  0  0  1
-1  0  0  0  0  0  1  0
 0  0  1  0  0 -1  0  0
 1  0  0 -1  0  0  0  1
 0  1  0  0  1  0 -1  0
 0  0  0  1  0  0  0  0

Сумма квадратов по 64 сэмплам ≈ 21. Средняя энергия на сэмпл ≈ 0,33.

Кодер прогоняет прямое 2-D DCT. Поскольку остаток ведёт себя почти как случайный шум, большинство DCT-коэффициентов малы, но не нули. DC-коэффициент (верхний-левый) примерно равен среднему блока, которое мы вычли, поэтому он около +0,5 после округления. Остальные 63 AC-коэффициента болтаются между +1 и −1.

Теперь квантуем. При QP = 27 типичный шаг квантования для AC-коэффициентов в H.264 – около 14 (отношение Qstep ≈ 2^((QP−4)/6), то есть Qstep(27) ≈ 13,5). Каждый коэффициент около ±1 делится на 14, округляется и становится 0. DC около +0,5 тоже округляется в 0, потому что модуль ниже половины шага идёт в ноль.

Квантованный блок: все 64 значения – 0.

Энтропийное кодирование представляет 64 нуля крошечным End-Of-Block-символом и парой бит знака/режима. Полная стоимость – около 6 бит.

Наивное несжатое кодирование того же 8-bit 8×8 luma-блока обошлось бы в 64 × 8 = 512 бит. Мы сжали его примерно в 85 раз, а на стороне декодера он восстановится как идеально плоский блок – визуально неотличимый от исходника, потому что человеческий глаз всё равно не увидел бы эти sub-quantum вариации.

Теперь представьте тот же блок на детальной траве. Остаток после предсказания далёк от нуля. После DCT энергия размазывается по многим коэффициентам. После квантования при QP = 27 переживут, скажем, 12–20 коэффициентов как ненулевые целые. Энтропийное кодирование потратит около 60–90 бит. Степень сжатия – около 6:1–8:1. Та же архитектура, тот же QP, очень разная стоимость в битах – потому что контент был сложнее.

Поэтому битрейт скачет от кадра к кадру в VBR и поэтому работает per-title encoding: архитектура тратит биты там, где у контента есть биты, на которые их тратить.

Декодер – это кодер минус четыре коробки

Декодер проще кодера. Он не ищет режимы предсказания; ему сказали, какой использовать. Он не выбирает QP; он читает его из bitstream. Он не запускает rate control и motion estimation. Декодер просто разворачивает нижнюю половину loop кодера – entropy decode, dequantize, inverse transform, добавить предсказание, in-loop filter – и пишет результат в тот же Decoded Picture Buffer, что и кодер.

Рисунок 2. Декодер – это нижний путь кодера. Нет mode decision, нет rate control, нет motion estimation. Проще, быстрее, легче поместить в телефон.

Асимметрия – это сознательное решение. Живой кодер может работать в 1× реального времени на серверном GPU или на ASIC NETINT Quadra. Декодер на $20-приставке должен поспевать за тем же потоком. Стандарты осознанно жмут сложность декодера вниз с каждым поколением, а сложность кодера – вверх. Эталонный кодер AV1 примерно в 100 раз медленнее эталонного декодера; эталонный кодер HEVC – примерно в 50 раз. Этот разрыв структурен, а не баг.

Почему все современные кодеки используют одну форму

Блочная гибридная архитектура стала дефолтом, потому что альтернативы проиграли реальные rate-distortion тесты.

Wavelet-кодеки (Motion JPEG 2000, Dirac, SMPTE VC-2) хорошо обращаются с плавными градиентами и избегают blocking-артефактов, но их сценарий motion compensation неудобный – wavelets не выровнены по блокам, и inter-кодирование вынуждено бороться с преобразованием. Wavelet-кодеки выжили в продакшен-нишах (broadcast contribution на очень высоких битрейтах), а не в доставке.

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

End-to-end нейросетевые кодеки заменяют весь pipeline learned autoencoder, часто variational autoencoder с hyperprior entropy coding. Недавние работы (Mentzer и соавторы в Google, Yang и соавторы, Lu и соавторы) выходят на HEVC и даже VVC по PSNR и обходят их по subjective MOS в контролируемых тестах. Они проигрывают по трём практическим осям, важным для деплоя: детерминированность поведения декодера между реализациями, вычислительная цена на существующем железе и предсказуемое поведение на невиденном контенте. Это самое интересное направление в исследовательской литературе – и пока не правдоподобная замена гибридной архитектуре в коммерческом деплое.

Гибридная архитектура за это время прошла путь от 50 Mbps на SD-видео в MPEG-2 до меньше 2 Mbps на 4K HDR в AV1 – примерно 50-кратное улучшение сжатия за 30 лет, а сама диаграмма не сдвинулась. Каждое поколение уточняло содержимое коробок.

Как каждый кодек уточняет коробки

Вот та же диаграмма, четыре раза, через поколения кодеков, с которыми работает большинство индустрии. Форма идентична. Что поменялось?

СтадияMPEG-2 (1994)H.264 / AVC (2003)H.265 / HEVC (2013)AV1 (2018)
РазбиениеФиксированный 16×16 macroblock16×16 macroblock + 8×8, 4×4 sub-blocksCTU 64×64 → quad-tree до 8×8Superblock 128×128 → rect + AB
Intra-predТолько DC (I-frame)9 режимов, 4×4 / 16×1635 режимов, angular56 directional + smooth + Paeth + CfL = 95 режимов
Inter-predHalf-pel, 1 refQuarter-pel, до 16 refs, B-frames как refsQuarter-pel, до 16 refs, weighted predictionEighth-pel, 7 refs, compound, warped motion, OBMC
Преобразование8×8 DCT4×4 / 8×8 integer DCT4×4 … 32×32 DCT + DST4×4 … 64×64 DCT/ADST/flipADST/Identity
КвантованиеЛинейное, частотно-взвешенноеЛинейное, частотно-взвешенноеТо же, с custom matricesЛинейное, широкий диапазон, per-plane
ЭнтропияVLCCAVLC или CABACТолько CABACMulti-symbol arithmetic
In-loop фильтрНетDeblockingDeblocking + SAODeblocking + CDEF + Loop Restoration
Reference buffer1 или 2До 16До 16До 8 (гибкое управление)
Битрейт, 1080p30 типично8–15 Mbps3–5 Mbps1,5–3 Mbps0,8–1,6 Mbps

Закономерность одинаковая. Каждое поколение добавляет более тонкое разбиение, больше режимов предсказания, больше вариантов преобразования, умнее in-loop фильтры и богаче entropy contexts. Сложность декодера растёт линейно с этими добавлениями. Сложность кодера растёт намного быстрее, потому что mode decision должен искать в большем пространстве. Битрейт при одинаковом качестве примерно вдвое снижается каждые 7–10 лет.

Рисунок 3. Форма не сдвинулась. Содержимое коробок стало богаче.

Секрет кодера: rate-distortion optimization

Мы описали архитектуру, но не сказали, как кодер на самом деле выбирает, какой режим предсказания, какой размер блока, какое преобразование и какой QP взять. Механизм называется Rate-Distortion Optimization (RDO), и именно там современные кодеры тратят большую часть своего CPU.

Для каждого блока кодер перебирает много комбинаций выборов. Для каждого кандидата он оценивает стоимость в битах (rate, R) и потерю качества в какой-то метрике искажений (distortion, D), а затем считает Лагранжев функционал:

J = D + λ · R

Здесь λ (lambda) – множитель Лагранжа, который кодер подбирает по целевому QP. Низкий QP → маленький λ → distortion доминирует → кодер выбирает дорогие, но качественные режимы. Высокий QP → большой λ → доминируют биты → кодер выбирает дешёвые режимы.

Типичный H.264-кодер оценивает 50–200 кандидатов режимов на 16×16 macroblock; HEVC-кодер – 500–2 000 на 64×64 CTU; AV1-кодер – 5 000–50 000 на 128×128 superblock. Большая часть времени работы кодера уходит на этот поиск. Поэтому софтовый AV1-кодер на cpu-used=0 libaom выходит в ~0,01× реального времени на быстром CPU, а ffmpeg SVT-AV1 preset 13 – в 1 000 раз быстрее, но на 30–50% хуже по битрейту при том же качестве.

Смысл гибридной архитектуры с инженерной точки зрения в том, что она задаёт чёткое пространство поиска, где каждый инструмент ведёт себя предсказуемо. Эвристики можно менять, тюнить под тип контента, ускорять на GPU или ASIC – и при этом получать стандарт-совместимый bitstream, который воспроизведёт любой декодер.

Частая ошибка: путать архитектуру со стандартом

Диаграмма выше – это архитектура. Стандарт – H.264, H.265, AV1 – это bitstream syntax, который обязан принимать любой совместимый декодер. Из этого следуют две вещи.

Первое: стандарт не говорит, как строить кодер. H.264 описывает, как выглядит bitstream; он не описывает, как кодер должен выбирать режимы. Поэтому два H.264-кодера (x264, OpenH264, Apple VideoToolbox, NVIDIA NVENC) дают очень разные файлы для одного и того же входа на одном и том же target bitrate, хотя все они «H.264». Внутри у них одна и та же гибридная архитектура; политика внутри коробок разная.

Второе: можно выпустить новый кодер под старый стандарт и всё равно получить выигрыш. x264 в 2026 на 20% эффективнее по битрейту при том же качестве, чем x264 в 2014, без каких-либо изменений в спецификации H.264. Кодер просто научился использовать инструменты стандарта умнее. По той же причине ffmpeg libsvtav1 ощутимо прибавил в эффективности между 2022 и 2025 – только за счёт улучшений mode decision, без нового стандарта.

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

Мы строим видео-пайплайны для video streaming, OTT, video surveillance, video conferencing, e-learning и telemedicine. В каждой из этих вертикалей именно архитектурное понимание того, как работают кодеки, определяет ваш счёт, вашу задержку и ваше качество. Мы выбираем кодеки и тюним пресеты под контент (для conferencing – низкая задержка и низкая сложность; для OTT – multi-pass высокой эффективности) и опираемся на hardware acceleration, когда стоимость кодера иначе сжирала бы unit-экономику. Surveillance особенно выигрывает от intra-refresh внутри гибридного loop – той же техники, которой conferencing пользуется, чтобы восстанавливаться после packet loss.

Порядок чтения остального Блока 4

Эта статья – карта. Остальные статьи Блока 4 заходят внутрь отдельных коробок:

Можно читать в любом порядке, если диаграмма из этой статьи уже у вас в голове.

Ключевые тезисы

  • Одна блочная гибридная диаграмма описывает каждый массовый кодек от MPEG-2 до AV1 и AV2.
  • Предсказание убирает корреляцию между сэмплами; преобразование убирает корреляцию внутри остатка.
  • Квантование – единственная стадия, где информация на самом деле выбрасывается.
  • Кодер запускает полный декодер у себя внутри, чтобы восстановленные пиксели сходились с тем, что увидит приёмник.
  • Каждое поколение кодеков уточняет содержимое девяти коробок; сами коробки не двигаются.
  • Большая часть CPU кодера уходит в rate-distortion поиск; стандарт этот поиск не диктует.

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

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

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