Содержание статьи +
- TL;DR
- Зачем это знать
- Одна диаграмма, которую стоит запомнить
- Девять стадий по шагам
- Конкретный численный пример
- Декодер – это кодер без четырёх блоков
- Почему все современные кодеки используют одну и ту же форму
- Как каждый кодек уточняет параметры коробки
- Секрет кодера: оптимизация соотношения скорости и искажений
- Частая ошибка: путать архитектуру со стандартом
- Где здесь Фора Софт
- Порядок чтения остального Блока 4
- Ключевые тезисы
- Что почитать дальше
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. Все стандарты пробовали альтернативные подходы – кодеки на основе вейвлетов, модельные кодеки, end-to-end нейросетевые кодеки – но каждый раз индустрия возвращалась к этой же архитектуре, поскольку её трудно превзойти по соотношению rate-distortion и сложности реализации.
В этой форме объединены две идеи. Первая – предсказание: большую часть кадра можно восстановить по уже известным пикселям – либо внутри того же кадра (например, стена рядом с дверным проёмом выглядит так же, как уже нарисованная стена), либо в предыдущем кадре (лицо сместилось на три пикселя влево, но само по себе осталось прежним). Вторая – преобразование: всё, что не удалось предсказать, называется остатком. На небольшом блоке пикселей энергия этого остатка сосредоточена в нескольких низкочастотных коэффициентах. Тогда те коэффициенты, которые глаз заметит с меньшей вероятностью, можно отбросить.
Это и есть «гибрид» в слове «гибридный». Предсказание учитывает корреляцию между сэмплами. Преобразование работает с корреляцией, оставшейся в остатке. Каждый из методов эффективно сжимает ту часть сигнала, с которой он справляется лучше всего, вместо того чтобы использовать один инструмент для обработки всего сигнала. Архитектуру называют гибридной с конца 1980-х годов – именно тогда рабочая группа H.261 в 1988 году утвердила её как рекомендацию.
Девять стадий по шагам
Гибридный кодер состоит из девяти последовательных стадий, соединённых обратной связью. Читайте слева направо. Названия стадий остаются неизменными от поколения к поколению; меняется лишь сложность реализации внутри каждой из них.
Стадия 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 – Преобразование
Блок остатка проходит через математическое преобразование, которое переводит пространственные сэмплы в частотные коэффициенты. Наиболее распространённый метод – приближение дискретного косинусного преобразования (DCT). Это преобразование ничего не теряет: оно «поворачивает» остаток так, чтобы энергия сконцентрировалась в левом верхнем углу, где находятся низкие частоты. В правом нижнем углу – высокие частоты – обычно почти нули.
Эта стадия обратима. Зная все коэффициенты точно, можно восстановить остаток без потерь. Само преобразование не сжимает данные – оно лишь переупаковывает их.
Стадия 5 – Квантование
Квантование – это этап, на котором кодек окончательно отбрасывает информацию. Каждый коэффициент преобразования делится на шаг квантования и округляется до ближайшего целого числа. Например, коэффициент 137 при делении на шаг 8 становится 17. Декодер умножит 17 обратно на 8 и восстановит 136 вместо 137. Ошибка, которую вы только что внесли, постоянна и является источником каждого видимого артефакта сжатия в мире.
Шаг управляется параметром квантования, который обычно называют QP. Низкий QP – маленький шаг – высокое качество – много бит. Высокий QP – большой шаг – низкое качество – мало бит. Все режимы управления битрейтом, с которыми вы знакомы – constant bitrate (CBR), variable bitrate (VBR), constant rate factor (CRF) – представляют собой различные стратегии выбора QP для каждого блока и каждого кадра.
Стадия 6 – Энтропийное кодирование
После квантования большинство коэффициентов – нули или небольшие целые числа. Энтропийное кодирование упаковывает такое распределение в минимально возможный битовый поток, выделяя короткие коды частым символам и длинные – редким. H.264 ввёл Context-Adaptive Binary Arithmetic Coding (CABAC), который сжимает данные примерно на 14% эффективнее простого кодера в стиле Хаффмана, заменившего его. AV1 использует многосимвольный арифметический кодировщик. Принцип остаётся тем же: это lossless-половина теоретико-информационного бюджета.
Энтропийное кодирование обратимо и не приводит к потерям. Декодер восстановит ровно те символы, которые были закодированы кодером.
Стадия 7 – Обратное квантование и обратное преобразование (внутри кодера)
Эта часть удивляет всех, кто впервые видит диаграмму. Кодер запускает декодер параллельно внутри себя: берёт квантованные коэффициенты, умножает их обратно на шаг (обратное квантование), пропускает через обратное преобразование и прибавляет результат к предсказанию. Теперь кодер обладает восстановленным блоком, побитово идентичным тому, что получит декодер на приёмной стороне.
Зачем? Потому что следующий блок может захотеть предсказать текущий на основе этого восстановленного блока, и если кодер будет опираться на оригинальные пиксели, а декодер – на восстановленные, их данные начнут расходиться. Кодер обязан использовать то, что увидит декодер. Этот обратный цикл, иногда называемый reconstruction loop или coding loop, и есть то, что не даёт ошибке сжатия накапливаться на протяжении тысяч кадров.
Стадия 8 – Фильтрация в цикле
У восстановленных блоков по краям видны швы – blocking artifacts – потому что каждый блок квантован независимо. Deblocking-фильтр сглаживает эти швы. HEVC добавил Sample Adaptive Offset (SAO), который корректирует значения пикселей, устраняя смещение. AV1 внедрил Constrained Directional Enhancement Filter (CDEF) и self-guided Loop Restoration. VVC добавил Adaptive Loop Filter (ALF). Все эти фильтры работают внутри цикла обработки – как в кодере, так и в декодере – поэтому следующий кадр предсказывается уже на основе отфильтрованных пикселей.
In-loop фильтры не делают видео волшебно лучше: они улучшают опорный кадр, от которого предсказываются последующие кадры, – и этот выигрыш накапливается в группе кадров (GOP), снижая общий битрейт при том же качестве примерно на 5–15% в зависимости от контента.
Стадия 9 – Буфер опорных кадров
Отфильтрованные восстановленные кадры поступают в Decoded Picture Buffer – кратковременную память кодека. При интерпредсказании в последующих кадрах система обращается к этому буферу в поисках подходящего блока. H.264 поддерживает до 16 опорных кадров; HEVC и AV1 – аналогично. Объём буфера ограничен, поэтому старые кадры вытесняются.
Буфер плюс стадия предсказания – вот суперсила архитектуры. Сцена «человек говорит на фоне неподвижной стены» требует битов только на движение головы – кадр за кадром, потому что все остальные блоки можно предсказать как «то же самое, что в предыдущем кадре», остаток около нуля.
Конкретный численный пример
Возьмём 8×8 luma-блок с плоским голубым небом. Исходные значения пикселей, после вычитания среднего luma блока для центрирования вокруг нуля – в основном небольшие числа: пара +2 и −1, вызванные шумом сенсора, остальное – нули. Пройдём через цикл с округлёнными значениями.
Остаток после вычитания 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.
Кодер выполняет прямое двумерное 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-битного 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. Ему не требуется выполнять управление битрейтом и оценку движения. Декодер просто выполняет нижнюю часть цикла кодера: энтропийное декодирование, декомпрессию, обратное преобразование, добавление предсказания и фильтрацию в цикле – и записывает результат в тот же буфер декодированных кадров, что и кодер.
Асимметрия – это осознанное решение. Живой кодер может работать в реальном времени на серверном GPU или на ASIC NETINT Quadra. Декодер на приставке за 20 долларов должен успевать за тем же потоком. С каждым поколением стандарты намеренно снижают сложность декодера, а сложность кодера – повышают. Эталонный кодер AV1 примерно в 100 раз медленнее эталонного декодера, а эталонный кодер HEVC – примерно в 50 раз. Этот разрыв – не ошибка, а закономерность.
Почему все современные кодеки используют одну и ту же форму
Блочная гибридная архитектура стала стандартной, поскольку альтернативы проиграли реальные тесты rate-distortion.
Wavelet-кодеки (Motion JPEG 2000, Dirac, SMPTE VC-2) хорошо справляются с плавными градиентами и не вызывают blocking-артефактов, но их подход к компенсации движения неудобен – вейвлеты не выровнены по блокам, и интер-кодирование вынуждено работать с преобразованием. Wavelet-кодеки нашли применение в узкоспециализированных задачах (например, в вещательной передаче на очень высоких битрейтах), но не при доставке контента.
Модельные кодеки описывают сцену как набор объектов с параметрами: модель головы, модель освещения, модель позы тела. На крайне низких битрейтах они превосходят гибридные кодеки в видеозвонках. Вне этой области они быстро теряют эффективность, как только в сцене появляется что-то, на что модель не была обучена.
End-to-end нейросетевые кодеки заменяют весь традиционный pipeline на learned autoencoder, часто на основе вариационного автоэнкодера с hyperprior-энтропийным кодированием. Недавние работы (Mentzer и соавторы в Google, Yang и соавторы, Lu и соавторы) достигают уровня HEVC и даже VVC по PSNR и превосходят их по субъективному MOS в контролируемых тестах. Однако они уступают по трём важным практическим аспектам, критичным для внедрения: детерминированности поведения декодера между различными реализациями, вычислительной эффективности на существующем оборудовании и предсказуемости работы на незнакомом контенте. Это – одно из самых перспективных направлений в научной литературе, но пока маловероятная замена гибридной архитектуре в коммерческих продуктах.
Гибридная архитектура за это время прошла путь от 50 Мбит/с на SD-видео в формате MPEG-2 до менее чем 2 Мбит/с на 4K HDR в AV1 – примерно 50-кратное улучшение сжатия за 30 лет, при этом сама диаграмма осталась неизменной. Каждое поколение уточняло содержимое блоков.
Как каждый кодек уточняет параметры коробки
Вот та же диаграмма – четыре раза, через поколения кодеков, с которыми работает большая часть индустрии. Форма осталась идентичной. Что изменилось?
| Стадия | MPEG-2 (1994) | H.264 / AVC (2003) | H.265 / HEVC (2013) | AV1 (2018) |
|---|---|---|---|---|
| Разбиение | Фиксированный 16×16 macroblock | 16×16 macroblock + 8×8, 4×4 sub-blocks | CTU 64×64 → quad-tree до 8×8 | Superblock 128×128 → rect + AB |
| Intra-pred | Только DC (I-frame) | 9 режимов, 4×4 / 16×16 | 35 режимов, angular | 56 directional + smooth + Paeth + CfL = 95 режимов |
| Inter-pred | Half-pel, 1 ref | Quarter-pel, до 16 refs, B-frames как refs | Quarter-pel, до 16 refs, weighted prediction | Eighth-pel, 7 refs, compound, warped motion, OBMC |
| Преобразование | 8×8 DCT | 4×4 / 8×8 integer DCT | 4×4 … 32×32 DCT + DST | 4×4 … 64×64 DCT/ADST/flipADST/Identity |
| Квантование | Линейное, частотно-взвешенное | Линейное, частотно-взвешенное | То же, с custom matrices | Линейное, широкий диапазон, per-plane |
| Энтропия | VLC | CAVLC или CABAC | Только CABAC | Multi-symbol arithmetic |
| In-loop фильтр | Нет | Deblocking | Deblocking + SAO | Deblocking + CDEF + Loop Restoration |
| Reference buffer | 1 или 2 | До 16 | До 16 | До 8 (гибкое управление) |
| Битрейт, 1080p30 типично | 8–15 Mbps | 3–5 Mbps | 1,5–3 Mbps | 0,8–1,6 Mbps |
Закономерность одинакова: каждое поколение добавляет более тонкое разбиение, больше режимов предсказания, больше вариантов преобразования, умные in-loop фильтры и более богатые entropy contexts. Сложность декодера растёт линейно с этими улучшениями. Сложность кодера растёт значительно быстрее, поскольку принятие решения о режиме требует перебора всё большего пространства вариантов. При одинаковом качестве битрейт примерно вдвое снижается каждые 7–10 лет.
Секрет кодера: оптимизация соотношения скорости и искажений
Мы описали архитектуру, но не объяснили, как кодер на самом деле выбирает режим предсказания, размер блока, тип преобразования и значение QP. Этот механизм называется Rate-Distortion Optimization (RDO), и именно здесь современные кодеры тратят большую часть вычислительных ресурсов CPU.
Для каждого блока кодер перебирает множество комбинаций вариантов. Для каждого кандидата он оценивает стоимость в битах (rate, R) и потерю качества по некоторой метрике искажений (distortion, D), после чего вычисляет Лагранжев функционал:
J = D + λ · RЗдесь λ (lambda) – множитель Лагранжа, который кодер подбирает в зависимости от целевого QP. Низкий QP → малый λ → доминирует искажение → кодер выбирает дорогие, но качественные режимы. Высокий QP → большой λ → доминируют биты → кодер выбирает дешёвые режимы.
Типичный H.264-кодер оценивает 50–200 кандидатов режимов на 16×16 макроблоке; HEVC-кодер – 500–2000 на 64×64 CTU; AV1-кодер – 5000–50 000 на 128×128 суперблоке. Большая часть времени кодера уходит на этот поиск. Поэтому софтовый AV1-кодер libaom при cpu-used=0 работает примерно в 0,01× от реального времени даже на быстром CPU, а ffmpeg с SVT-AV1 при пресете 13 – в 1000 раз быстрее, но требует на 30–50% больше битрейта при том же качестве.
Смысл гибридной архитектуры с инженерной точки зрения – в том, что она задаёт чёткое пространство поиска, в котором каждый инструмент ведёт себя предсказуемо. Эвристики можно настраивать, оптимизировать под тип контента, ускорять на GPU или ASIC – и при этом получать стандартно совместимый bitstream, который сможет воспроизвести любой декодер.
Частая ошибка: путать архитектуру со стандартом
Диаграмма выше – это архитектура. Стандарт – H.264, H.265, AV1 – представляет собой bitstream syntax, который обязан поддерживать любой совместимый декодер. Из этого вытекают две вещи.
Первое: стандарт не определяет, как должен быть устроен кодер. H.264 описывает структуру bitstream, но не указывает, как кодеру выбирать режимы кодирования. Поэтому два H.264-кодера – например, x264, OpenH264, Apple VideoToolbox, NVIDIA NVENC – при одинаковом входном материале и целевом битрейте генерируют сильно отличающиеся файлы, хотя все они соответствуют стандарту H.264. У всех них общая гибридная архитектура, но алгоритмы принятия решений внутри – разные.
Второе: можно выпустить новый кодер под старый стандарт и всё равно получить выигрыш. x264 в 2026 году на 20 % эффективнее по битрейту при том же качестве, чем x264 в 2014 году, – без каких-либо изменений в спецификации H.264. Кодер просто стал умнее использовать инструменты стандарта. По той же причине ffmpeg libsvtav1 заметно прибавил в эффективности между 2022 и 2025 годами – исключительно за счёт улучшений в mode decision, без появления нового стандарта.
Где здесь Фора Софт
Мы разрабатываем видео-пайплайны для видеостриминга, OTT, видеонаблюдения, видеоконференций, электронного обучения и телемедицины. В каждой из этих областей именно архитектурное понимание работы кодеков определяет качество, задержку и стоимость решения. Мы подбираем кодеки и настраиваем пресеты под тип контента: для видеоконференций – минимальная задержка и низкая вычислительная сложность, для OTT – многократный проход с высокой эффективностью сжатия. При этом активно используем аппаратное ускорение, иначе стоимость кодирования разрушила бы unit-экономику. Особенно выгодно видеонаблюдение использует intra-обновление в рамках гибридного цикла – ту же технологию, что и видеоконференции применяют для восстановления после потерь пакетов.
Порядок чтения остального Блока 4
Эта статья – карта. Остальные статьи Блока 4 углубляются в содержание отдельных коробок:
- Intra-frame coding – стадия предсказания, когда предыдущего кадра нет.
- Inter-frame coding и motion estimation – стадия предсказания, когда он есть.
- GOP-структура: I, P, B-кадры, open/closed GOP – как организован буфер опорных кадров во времени.
- Block-based prediction: MB, CTU, SB и superblocks – детальный взгляд на стадию разбиения.
- Transform coding и Quantization – две стадии, на которых происходит реальное lossy-сжатие.
- Entropy coding в деталях – финальная lossless-упаковка.
- In-loop filtering – постобработка после реконструкции.
- Mode decision и RDO и Rate control – уровень политики над архитектурой.
Можно читать в любом порядке, если диаграмма из этой статьи уже у вас перед глазами.
Ключевые тезисы
- Одна блочная гибридная диаграмма описывает каждый массовый кодек – от MPEG-2 до AV1 и AV2.
- Предсказание устраняет корреляцию между сэмплами; преобразование – внутри остатка.
- Квантование – единственная стадия, на которой информация действительно теряется.
- Кодер запускает полный декодер внутри себя, чтобы восстановленные пиксели совпадали с теми, что увидит приёмник.
- Каждое поколение кодеков уточняет содержимое девяти блоков; сами блоки остаются неизменными.
- Большая часть ресурсов CPU кодера уходит на поиск оптимального соотношения скорости и искажений; стандарт этот процесс не регламентирует.