Transform Coding: DCT, ADST и целочисленные преобразования

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

TL;DR

Видеокодер тратит почти ноль битов на сами пиксели – он использует их для кодирования остаточной ошибки после предсказания, а эту ошибку «перемешивает» математическая операция под названием transform, чтобы кодер мог отбросить ту часть, которую глаз не замечает. Каждый современный кодек с 1988 года использует одни и те же инструменты: DCT (дискретное косинусное преобразование) для гладких участков, DST и ADST (асимметричное DST) для границ, а также целочисленные приближения этих преобразований – чтобы все декодеры на планете приходили к одинаковому результату до последнего бита. Различия между H.264, HEVC, VP9, AV1 и VVC – не в самой идее, а в размере блоков, количестве доступных типов transform и дополнительных улучшениях сверху. Сделайте стадию transform правильно – и 4K-поток в 2026 году поместится в ту же «трубу», в которой пять лет назад едва помещалось 1080p.

Зачем это вам

Если у вас видеосервис, главная причина, по которой 4K-стриминг сегодня стоит вдвое дешевле, чем в 2019 году, – это стадия трансформации в кодеке, а не сеть, плеер или экраны. Продакт-менеджер, способный объяснить, что «кодер распределяет ошибку по нескольким крупным коэффициентам и отбрасывает мелкие», может читать даташит и задавать правильные вопросы: какие размеры transform-блоков используются, какие типы трансформаций поддерживаются и есть ли вторичная трансформация. Основатель, который сомневается в вендорском утверждении о «30% экономии битрейта» и уточняет, на каком контенте проводились тесты и какие трансформации были включены, экономит четверть расходов на хранение и CDN. Технический лидер, понимающий, зачем VVC поддерживает сразу DCT-II, DCT-VIII и DST-VII, создаёт транскодер, который превосходит вендорское решение вдвое дешевле.

Блок, который должен покинуть кодер

Каждый современный кодек работает с маленькими прямоугольными блоками пикселей – об этом мы подробно рассказывали в статье про block-based прогнозирование. Для каждого блока кодер сначала пытается предсказать значения пикселей – либо на основе соседних пикселей в том же кадре, либо по аналогии с похожим блоком из более раннего кадра. Эти этапы мы разбирали в статьях intra-frame coding и inter-frame coding и motion estimation. Предсказание почти никогда не бывает идеальным. Попиксельная разница между предсказанием и реальным значением называется residual – остаточная ошибка.

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

Эта смена точки зрения – суть работы transform. Он берёт residual-блок и представляет его в виде суммы фиксированных волнообразных образцов, называемых базисными функциями. У каждой базисной функции своя фиксированная частота – медленная, средняя или быстрая – и своё направление: горизонтальное, вертикальное или диагональное. На выходе transform выдаёт одно число для каждой базисной функции, которое сообщает кодеру, «насколько сильно» данный образец присутствует в блоке. Эти числа называются коэффициентами.

Фокус в том, что реальные остатки (residuals) в основном выглядят как несколько низкочастотных компонентов плюс длинный хвост близких к нулю высокочастотных. Хорошо подобранное преобразование (transform) сдвигает почти всю энергию в верхний левый угол сетки коэффициентов – низкочастотный «гладкий» угол – и оставляет остальную часть сетки заполненной малыми числами, которые квантизация (quantization) – мы разберём её в следующей статье блока, Quantization – может отбросить с минимальным видимым ущербом. Эта концентрация энергии в нескольких коэффициентах называется energy compaction – компактизация энергии – и это единственная причина существования преобразований (transform).

Рис. 1. Преобразование (transform) превращает пиксельный residual в transform-коэффициенты. Энергия концентрируется в верхнем левом углу – именно это делает следующий этап, квантизацию (quantization), эффективной.

Что такое DCT на самом деле

