Внутрикадровое кодирование: как сжимается один кадр

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

TL;DR

Внутрикадровое кодирование (intra-frame coding) – это та часть видеокодека, которая сжимает один кадр, используя только пиксели внутри этого же кадра, без обращения к прошлым или будущим. Все кодеки от MPEG-2 до AV2 используют один и тот же пятистадийный рецепт: разделить кадр на блоки, предсказать каждый блок из уже закодированных соседей, вычесть прогноз – получится остаток (residual), преобразовать его в частотные коэффициенты, квантовать и пропустить через энтропийное кодирование. Рецепт не меняется от поколения к поколению – меняется только число режимов предсказания (от 9 в H.264 до ~95 в AV1 и набора data-driven режимов в AV2) и качество упаковки остатка. Если вы понимаете intra-frame coding, вы понимаете JPEG, каждый keyframe в каждом видеопотоке, который вы когда-либо смотрели, и каждый all-intra мастер-кодек в постпродакшене.

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

Внутрикадровое кодирование – фундамент любого adaptive-bitrate-стрима, любого видеофайла и любого all-intra production workflow, от которого вы зависите. Keyframe interval в OBS или в транскодере вашего CDN, размер HLS- и DASH-сегментов, цена мастеринга 4K HDR в ProRes, скорость перемотки YouTube-видео – всё это прямые последствия выбора параметров intra coding. Продакт-менеджеры, которые без перевода в голове читают datasheet с упоминанием «intra prediction modes», «angular modes» или «all-intra profile», принимают лучшие решения по стоимости, латентности и качеству. Эту ментальную модель можно собрать за полчаса, и она экономит годы запутанных разговоров с инженерами.

Что значит «intra» и зачем оно нужно

Слово intra – латинское «внутри». Внутрикадровое кодирование сжимает видеокадр, используя только информацию внутри этого же кадра. Противоположность – межкадровое кодирование (inter-frame), которое сжимает кадр со ссылкой на другие кадры. Каждый видеопоток использует оба, но intra-кодированные кадры – обычно их называют I-кадрами или keyframes – это якоря потока. Они декодируются сами по себе. Inter-кодированные кадры – нет.

I-кадры нужны по четырём причинам, ни одна из которых не связана с эффективностью сжатия.

Во-первых, воспроизведение должно с чего-то начаться. Когда вы открываете видео, плееру нужен хотя бы один полностью декодируемый кадр, чтобы было от чего предсказывать следующие. Этот первый кадр обязан быть intra-кодированным.

Во-вторых, adaptive streaming зависит от точек переключения. В HLS и DASH плеер переключается между битрейт-лестницей на границах сегментов – обычно каждые 2–6 секунд. Каждый сегмент обязан начинаться с I-кадра, потому что должен декодироваться без предыдущего.

В-третьих, восстановление после ошибок требует «сброса». Если сетевой пакет потерян или повреждён в live-стриме, все последующие inter-кадры неверны до прихода следующего intra-кадра. Без периодических I-кадров глитч длится вечно.

В-четвёртых, редакторам нужны frame-accurate-склейки. Резать видео по inter-кодированному кадру означает перекодировать всё от предыдущего I-кадра. Production-кодеки – Apple ProRes, Avid DNx (ранее DNxHD/DNxHR), Sony XAVC-I – кодируют каждый кадр как intra именно по этой причине. Любой кадр декодируется самостоятельно; резать можно где угодно.

Так что intra coding – это не просто один инструмент внутри видеокодека. Это полный кодек неподвижного изображения, который сидит внутри каждого видеокодека, и одновременно полный кодек нескольких профессиональных форматов. JPEG, JPEG 2000 и HEIF используют ту же машинерию без «видео»-обёртки.

Пять стадий по порядку

Внутрикадровое кодирование – это пять последовательных стадий без петель и обратной связи. Читаем слева направо.

Рисунок 1. Пайплайн intra-frame coding. Каждый кодек неподвижного изображения и каждый видеоkeyframe проходит через эти пять стадий именно в таком порядке.

Стадия 1 – Разбиение на блоки (partitioning)

Энкодер получает один кадр – для видео 1080p это сетка 1920 × 1080 luma-сэмплов плюс две chroma-плоскости – и разрезает его на прямоугольные блоки. Размер блока не фиксирован. Гладкие области вроде синего неба получают большие блоки. Детальные области вроде ресницы – маленькие.

