🔍 КАК ЭТО УСТРОЕНО

Почему фильм в HD весит меньше одной фотографии в секунду

Если бы видео хранило каждый кадр как отдельную фотографию, фильм весил бы терабайты. Но он весит гигабайты. Секрет — в том, что соседние кадры почти одинаковы, и хранить их целиком не нужно.

Прикиньте на салфетке: тридцать фотографий в секунду на два часа — и фильм должен весить терабайты. Но он умещается в гигабайты, и весь фокус в одном наблюдении.
Соседние кадры видео почти неотличимы друг от друга. Зачем хранить каждый целиком, если можно записать только то, что изменилось?

Видео — это последовательность картинок, мелькающих десятки раз в секунду. Казалось бы, храни каждый кадр как JPEG — и готово. Но посчитаем: даже сжатый кадр весит сотни килобайт, кадров тридцать в секунду, фильм идёт два часа. Выходят терабайты. В реальности фильм в неплохом качестве — это пара-тройка гигабайт. Откуда такая разница? Из главной идеи видеосжатия: хранить не кадры, а изменения между ними.

Соседние кадры — почти близнецы

Посмотрите на любые два подряд идущих кадра. Человек чуть сдвинул руку, машина проехала пару пикселей, остальное — фон, небо, стены — не изменилось вовсе. Значит, второй кадр почти полностью предсказуем по первому. Хранить его целиком — расточительство.

Поэтому видеокодек делит кадры на два сорта:

  • Ключевые кадры — полноценные картинки, сжатые сами по себе, примерно как JPEG. Они тяжёлые, но встречаются редко.
  • Промежуточные кадры — не картинки, а инструкции: «возьми предыдущий кадр и вот что в нём поменяй». Они лёгкие, и их большинство.

Этот приём и называют межкадровым сжатием: основная экономия рождается из сходства соседних кадров.

Компенсация движения: следим за блоками

Но кодек идёт ещё дальше. Если машина просто переместилась, её пиксели не изменились — они переехали. Зачем перерисовывать машину заново? Достаточно сказать: «этот блок пикселей из прошлого кадра сдвинулся вправо на столько-то». Такой указатель называется вектором движения, а сам приём — компенсацией движения.

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

Тип кадраЧто хранитВес
ключевойвсю картинку целикомбольшой
промежуточныйсдвиги блоков и мелкие правкималенький

Почему статичное видео весит меньше динамичного

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

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

Зачем вообще ключевые кадры

Возникает вопрос: если промежуточные кадры такие лёгкие, почему не сделать один ключевой в начале, а дальше сплошные изменения? Из-за перемотки. Чтобы показать кадр на тридцатой минуте, плеер должен от ближайшего ключевого кадра «доиграть» все изменения. Будь ключевой кадр один в начале — пришлось бы пересчитывать полчаса видео ради одного стоп-кадра. Поэтому ключевые кадры расставляют регулярно, раз в пару секунд: это компромисс между размером файла и возможностью быстро прыгнуть в любую точку.

Так что видео «весит меньше, чем кажется» не из-за магии, а из-за честного наблюдения: мир на экране меняется медленно, и хранить стоит только перемены.

#видео#данные#кодеки#межкадровое#сжатие