Дискретное косинусное преобразование (DCT) – это способ разложить любой блок чисел на сумму косинусоид фиксированных частот. Идея была предложена математиком Насиром Ахмедом (Nasir Ahmed) в 1972 году в Университете Техаса в Арлингтоне. Позже он вместе с учениками Т. Раджем Натараджаном и К. Р. Рао опубликовал формальный алгоритм в статье, вышедшей в январе 1974 года. Первое применение в области видео произошло в 1975 году, когда Джон А. Роуз и Гюнер С. Робинсон использовали DCT в кодере с компенсацией движения между кадрами и показали, что он способен сжимать данные до 0,25 бита на пиксель – цифры, которая спустя пятьдесят лет по-прежнему определяет архитектуру практически всех кодеков в интернете.

DCT сначала обрабатывает строки, а затем – столбцы. Для блока 4×4 преобразование записывает каждую строку как взвешенную сумму четырёх косинусоид: одна волна остаётся неизменной (среднее значение), вторая переходит от плюса к минусу вдоль строки (первый косинус), третья имеет два нуля, четвёртая – три. Тот же алгоритм применяется к столбцам. На выходе получается сетка 4×4 коэффициентов, где верхний левый элемент – DC-коэффициент – представляет собой среднее значение пикселей; он назван по аналогии с постоянным током (direct current) в электротехнике, а остальные – AC-коэффициенты, соответствующие возрастающим частотам.

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

В математической литературе существует восемь вариантов DCT – от DCT-I до DCT-VIII. В видео используется DCT-II – тот же самый алгоритм, что и в JPEG с 1992 года. Современные кодеки также применяют второй вариант – DCT-VIII, с которым мы столкнёмся позже при обсуждении VVC и AV1.

Рис. 2. 16 базисных функций DCT-II 4×4. Любой residual-блок представляется как взвешенная сумма этих 16 узоров; веса – это коэффициенты, которые кодек на самом деле передаёт.

Пример на одном блоке

Чтобы математика стала наглядной, рассмотрим residual-блок размером 4×4, в котором каждое значение равно 8:

8 8 8 8
8 8 8 8
8 8 8 8
8 8 8 8

В блоке нет деталей – только среднее значение. Если применить к нему 4×4 DCT-II, ненулевым окажется только один коэффициент – DC-коэффициент, пропорциональный среднему по блоку, умноженному на его размер. Все остальные коэффициенты будут равны нулю. Мы начали с 16 одинаковых чисел и получили одно число, содержащее всю энергию. Кодер передаёт это число (несколько бит), а декодер восстанавливает блок – картинка получается точной.

Теперь смешаем residual с вертикальным краем:

 8  8 -8 -8
 8  8 -8 -8
 8  8 -8 -8
 8  8 -8 -8

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

Теперь шумный блок – residual после ошибки предсказания движения:

 4 -3  2  1
-2  5 -1  3
 1 -2  4 -1
-3  2 -1  5

Выход DCT-II распределяется по многим коэффициентам, причём самые крупные по-прежнему сосредоточены в верхнем левом углу. Сжатие энергии слабее проявляется для шума, чем для гладкого сигнала – и это как раз то поведение, которое требуется: случайный шум не может «спрятаться», и кодеру приходится тратить биты.

Причина, по которой каждый кодек использует DCT в качестве «дефолтного» преобразования, – в том, что в 90 % случаев остаточные данные выглядят как на первых двух примерах, а не как на третьем.

Целочисленные transform – почему декодеры никогда не расходятся

Стандартный DCT-II использует значения косинусов с плавающей точкой, а вычисления с плавающей точкой не являются bit-exact на разных устройствах. Телефон, телевизор и браузер на ноутбуке должны декодировать один и тот же битстрим в одни и те же пиксели – кадр за кадром, часами подряд. Если хотя бы один из них вычисляет обратный DCT хоть немного иначе – даже в последнем десятичном знаке – небольшая ошибка накапливается от кадра к кадру, и декодеры начинают расходиться. Это был реальный баг в ранних MPEG-кодеках, известный как inverse transform drift – он вызывал полосы и «призраки» на длинных видео.