Конкретные размеры блоков зависят от кодека. JPEG использует фиксированные 8×8. MPEG-2 – макроблоки 16×16. H.264 делит макроблок 16×16 вплоть до 4×4. H.265/HEVC использует quad-tree от 64×64 до 4×4. AV1 стартует с superblock 128×128, который дробится до 4×4. H.266/VVC использует coding tree unit 128×128 с ещё более гибкими разбиениями, включая ternary и binary splits, до 4×4.

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

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

Это сердце intra coding и стадия, которая больше всего изменилась между поколениями кодеков. Для каждого блока энкодер смотрит на пиксели прямо сверху и прямо слева – пиксели, уже закодированные ранее в том же кадре – и использует их, чтобы предсказать, как выглядит текущий блок.

Предсказание – это догадка. Догадка редко идеальна, но обычно близка к реальности, потому что соседние пиксели в настоящей фотографии сильно скоррелированы. Если ряд пикселей сверху показывает верхнюю часть деревянной двери, сам блок тоже, скорее всего, часть этой двери.

У энкодера много способов предсказывать – много режимов – и он пробует все. Самые простые:

  • DC mode: заполнить блок средним значением пикселей по верхней и левой границам. Полезен на ровных поверхностях.
  • Planar mode: проложить гладкую плоскость через граничные пиксели. Полезен на мягких градиентах вроде неба или щеки при мягком свете.
  • Angular modes (направленные): копировать линию пикселей с верхней или левой границы вдоль определённого направления. Полезны для рёбер и текстур с явной ориентацией.

Представьте фото с наклонной крышей. Крыша идёт из нижнего левого угла в верхний правый под углом, скажем, 30 градусов. Angular mode на 30 градусов берёт пиксели верхней левой границы блока и сдвигает их вниз вдоль этой линии. Получается почти идеальное предсказание крыши внутри блока.

Число доступных режимов росло с каждым поколением. Прогресс рассказывает историю:

КодекГодIntra-режимы (luma)
JPEG1992нет (DC predictor только на DC-коэффициенте)
MPEG-21994только DC
H.264 / AVC20039 (DC + Planar + 7 angular для блоков 4×4)
H.265 / HEVC201335 (DC + Planar + 33 angular)
VP9201310 (DC + TM/Paeth-like + 8 angular)
AV12018~95 (8 номинальных углов × 6 дельт + DC + Smooth-V/H/Bi + Paeth + recursive + CfL для chroma + palette + intra block copy)
H.266 / VVC202067 (DC + Planar + 65 angular) + MIP + MRL + ISP + CCLM + PDPC
AV2 (AVM, разрабатывается)2025весь набор AV1 + data-driven обученные режимы + улучшенный CfL + multi-reference line

Источники для таблицы: спецификации ITU-T H.264, H.265, H.266; спецификация AOMedia AV1 и Tool Description; черновики AV2 AVM (2025).

Читатель, видевший статью про архитектуру, узнает: intra prediction – это стадия predict гибридного кодека, ограниченная ссылками внутри текущего кадра. Inter-coding – та же стадия со ссылками на прошлые кадры.

Стадия 3 – Residual: вычесть прогноз

После того как энкодер выбрал лучший режим предсказания для блока, он вычитает предсказанный блок из оригинального, сэмпл за сэмплом. Результат – блок разностей, остаток (residual).

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

Зачем уменьшать энергию? Потому что каждая следующая стадия сжимает маленькие числа эффективнее, чем большие. Квантование округлит маленькие числа в ноль. Энтропийный кодер даст короткие коды частым значениям, а ими теперь в основном являются нули и маленькие целые числа. Весь пайплайн настроен на остаток, прижатый к нулю.

Стадия 4 – Transform: пространство в частоту

Остаток пропускается через математическое преобразование, которое превращает блок пиксельных разностей в блок частотных коэффициентов. Самое распространённое – целочисленная аппроксимация discrete cosine transform, сокращённо DCT.

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

Само по себе преобразование не сжимает. Оно переупорядочивает. Если знать каждый коэффициент точно, остаток можно восстановить точно.

Современные кодеки включают несколько вариантов преобразования, потому что одно не подходит всем блокам. AV1 выбирает между DCT, ADST (asymmetric discrete sine transform), flipped ADST и identity transform для каждого блока. У VVC есть multiple transform selection (MTS) и low-frequency non-separable transform (LFNST) для дополнительного выжимания. AV2 снова расширяет меню. Энкодер пробует каждое и выбирает то, что даёт минимальный выход.

Стадия 5 – Quantization, потом entropy coding

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

