H.264 — стандарт сжатия видео. И он вездесущ, его используют для сжатия видео в интернете, на Blu-ray, телефонах, камерах наблюдения, дронах, везде. Все сейчас используют H.264.
Нельзя не отметить технологичность H.264. Он появился в результате 30-ти с лишним лет работы с одной единственной целью: уменьшение необходимой пропускной способности канала для передачи качественного видео.
С технической точки зрения это очень интересно. В статье будут поверхностно описаны подробности работы некоторых механизмов сжатия, я постараюсь не наскучить с деталями. К тому же, стоит отметить, что большинство изложенных ниже технологий справедливы для сжатия видео в целом, а не только для H.264.
Зачем вообще сжимать что-либо?
Видео в несжатом виде это последовательность двумерных массивов, содержащих информацию о пикселях каждого кадра. Таким образом это трёхмерный (2 пространственных измерения и 1 временной) массив байтов. Каждый пиксель кодируется тремя байтами — один для каждого из трёх основных цветов (красный, зелёный и синий).
1080p @ 60 Hz = 1920x1080x60x3 => ~370 Мб/с данных.
Этим практически невозможно было бы пользоваться. Blu-ray диск на 50Гб мог бы вмещать всего около 2 мин. видео. С копированием так же будет не легко. Даже у SSD возникнут проблемы с записью из памяти на диск.
Поэтому да, сжатие необходимо.
Почему же H.264?
Обязательно отвечу на этот вопрос. Но сперва я покажу кое-что. Взгляните на главную страницу Apple:
Я сохранил изображение и приведу в пример 2 файла:
Эмм… что? Размеры файлов кажется перепутали.
Нет, с размерами всё в порядке. Видео H.264 с 300 кадрами весит 175 Кб. Один единственный кадр из видео в PNG — 1015 Кб.
Кажется, мы храним в 300 раз больше данных в видео, но получаем файл весом в 5 раз меньше. Получается H.264 эффективнее PNG в 1500 раз.
Как такое возможно, в чём заключается приём?
А приёмов очень много! H.264 использует все приёмы о которых вы догадываетесь (и уйму о которых нет). Давайте пройдёмся по основным.
Избавляемся от лишнего веса.
Представьте, что вы готовите машину к гонкам и вам нужно её ускорить. Что вы сделаете в первую очередь? Вы избавитесь от лишнего веса. Допустим, машина весит одну тонну. Вы начинаете выбрасывать ненужные детали… Заднее кресло? Пфф… выбрасываем. Сабвуфер? Обойдёмся и без музыки. Кондиционер? Не нужен. Коробка передач? В мусо… стойте, она еще пригодится.
Таким образом вы избавитесь от всего, кроме необходимого.
Этот метод отбрасывания ненужных участков называется сжатием данных с потерями. H.264 кодирует с потерями, отбрасывая менее значимые части и сохраняя при этом важные.
PNG кодирует без потерь. Это означает, что вся информация сохраняется, пиксель в пиксель, и поэтому оригинал изображения можно воссоздать из файла, закодированного в PNG.
Важные части? Как алгоритм может определять их важность в кадре?
Существует несколько очевидных способов урезания изображения. Возможно, верхняя правая четверть картинки бесполезна, тогда можно удалить этот угол и мы уместимся в ? исходного веса. Теперь машина весит 750 кг. Либо можно вырезать кромку определенной ширины по всему периметру, важная информацию всегда ведь по середине. Да, возможно, но H.264 всего этого не делает.
Что же на самом деле делает H.264?
H.264, как и все алгоритмы сжатия с потерями, уменьшает детализацию. Ниже, сравнение изображений до и после избавления от деталей.
Видите как на сжатом изображении исчезли отверстия в решётке динамика у MacBook Pro? Если не приближать, то можно и не заметить. Изображение справа весит всего 7% от исходного и это при том, что сжатия в традиционном смысле не было. Представьте машину весом всего лишь 70 кг!
7%, ого! Как возможно так избавиться от детализации?
Для начала немного математики.
Информационная энтропия
Мы подходим к самому интересному! Если вы посещали теорию информатики, то возможно вспомните про понятие информационной энтропии. Информационная энтропия это количество единиц для представления некоторых данных. Заметьте, что это вовсе не размер самих данных. Это минимальное количество единиц, которое нужно использовать, чтобы представить все элементы данных.
Например, если в виде данных взять один бросок монеты, то энтропия получится 1 единица. Если же бросков монетки 2, то понадобятся 2 единицы.
Предположим, что монета весьма странная — её подбросили 10 раз и каждый раз выпадал орёл. Как бы вы кому нибудь рассказали об этом? Вряд ли как-то вроде ОООООООООО, вы бы сказали «10 бросков, все орлы» — бум! Вы только что сжали информацию! Легко. Я вас спас от многочасовой утомительной лекции. Это, конечно же, огромное упрощение, но вы преобразовали данные в некое короткое представление с той же информативностью. То есть уменьшили избыточность. Информационная энтропия данных не пострадала — вы только преобразовали представление. Такой способ называется энтропийным кодированием, который подходит для кодирования любого вида данных.
Частотное пространство
Теперь, когда мы разобрались с информационной энтропией, перейдем к преобразованию самих данных. Можно представить данные в фундаментальных системах. Например, если использовать двоичный код, будут 0 и 1. Если же использовать шестнадцатеричную систему, то алфавит будет состоять из 16 символов. Между вышеупомянутыми системами существует взаимно однозначная связь, поэтому можно легко преобразовывать одно в другое. Пока всё понятно? Идём дальше.
А представьте, что можно представить данные, которые изменяются в пространстве или времени, в совершенно иной системе координат. Например, яркость изображения, а вместо системы координат с x и y, возьмём частотную систему. Таким образом, на осях будут частоты freqX и freqY, такое представление называется частотным пространством[Frequency domain representation]. И существует теорема, что любые данные можно без потерь представить в такой системе при достаточно высоких freqX и freqY.
Хорошо, но что такое freqX и freqY?
freqX и freqY всего лишь другой базис в системе координат. Так же как можно перейти из двоичной системы в шестнадцатеричную, можно перейти из X-Y в freqX и freqY. Ниже изображён переход из одной системы в другую.
Мелкая решётка MacBook Pro содержит высокочастотную информацию и находится в области с высокими частотами. Таким образом мелкие детали имеют высокую частоту, а плавные изменения, такие как цвет и яркость низкую. Всё, что между, остаётся между.
В таком представлении, низкочастотные детали находятся ближе к центру изображения, а высокочастотные в углах.
Пока всё понятно, но зачем это нужно?
Потому что теперь, можно взять изображение, представленное в частотных интервалах, и обрезать углы, иными словами применить маску, понизив тем самым детальность. А если преобразовать изображение обратно в привычное, можно будет заметить, что оно осталось похожим на исходное, но с меньшей детализацией. В результате такой манипуляции, мы сэкономим место. Путём выбора нужной маски, можно контролировать детализацию изображения.
Ниже знакомый нам ноутбук, но теперь уже с, применёнными к ней, круговыми масками.
В процентах указана информационная энтропия относительно исходного изображения. Если не приближать, то разница не заметна и при 2%! — машина теперь весит 20 кг!
Именно таким образом нужно избавляться от веса. Такой процесс сжатия с потерями называется Квантованием.
Это впечатляет, какие еще приёмы существуют?
Цветовая обработка
Человеческий глаз не особо хорошо различает близкие оттенки цвета. Можно легко распознавать наименьшие различия в яркости, но не цвета. Поэтому должен существовать способ избавления от лишней информации о цвете и сэкономить ещё больше места.
В телевизорах, цвета RGB преобразуются в YCbCr, где Y это компонента яркости (по сути яркость черно-белого изображения), а Cb и Cr компоненты цвета. RGB и YCbCr эквиваленты в плане информационной энтропии.
Зачем же тогда усложнять? RGB разве не достаточно?
Во времена чёрно-белых телевизоров, была только компонента Y. А с началом появления цветных телевизоров у инженеров встала задача о передаче цветного RGB изображения вместе с чёрно-белым. Поэтому вместо двух каналов для передачи, было решено кодировать цвет в компоненты Cb и Cr и передавать их вместе с Y, а цветные телевизоры уже сами будут преобразовывать компоненты цвета и яркости в привычный им RGB.
Но вот в чём хитрость: компонента яркости кодируется в полном разрешении, а компоненты цвета лишь в четверть. И этим можно пренебречь, т.к. глаз/мозг плохо различает оттенки. Таким образом можно уменьшить размер изображения в половину и с минимальными отличиями. В 2 раза! Машина будет весить 10 кг!
Данная технология кодирования изображения со снижением цветового разрешения называется цветовой субдискретизацией. Она используется повсеместно уже давно и относится не только к H.264.
Это самые значительные технологии в уменьшении размера при сжатии с потерями. Нам удалось избавиться от большинства детализации и сократить информацию о цвете в 2 раза.
А можно ещё больше?
Да. Обрезание картинки это лишь первый шаг. До этого момента мы разбирали отдельно взятый кадр. Пришло время взглянуть на сжатии во времени, где нам предстоит работать с группой кадров.
Компенсация движения
H.264 стандарт, который позволяет компенсировать движения.
Компенсация движения? Что это?
Представьте, что вы смотрите теннисный матч. Камера зафиксирована и снимает с определенного угла и единственное что движется это мячик. Как бы вы закодировали это? Вы бы сделали что и обычно, да? Трёхмерный массив пикселей, две координаты в пространстве и один кадр за раз, так?
Но зачем? Большая часть изображения одинакова. Поле, сетка, зрители не меняются, единственное что движется это мячик. Что если определить единственное изображение фона и одно изображение мячика, движущегося по нему. Не сэкономило бы это значительно места? Вы видите к чему я клоню, не так ли? Компенсация движения?
И это именно то, что H.264 делает. H.264 разбивает изображение на макроблоки, обычно 16х16, которые используются для расчёта движения. Один кадр остаётся статичным, обычно его называют I-кадр [Intra frame], и содержит всё. Последующие кадры могут быть либо P-кадры [predicted], либо B-кадры [bi-directionally predicted]. В P-кадрах вектор движения кодируется для каждого макроблока на основе предыдущих кадров, таким образом декодер должен использовать предыдущие кадры, взяв последний из I-кадров видео и постепенно добавляя изменения последующих кадров пока не дойдёт до текущего.
Ещё интереснее обстоят дела с B-кадрами, в которых расчёт производится в обоих направлениях, на основании кадров идущих до и после них. Теперь вы понимаете почему видео в начале статьи весит так мало, это всего лишь 3 I-кадра, в которых мечутся макроблоки.
При такой технологии кодируется только различия векторов движения, тем самым обеспечивая высокую степень сжатия любого видео с перемещениями.
Мы рассмотрели статическое и временное сжатия. С помощью квантования мы во много раз уменьшили размер данных, затем с помощью цветовой субдискретизации ещё вдвое сократили полученное, а теперь еще компенсацией движения добились хранения лишь 3х кадров из 300, которые были первоначально в рассматриваемом видео.
Выглядит впечатляюще. Теперь что?
Теперь мы подведём черту, используя традиционное энтропийное кодирование без потерь. Почему нет?
Энтропийное кодирование
После этапов сжатия с потерями, I-кадры содержат избыточные данные. В векторах движения каждого из макроблоков в P-кадрах и B-кадрах много одинаковой информации, так как зачастую они двигаются идентично, как это можно наблюдать в начальном видео.
От такой избыточности можно избавиться энтропийным кодированием. И можно не переживать за сами данные, так как это стандартная технология сжатия без потерь, а значит всё можно восстановить.
Вот теперь всё! В основе H.264 лежат вышеупомянутые технологии. В этом и заключаются приёмы стандарта.
Отлично! Но меня разбирает любопытство узнать, сколько же весит теперь наша машина.
Исходное видео было снято в нестандартном разрешении 1232x1154. Если посчитать, то получится:
5 сек. @ 60 fps = 1232x1154x60x3x5 => 1.2 Гб
Сжатое видео => 175 Кб
Если соотнести результат с оговорённой массой машины в одну тонну, то получится вес равный 0.14 кг. 140 граммов!
Да, это магия!
Конечно же я в очень упрощённом виде изложил результат десятилетних исследований в этой сфере. Если захотите узнать больше, то страница в википедии вполне познавательна.
Комментарии (38)
RomanArzumanyan
01.12.2016 12:20+6Это всё здорово, но стандарту уже больше 10 лет. И о самом стандарте сказано мало.
den_admin
01.12.2016 12:31+3H.264, насколько я понимаю, увешан патентами, как новогодняя елка — игрушками?
А кроме гугловского Webm есть еще конкуренты?ValdikSS
01.12.2016 12:51+6WebM не гугловский, WebM — контейнер, упрощенный Matroska до такой степени, что в него можно добавить только VP8/9, Vorbis/Opus, WebVTT-дорожки.
Вы, видимо, VP8/9 имели ввиду. Реальных конкурентов пока нет. Разрабатывается AOMedia Video 1.Klotos
01.12.2016 14:35Если брать разрабатываемые кодеки, то можно ещё упомянуть Daala. К тому же, самым что ни на есть реальным конкурентом для H.264 является H.265 (HEVC).
mapron
01.12.2016 17:27+1Вы неправы, H.265 не конкурент AVC, это скорее его потомок, он принадлежит той же MPEGLA. А вот конкурентом будет VP9, а так же VP10, который будет заменен AV1
https://en.wikipedia.org/wiki/AOMedia_Video_1
Свободный кодек, который пилял гугл, циска, мозилла, amd, nvidia, да куча уже участников. У мпеглы появится свободный конкурент)erlyvideo
02.12.2016 09:38почему вы решили, что патенты, которые держит mpegla не покрывают vp9 или av1?
mapron
02.12.2016 17:46Я ничего не решил, это будут эксперты по патентам решать. Но авторы хотят, чтобы пересечений не было.
erlyvideo
02.12.2016 20:11я бы рекомендовал не распространять гугловый миф о том, что у mpegla нет патентов, затрагивающих vpN.
H264 как раз открытый кодек с хорошим открытым описанием в отличие от гугловых ранних поделочек.
nevzorofff
01.12.2016 12:37+8Почему H.264, с потерями сравнивается со сжатием без потерь в PNG, а не с «аналогичным» JPEG?
A3a
01.12.2016 12:43Я думаю, смысл заключался как раз в демонстрации контраста размера данных между сжатыми с потерями и исходными.
Shultc
01.12.2016 12:59Тогда почему не BMP, к примеру?
Aingis
01.12.2016 13:19Да там и PNG неоптимизированный, он легко ужимается до 519 КБ.
VioletGiraffe
01.12.2016 13:24+1В чём заключается оптимизация? Индексированные цвета?
Aingis
01.12.2016 15:38Методов много: использование лучше сжимающих фильтров (в PNG их несколько, и можно комбинировать), использование более лучшего алгоритма deflate сжатия (kzip, zopfli) и многое другое.
Причём это без потери качества. Уменьшением числа цветов иногда можно сжать ещё на несколько десятков процентов без видимой глазу разницы.
Saffron
01.12.2016 14:02+2Только надо понимать, что мы так долго ждали появления новых способов кодирования видео не потому, что теория кодирования активно развивается последние годы, а потому что производительность процессоров подросла и они могут выполнять более изощрённые алгоритмы декодирования в реальном времени. Следующий шаг, наверное, это отказ от декодирования на стороне процессора с прицелом только на видеоускорители. Они и сейчас способны декодировать видео, но алгоритм достаточно прост, чтобы на компьютере без видеоускорителя процессор мог справится сам, пусть и загруженный почти на полную. Формат будущего, возможно, будет настолько сложен, что даже процессор ПК не будет способен своевременно его обрабатывать.
Квантованием называется как раз урезание пространства — вместо чисел 1,2,3,4 мы храним числа 2,2,4,4. Картинка от такого портится слишком заметно. Именно поэтому квантование применяется в частотной области.
Сам показанный алгоритм примитивен и не показывает отличий h264 от предшественников.
uSasha
01.12.2016 15:37Вообще если говорить про встраиваемые системы или планшеты/телефоны, то там все делается исключительно аппаратными кодерами, обычное ядро захлебнулось бы.
У меня и ноутбук старенький (AMD E-350) не может даже WXGA декодировать на лету.
erlyvideo
01.12.2016 14:21> PNG скриншот главной страницы 1015 Кб
> 5 секунд H.264 видео при 60 fps той же страницы 175 Кб
Так вы же не то сравниваете. Сравнивать надо jpeg с h264.
Другой вопрос в том, что i-frame в h264 может выйти меньше чем jpeg при прочих примерно равных.A3a
01.12.2016 14:28+5Во первых, сравниваю не я, а автор оригинальной статьи. А во вторых, я уже предположил почему автор выбрал PNG, а не JPEG выше.
kosmos89
01.12.2016 18:28Такой процесс сжатия с потерями называется Квантованием
Про квантование в статье ни слова не сказано, на самом деле.
vanxant
04.12.2016 10:36-1И всё-таки frequency domain по русски — это «частотная область»
A3a
04.12.2016 13:39Возможно. Я перевёл это полагаясь на русскоязычную статью в википедии
vanxant
04.12.2016 20:31-2Переводчик гуманитарий, понятно.
Приведённая вами статья в википедии вообще не про то. Правильная статья, раздел «применение». Впрочем, вики, как обычно, безграмотна, и использует неизвестный науке термин «частотное пространство» (46 запросов в месяц по вордстату, что в 30 раз реже «частотной области»).A3a
04.12.2016 21:14Прошу прощения конечно, но не надо говорить о том, чего не знаете (о моём образовании имею ввиду)
Соглашусь, что в данном контексте пространство(область) подходит больше. Ошибся, бывает, но это не значит что можно делать преждевременные выводы.
1eqinfinity
07.12.2016 09:36+1неизвестный науке термин «частотное пространство»
Это необоснованное обобщенное утверждение. Не беритесь говорить за всю науку.
И потом, со смысловой точки зрения «частотное пространство» точнее «частотной области». Частотная область это, например, от 10 до 50 КГц, понимаете, да? Это некоторая область частот в частотном пространстве. Вы, вероятно, сможете привести в пример какой-нибудь советский талмуд с «областями», но лично я не сторонник подерживать традиционные семантические ошибки.
А вот где переводчик ошибся, так это в расстановке точек после единиц веса.
perfect_genius
04.12.2016 11:14Сколько было статей на Хабре про энтропию, читал и в Вики и в Сети, никак не мог понять. А теперь… Я правильно понимаю, что энтропия — это всего лишь
минимальное количество единиц, которое нужно использовать, чтобы представить все элементы данных.
?A3a
04.12.2016 11:23Не совсем. Термин энтропия используется в разных областях, если обобщить, то это мера неопределённости и хаотичности в соответсвующих областях. Но в статье идёт речь только об информационной энтропии
vanxant
04.12.2016 12:56На пальцах лучше так: количество информации (в сообщении, файле и т.д.) равно длине архива, сделанного из этого сообщения/файла/… неким идеальным архиватором. Измеряется в битах, байтах и т.д.
Энтропия — это мера неопределённости ваших знаний о некотором объекте или системе, т.е. объём информации, которую вы не знаете. Прочтение сообщения с количеством информации N bit уменьшает энтропию (ваше незнание) на эти же N bit. Соответственно, энтропия объекта/системы равна количеству информации (длине заархивированного сообщения), полностью описывающей его/её состояние.
Godless
06.12.2016 17:50Спасибо за перевод.
4 раза перечитывал книгу Методы сжатия данных в бумажном варианте еще в универе. Некоторые алгоритмы очень изящны и красивы. Очень рекомендую всем интересующимся.
ValdikSS
Интересно, конечно, но описываемые в статье методы самые базовые, и появились и использовались задолго до H.264, в MPEG-2, например.
A3a
Соглашусь, большинство описанного не относится только к H.264 и поэтому может стоило назвать статью по другому, но оставим это на совести автора, сама статья мне показалась полезной.
uSasha
Классная статья, спасибо за перевод!