H.264, утверждённый в 2003 году, решил эту проблему раз и навсегда, заменив floating-point DCT на целочисленный transform – масштабированное приближение DCT-II, использующее лишь сложение, вычитание и сдвиг вправо. Элементы матрицы – небольшие целые числа (в основном 1 и 2), подобранные так, что transform ведёт себя как настоящий DCT-II с точностью до доли коэффициента, но при этом каждый шаг выполняется в целочисленной арифметике. Цена – небольшая потеря energy compaction (целочисленный transform в среднем примерно на 0,1 дБ хуже истинного DCT-II); выигрыш – каждый декодер на Земле выдаёт идентичный результат байт в байт.

Transform-слой H.264 состоит из четырёх компонентов. Базовое преобразование 4×4 – это целочисленное приближение DCT-II, которое мы только что описали. Hadamard-преобразование 4×4 использует лишь сложение и вычитание – оно проще базового – и применяется к DC-коэффициентам блоков 16×16 при intra-предсказании, чтобы дополнительно повысить эффективность кодирования плоских областей. Hadamard 2×2 выполняет аналогичную задачу для chroma-DC. И, наконец, целочисленное преобразование 8×8, добавленное в профиль High в 2005 году, представляет собой расширенную версию базового преобразования для блоков с более гладким содержанием, где 4×4 оказывается недостаточно эффективным.

Вторая дизайнерская идея H.264 – разделение transform на основную часть и масштабирующую часть. Основная часть отвечает за кодирование и декодирование, а масштабирующая – за работу с квантованием. Такое разделение упрощает как кодер, так и декодер, и объясняет, почему преобразования H.264 выполняются только с использованием сложений, вычитаний и сдвигов: умножения вынесены в другую часть.

Каждый кодек после H.264 следует одному и тому же шаблону: определяются целочисленные матрицы, доказывается, что обратное преобразование точно восстанавливает исходный сигнал, а в квантизатор добавляется масштабирование. Числа в матрицах различаются, но общая методика остаётся неизменной.

Рис. 3. Целочисленный transform-пайплайн H.264. 2D-преобразование выполняется двумя 1D-проходами: сначала по строкам, затем по столбцам, каждый с использованием небольшой целочисленной матрицы. Такое разбиение раз и навсегда устраняет накопление ошибок при обратном преобразовании (inverse transform drift).

DST и ADST – лучший инструмент для краёв

DCT-II хорошо работает с гладким контентом, где остаточная ошибка плавно убывает от центра. Он менее эффективен для блоков остатка, имеющих форму одностороннего наклона – пиксели мелкие с одной стороны, крупные – с другой. Именно такую форму и принимает ошибка intra-предсказания. Intra-предсказание копирует пиксели из верхней и левой частей блока: предсказание максимально точное у границы и постепенно ухудшается с удалением от неё. Соответственно, остаточная ошибка мала в верхнем левом углу и возрастает к нижнему правому.

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

HEVC, утверждённый в 2013 году, стал первым стандартом, внедрившим DST в продакшен. Он определяет 4×4 целочисленный DST-7 – седьмой тип из семейства дискретных синусоидальных преобразований – и требует от кодера применять его к 4×4 остаткам яркости (luma residuals) внутри областей с внутрикадровым предсказанием. Авторы HEVC ограничили использование DST-7 только 4×4 блоками luma intra, поскольку именно там достигается наибольший выигрыш; на более крупных блоках или для цветовых компонент (chroma) выигрыш оказывался меньше, чем затраты на поддержку двух типов преобразований. Объединённая команда JCT-VC зафиксировала около 1%-ное снижение битрейта при неизменном субъективном качестве изображения только за счёт этого правила (Sze et al., 2014).