Шаг управляется quantization parameter, или QP. Низкий QP означает маленький шаг, высокое качество, много бит. Высокий QP – большой шаг, низкое качество, мало бит. После квантования большинство коэффициентов – нули, а немногие ненулевые – маленькие целые числа: ровно та форма, которую энтропийное кодирование сжимает лучше всего.

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

Это intra coding от начала до конца. Пять стадий, без петель, без зависимостей от будущих кадров, без motion estimation. JPEG реализует стадии 1, 4 и 5. Современные видеокодеки добавляют стадии 2 и 3. Всё остальное – inter-prediction, GOP-структура, rate control – сидит сверху.

Числовой пример: один блок 4×4

Возьмём один luma-блок 4×4 из угла слегка текстурированной стены. Оригинальные значения сэмплов (после вычитания 128 для центрирования вокруг нуля):

 24  22  20  18
 26  24  22  20
 28  26  24  22
 30  28  26  24

Значения растут из правого верхнего угла в левый нижний – гладкий градиент. Классический angular-паттерн – идеален для angular intra mode.

Шаг 1 – Predict. Энкодер выбирает angular mode, указывающий вдоль направления градиента (45 градусов, копирование из левого верхнего угла). Предсказанный блок:

 24  22  20  18
 26  24  22  20
 28  26  24  22
 30  28  26  24

В этом искусственном примере прогноз идеален, потому что блок построен из идеального градиента. Энкодер сигнализирует «mode = angular at 45 degrees» – это стоит 4–6 бит overhead.

Шаг 2 – Residual. Оригинал минус прогноз:

 0  0  0  0
 0  0  0  0
 0  0  0  0
 0  0  0  0

Все нули. Сумма квадратов остатка: 0.

Шаг 3 – Transform. DCT нулевого блока – нулевой блок коэффициентов. Ноль на входе, ноль на выходе.

Шаг 4 – Quantize. Ноль делёный на любой шаг – ноль. Ненулевых квантованных коэффициентов нет.

Шаг 5 – Entropy code. Энкодер записывает «mode = 45-degree angular» плюс сигнал «end of block», что означает «дальше ненулевых коэффициентов нет». Итоговая цена блока: около 6 бит.

Это полное сжатие одного блока 4×4 – 16 сэмплов × 8 бит = 128 бит – до 6 бит. Степень сжатия 21×. Сжатие пришло от предсказания. Настоящие фотографии беспорядочнее, и остаток редко нулевой, но принцип сохраняется: большая часть выигрыша в intra coding приходит от предсказания, а не от преобразования.

Теперь представим, что блок был более шумным участком стены, где прогноз промахивается на ±2 на сэмпл. Остаток содержал бы ненулевые элементы около ±2. После DCT энергия размазалась бы по нескольким низкочастотным коэффициентам. После квантования при QP = 20 (шаг ≈ 10) большинство коэффициентов округлились бы в ноль, и выжило бы один–два коэффициента ±1. Блок обошёлся бы в 25–40 бит – всё ещё большое сжатие с небольшой ошибкой реконструкции от квантования.

Внутри зоопарка предсказания

Самая активная зона инноваций intra coding – стадия предсказания. Ниже экскурсия по основным инструментам, с одной-двумя фразами на каждый. Запоминать не обязательно – но если datasheet кодека упомянет один из них, вы узнаете семью.

DC mode – заполнить блок средним значением граничных сэмплов. Самый старый режим; есть в каждом кодеке.

Planar mode – проложить гладкую плоскость через граничные сэмплы. Отлично для мягких градиентов вроде лица при свете из окна.

Angular modes – копировать граничные сэмплы вдоль определённого направления. У H.264 – 8 углов. У HEVC – 33. У VVC – 65. У AV1 – 56 (8 номинальных × 7 дельт).

Paeth predictor – для каждого предсказываемого пикселя выбирается тот из трёх референсных сэмплов (сверху, слева, верхний левый), который ближе всего к линейной экстраполяции. Изначально из PNG, принят VP9 и AV1.

Smooth modes – AV1 включает Smooth, Smooth-Horizontal и Smooth-Vertical, интерполирующие из углов и краёв. Отлично для мягких градиентов.

Recursive intra prediction – AV1 делит блок на под-блоки 2×2 и предсказывает каждый из предыдущего маленьким фильтром. Полезно на шумных текстурах.

Cross-component linear model (CCLM) – VVC предсказывает chroma-блок как линейную функцию реконструированного luma-блока в той же позиции. Параметры выводятся из соседних граничных сэмплов. Экономит около 14% битрейта на chroma в all-intra-кодировании.