Следующий кодек, VP9, утверждённый Google в 2013 году, развил ту же идею дальше. VP9 ввёл Asymmetric Discrete Sine Transform (ADST) – асимметричное дискретное синус-преобразование – в качестве дополнения к DCT. ADST близок к DST-7, но реализован так, чтобы корректно работать с целочисленной арифметикой и интегрироваться с режимами intra-предсказания в VP9. Кодер VP9 применяет ADST для остаточных блоков при directional-предсказании и DCT – для inter-остатков и плоских направлений. Декодер выбирает тип преобразования на основе флагов в битстриме.

Причина, по которой ADST помогает, та же, что и у DST-7 в HEVC: его базисные функции наклонены в ту же сторону, что и типичный intra-остаток, поэтому сжатие энергии оказывается более плотным. Слово «asymmetric» означает, что базисные функции не симметричны относительно центра блока – они нарастают в одну сторону, повторяя асимметричную форму остатка.

AV1 – шестнадцать преобразований и обучаемый выбор

AV1, утверждённый Альянсом за открытые медиа (AOMedia) в марте 2018 года, довёл идею множественных типов преобразований до логического предела. AV1 определяет четыре 1D-ядра: DCT, ADST, FLIPADST и IDTX.

DCT – стандартное косинусное преобразование, с которым мы уже сталкивались. ADST – асимметричное синусное преобразование, унаследованное и доработанное из VP9. FLIPADST – перевёрнутая версия ADST: те же базисные функции, но обрабатываются снизу вверх, а не сверху вниз; она нужна для остатков, чья энергия сосредоточена в противоположной стороне. IDTX (сокращение от identity transform) оставляет входные данные без изменений. IDTX полезен для экранного контента – текста, линий, резкой компьютерной графики, – где остаток уже состоит из нескольких изолированных «всплесков», и реальное частотное преобразование только размывает их.

AV1 объединяет эти четыре ядра в горизонтальном и вертикальном направлениях, обеспечивая до 16 различных 2D-преобразований на блок. Для блоков 4×4 и 8×8 доступны все 16 комбинаций; для блоков 16×16, 32×32 и 64×64 кодер использует сокращённый набор, чтобы сделать поиск по rate-distortion управляемым. Тип преобразования указывается в битстриме для каждого блока – одна из причин, по которой битстрим AV1 содержит гораздо больше флагов на блок по сравнению с H.264.

Цена шестнадцати трансформаций – сложность кодера. Кодер должен перебрать всех кандидатов, выполнить квантование, оценить битовую стоимость и выбрать лучшего – этот процесс называется rate-distortion optimization (RDO), о нём подробно рассказано в статье Mode decision и RDO. Выгода – примерно 5–7% снижения битрейта при той же картинке на естественном контенте по сравнению с базовой схемой с одним трансформом, и до 15–20% на экранном контенте, где особенно эффективен IDTX.

TransformГде лучше всегоДоступен вРазмеры блоков
DCT-IIГладкие residual, interH.261, MPEG-2, H.264, HEVC, VP9, AV1, VVC4×4 – 64×64
DST-VII4×4 intra lumaHEVC, VVC4×4 (HEVC), 4×4 – 32×32 (VVC)
ADSTDirectional intraVP9, AV14×4 – 64×64
FLIPADSTIntra с обратным наклономAV14×4 – 64×64
IDTX (identity)Screen content, всплескиAV1 (и VVC TS-mode)4×4 – 32×32
DCT-VIIIМалые intra-блокиVVC4×4 – 32×32

Таблица 1. Меню transform-ов современных кодеков. Каждое поколение кодеков добавляет либо новое ядро, либо новый размер блока – базовая идея с 1972 года не менялась.

VVC – Multiple Transform Selection и вторичная стадия

VVC, ратифицированный как ITU-T H.266 в июле 2020 года, переработал стадию преобразования двумя параллельными нововведениями: Multiple Transform Selection (MTS) и Low-Frequency Non-Separable Transform (LFNST).

MTS предоставляет кодеру VVC три типа преобразований – DCT-II, DCT-VIII и DST-VII – и позволяет независимо выбирать наиболее подходящее для каждого блока по горизонтали и вертикали. Размеры блоков варьируются от 4×4 до 64×64 для DCT-II и до 32×32 для DCT-VIII и DST-VII. Это та же концепция, что и в AV1, но с несколько иным набором ядер.

LFNST – то, что делает VVC особенным. Он работает после первичного преобразования и перед квантованием, обрабатывая только низкочастотные коэффициенты (верхний левый угол блока 4×4 или 8×8 на выходе первичного преобразования). LFNST – несепарабельный: он не разбивается на отдельные проходы по строкам и столбцам, а применяет единую 2D-матрицу к развёрнутому вектору из 16 или 64 коэффициентов. Несепарабельные преобразования способны уловить корреляции, которые стандартная схема «строки, потом столбцы» обычного сепарабельного DCT упускает – особенно в направленных intra-остатках, где энергия сосредоточена вдоль диагонали.

Цена – преобразования non-separable стоят дороже арифметических операций. LFNST ограничивает ущерб тем, что работает только в низкочастотной области – максимум 64 коэффициента на блок – и хранит лишь несколько небольших матриц, выбираемых в зависимости от режима intra-предсказания. Команда JVET зафиксировала дополнительно около 1–2% снижения битрейта за счёт одного LFNST на intra-контенте (Wang et al., 2021).

У LFNST есть одно важное свойство: когда LFNST включён, MTS принудительно устанавливается в DCT-II. Эти два режима не комбинируются – они чередуются, выбор делается для каждого блока отдельно.

Рис. 4. Этап преобразования в VVC. Multiple Transform Selection выбирает первичное ядро; опциональный Low-Frequency Non-Separable Transform дополнительно декоррелирует низкочастотные коэффициенты перед квантованием.

AV2 – ядра, управляемые данными, и внутрисекционные/межсекционные вторичные преобразования

AV2, преемник AV1 от AOMedia, находится в активной разработке по состоянию на май 2026 года. Стадия преобразования – одна из областей с наиболее масштабными запланированными изменениями. Опубликованные технические отчёты выделяют четыре направления.

Во-первых, AV2 перепроектирует первичные ядра DCT, DST и ADST, чтобы целочисленные матрицы точнее соответствовали статистике residual-ов, измеренной на крупных современных видеокорпусах. Во-вторых, AV2 вводит data-driven transforms (DDTs) – ядра, обученные офлайн на реальном видео и вшитые в стандарт; идея похожа на обучаемые компоненты neural codec, но закодированы они как фиксированные матрицы, чтобы декодеры оставались детерминированными. В-третьих, AV2 добавляет intra/inter secondary transforms (IST) – non-separable вторую стадию, аналог VVC LFNST, но доступную и для intra, и для inter блоков. В-четвёртых, AV2 расширяет фреймворк partitioning-а transform-ов, чтобы кодер мог выбрать более мелкие разбиения transform-блоков внутри одного coded-блока, подгоняя размер transform под локальную структуру residual (Nadir et al., arXiv:2601.02712, 2026).

Ожидаемый прирост только на стадии transform – снижение битрейта на 3–6% по сравнению с AV1 при неизменном качестве изображения на естественном контенте, с более значительным выигрышем на screen content. Общая цель AV2 по отношению к AV1 со всеми инструментами – снижение битрейта на 30–40%; эта цифра условна, поскольку стандарт ещё не утверждён.

Как transform взаимодействует со всем остальным

Transform не работает в одиночку. Его решения влияют на три последующие стадии.

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

Reordering и run-length coding обходят сетку коэффициентов зигзагообразно – от верхнего левого угла к периферии, следуя возрастанию частоты. Цель – собрать длинный хвост нулей в единый прогон, который энтропийный кодер затем сжимает почти до нуля. Разные преобразования дают разный порядок сканирования; для ADST и FLIPADST он повёрнут с учётом асимметрии базисных функций. Подробности – в статье Reordering, zig-zag и run-length.