Chroma from luma (CfL) – эквивалент CCLM в AV1. Использует subsampled luma для предсказания chroma.

Matrix-based intra prediction (MIP) – VVC включает набор небольших data-driven prediction matrices, обученных на тренировочных данных. Энкодер выбирает лучшую матрицу и применяет её к граничным сэмплам. Полезно на паттернах, которые не вписываются ни в один rule-based-режим.

Multiple reference line (MRL) – VVC и AV2 разрешают предсказывать от reference line на 2 или 3 сэмпла отстоящей от границы блока, а не от непосредственного соседа. Полезно, когда непосредственный сосед испорчен шумом квантования.

Intra subpartition (ISP) – VVC делит coding-блок на вертикальные или горизонтальные полосы и предсказывает каждую от предыдущей. Полезно на мелких деталях.

Position-dependent prediction combination (PDPC) – VVC смешивает angular-прогноз с граничными сэмплами с позиционно-зависимым весом, сглаживая переход на краю блока.

Palette mode – H.265 SCC, AV1 и AV2 используют небольшую цветовую палитру и индекс на каждый сэмпл. Сделано для screen content: текст, UI-мокапы, игровые стримы – где блок содержит лишь несколько разных цветов.

Intra block copy (IBC) – H.265 SCC и AV1 позволяют блоку в текущем кадре быть предсказанным от другого уже закодированного блока в том же кадре, через смещение. Как motion compensation, но внутри одного кадра. Полезно для screen content с повторяющимися элементами.

Data-driven / learned modes (AV2) – AV2 вводит intra-режимы, параметры которых выучены на корпусе тренировочных изображений. Энкодер выбирает между rule-based и learned режимами на блок.

Рисунок 2. Intra prediction modes по поколениям. Число направлений выросло примерно как кубический корень от сложности декодера; крупные выигрыши пришли от специализированных инструментов вроде CCLM и palette mode, а не от добавления углов.

Частая ошибка: считать, что больше режимов всегда лучше

Естественное прочтение таблицы выше: AV1 должен быть примерно в десять раз лучше H.264 на intra, потому что у него в десять раз больше режимов. Это не так. Две вещи ломают линейную интуицию.

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

Во-вторых, время энкодера растёт с числом режимов. Энкодер обязан попробовать каждый режим (или применить умную эвристику, чтобы пропустить большинство) и оценить каждый. Полный intra-поиск AV1 примерно в 8 раз медленнее HEVC, который в свою очередь примерно в 4 раза медленнее H.264. Production-энкодеры идут с пресетами – veryfast, medium, slow, veryslow – которые торгуют тем, сколько режимов разрешено попробовать.

Заголовочные цифры – VVC экономит около 35% над AV1 на intra ценой примерно 8× времени кодирования по бенчмаркам 2026 года – говорят: зоопарк предсказания действительно помогает, но платите вы на стороне энкодера. Декодер дешевле, и именно это важно для delivery.

Где intra-кадры сидят в видеопотоке

В потоке с обоими типами кадров intra-кадры расставлены периодически как якоря. Расстояние между ними называется длина GOP (group of pictures) или keyframe interval.

Три силы тянут интервал в противоположные стороны.

Во-первых, эффективность сжатия любит длинные GOP. Intra-кадры большие – обычно в 4–10 раз больше inter-кадров при том же качестве – потому что не могут переиспользовать содержимое прошлых кадров. Чем длиннее GOP, тем меньше средний размер кадра, тем ниже битрейт. Netflix оптимизировал свои VOD-энкодинги, увеличив random-access picture period с 2 секунд до 15, сэкономив около 20% размера файла при том же VMAF.

Во-вторых, adaptive streaming навязывает конкретные интервалы. HLS и DASH-плееры переключают битрейт на границах сегментов. Каждый сегмент обязан начинаться с intra-кадра. Длина сегмента обычно 2–6 секунд. Если сегмент 2 секунды и framerate 30 fps, intra-кадр нужен каждые 60 кадров, точка. Дефолтные 2-секундные сегменты Bitmovin фиксируют 2-секундный keyframe interval.

В-третьих, live и low-latency стриминг хотят коротких GOP. Новый зритель, подключившийся к live-стриму, обязан ждать следующего keyframe перед началом воспроизведения. 15-секундный keyframe interval даёт 15-секундную worst-case startup-задержку. Low-latency HLS и WebRTC-style стримы используют интервалы в 1 секунду или меньше.

Production-кодеки обходят всё это. ProRes, DNx и Sony XAVC-I кодируют каждый кадр как intra. Длина GOP равна 1. Файлы намного больше, но каждый кадр – независимый keyframe, и это единственное, что важно редактору.