Entropy coding – CABAC в H.264/HEVC/VVC, арифметический кодер в AV1 – преобразует квантованные коэффициенты и их позиции в финальные биты. Компактные, в основном нулевые сетки коэффициентов дают entropy-кодеру материал, который он сжимает агрессивно; «размазанные» сетки – нет. Подробнее об этом рассказано в статье Entropy coding в деталях.

Четыре стадии – transform, quantization, reordering, entropy – построены как единая цепочка. Изменение одной из них без остальных сводит её пользу к нулю; именно поэтому каждое новое поколение кодеков пересматривает все четыре этапа сразу, а не настраивает лишь один блок.

Рис. 5. Цепочка кодирования в каждом современном кодеке. Transform, quantize, reorder, entropy – четыре стадии, которые нужно оптимизировать совместно, чтобы добиться максимального выигрыша в сжатии.

Частая ошибка – высокий QP и обвинения в адрес transform

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

Если изображение выглядит блочным – значит, преобразование (transform) выполнило свою работу, а квантование (quantizer) было слишком агрессивным. Если заметны осцилляции (ringing) по краям – преобразование корректно выделило высокочастотные компоненты, но квантование их подавило: это классический эффект Гиббса, вполне предсказуемый, устраняется снижением QP или увеличением битовой глубины на границах. Если видны цветовые полосы – преобразование передало чистые коэффициенты квантователю с недостаточным числом уровней; исправить можно повышением битовой глубины или переходом на 10-битное кодирование. Преобразование – как фотограф, а квантователь – как корзина для неудачных снимков. Исправлять нужно не снимок, а корзину.

Где Фора Софт в этой картине

В стриминговых, системах видеонаблюдения, конференц-связи и AR/VR-продуктах, которые мы разрабатываем, выбор стадии трансформации определяет треть качества изображения и четверть времени кодирования. В live OTT-пайплайнах мы используем DST-7 HEVC для контента с высокой долей intra-кадров и полное меню из шестнадцати трансформаций AV1 для премиального VOD – там, где стоимость кодирования оплачивается один раз, а экономия окупается миллионами воспроизведений. В WebRTC SFU мы применяем целочисленный 4×4 transform из H.264, поскольку точность декодирования и минимальная вычислительная нагрузка на блок важнее последних нескольких процентов сжатия. В композитах видеонаблюдения используем MTS VVC с отключённым LFNST, так как выигрыш от несепарабельных трансформаций теряется на обрезанных под-кадрах. Суть в том, что трансформация – это инструмент под конкретную нагрузку, а не стандартная настройка, унаследованная из вендорских пресетов.

Главное

  • Transform переписывает пиксельный residual как веса фиксированных волновых узоров; энергия концентрируется так, что quantization может отбросить мелкую деталь.
  • DCT-II – стандарт для гладкого контента; DST-7 и ADST лучше подходят для intra-ресидуалов с градиентом по блоку.
  • Целочисленные преобразования – только сложения, вычитания и сдвиги – устраняют дрейф обратного преобразования и обеспечивают bit-exact декодирование на каждом устройстве.
  • HEVC использует DST-7 для 4×4 luma intra; VP9 и AV1 активно применяют ADST; AV1 добавляет FLIPADST и identity transform для screen content; VVC вводит DCT-8 и вторую стадию LFNST; AV2 добавляет data-driven преобразования.
  • Прибыль от стадии преобразования складывается с выигрышем от квантования, перестановки и энтропийного кодирования – их нужно оптимизировать совместно, чтобы получить реальный coding gain.
  • Выбор подходящего преобразования для каждого блока – одна из самых важных возможностей кодера; современные кодеки тратят вычислительные ресурсы на качественный подбор.

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

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

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