Рисунок 3. Три расстановки intra-кадров. Один и тот же энкодер, три разных keyframe interval, три очень разных размера файла при том же качестве.

Числовой пример: насколько I-кадр больше?

Возьмём видео 1080p30, закодированное x264 с CRF 23 (типичный quality target). Типичные размеры кадров для кино-подобного материала:

  • I-кадр (intra-only): ~120 килобит (≈ 15 КБ).
  • P-кадр (предсказанный из прошлого): ~25 килобит (≈ 3 КБ).
  • B-кадр (предсказанный из прошлого и будущего): ~10 килобит (≈ 1.25 КБ).

2-секундный GOP при 30 fps содержит 60 кадров: обычно 1 I-кадр, потом смесь P и B. Общий размер GOP в битах:

1 × 120 + 25 × 25 + 34 × 10 = 120 + 625 + 340 = 1 085 килобит за 2 секунды

Это примерно 542 килобита в секунду. Сам I-кадр вносит 120 / 1085 ≈ 11% бит, составляя только 1 / 60 ≈ 1.7% кадров. Сокращение keyframe interval до 1 секунды удваивает долю I-кадров до примерно 20% битстрима – это цена за более частые точки случайного доступа для плеера.

Теперь та же выкладка для all-intra кодека Avid DNx HQ при том же разрешении и framerate. DNx HQ на 1080p30 даёт около 145 мегабит в секунду – примерно в 270 раз больше, чем H.264-стрим. Это цена за независимость каждого кадра.

Как intra coding формирует остальной кодек

Intra coding – больше, чем механика keyframes. Она также влияет на intra-кодированные блоки внутри inter-кадров. Когда inter-энкодер не находит хорошего соответствия в reference-буфере – из-за смены сцены, окклюзии или совершенно нового содержимого – он откатывается на intra-кодирование для этого блока. P-кадр с многими intra-блоками называется «P-кадр с высокой intra-cost»; он стоит больше бит, чем средний P-кадр, но меньше полноценного I-кадра.

Вот почему важна scene-cut detection. Хороший энкодер ловит смену сцены и принудительно ставит I-кадр в этой точке, даже если это ломает регулярный ритм GOP. Иначе первый P-кадр после склейки оказался бы почти полностью intra-кодированным (нет хорошего motion-соответствия через смену сцены) и был бы почти таким же большим, как I-кадр, но без точки случайного доступа для плеера.

Вот почему также screen content особый. Блок сплошного цвета или блок чётких глифов шрифта имеет совсем другой статистический профиль, чем блок камерных пикселей. Intra-инструменты, выигрывающие на камерном контенте – angular modes, planar, DCT – не те, что выигрывают на screen content. Palette mode и intra block copy добавлены ровно для desktop sharing, удалённой работы и облачного гейминга.

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

Мы выпускаем видеоинфраструктуру, которая живёт или умирает на intra-решениях. В WebRTC-конференциях keyframe interval управляет временем восстановления соединения после потери пакетов – мы настраиваем его под use case для клиентов в телемедицине и e-learning. В OTT- и Internet-TV-стэках мы выравниваем keyframes по границам HLS- и DASH-сегментов, чтобы adaptive bitrate switching не вис. В видеонаблюдении мы балансируем длинные GOP ради экономии хранения и частые keyframes ради forensic seek time. В AR/VR и 360°-стриминге low-latency intra refresh-паттерны («gradual decoder refresh» или intra-блоковые keyframes) заменяют традиционные I-кадры. Мы не пишем новый кодек – мы используем H.264, H.265, AV1 и WebRTC-профили – но за 239 проектов с 2005 года настроили их на боевых задачах.

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

  • Intra coding сжимает одну картинку, используя только пиксели внутри неё, без обращения к другим кадрам.
  • Пайплайн – пять стадий: partition, predict from neighbours, residual, transform, quantize-and-entropy-code.
  • Поколения кодеков растили palette предсказаний от 9 (H.264) до ~95 (AV1) и data-driven режимов (AV2).
  • Keyframes – точки случайного доступа в каждом стриме; их частота управляет битрейтом, выравниванием сегментов и startup-латентностью.
  • All-intra production кодеки (ProRes, Avid DNx, XAVC-I) кодируют каждый кадр как keyframe ради frame-accurate-редактирования.
  • Больше режимов предсказания не покупают пропорционально больше сжатия – это убывающая отдача ценой времени энкодера.

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

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

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