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

Начнем с того, что медиа-информацию (видео и аудио) необходимо хранить в цифровом виде, и хорошо бы еще и в сжатом. Этим занимаются кодеки (codec, coder-decoder). Они переводят медиа-информацию в цифровой поток и обратно.

codecs

Надо сказать, что формально кодек — это реализация стандарта кодирования/декодирования. Т.е. программа или алгоритм. Но иногда кодеком называют стандарт кодирования.

Стандарты кодирования, как правило, оставляют нахождение алгоритмов для реализации этих стандартов разработчикам, и кодеки разных производителей, реализующие один и тот-же стандарт, могут сильно различаться по скорости работы и качеству при одинаковом битрейте. Понятие «качества», конечно, весьма субъективно, и мнение о том, какой кодек качественнее у разных людей разные.

Кодеки бывают с потерей качества (lossy), бывают без потери качекства (lossless). Кодеки без потери качества сжимают до некоторого теоретического предела. Предел этот большой и медиа занимает много места. Например, час музыки — 400 МБайт. Тут, конечно, зависит от частоты сэмплирования, дискретизации (для аудио), размера картинки, количества кадров в секунду (для видео), но все равно, в среднем получается много. Кодеки с потерей качества могут сжать как угодно сильно, но за счет, как не трудно догадаться, потери в качестве.

loss

Примеры кодеков: H.264/MPEG-4 AVC, Theora, VP6, MPEG-2 Audio Layer 3. Первые три — видео-кодеки, последний — аудио-кодек. Перечислены, разумеется, далеко не все распространенные.

Цифровой поток, созданный энкодером (кодирующей частью кодека), хорошо бы как-то хранить. Также, хорошо бы хранить вместе видео-поток и аудио-поток. Ну и до кучи, хранить там мета-информацию: длительность, описание, и т.д. Этим занимаются контейнеры (media containers). Их задача составить индекс, где какие части какого потока лежат, перемешать эти части так, чтобы снизить накладные расходы при параллельном чтении видео и аудио потоков, расставить индексы соответствия кадров отступам в байтах и т.д.

container

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

Примеры контейнеров: AVI, MPEG-4 Part 14 (mp4), Matroska, Ogg.

Довольно часто новые контейнеры и кодеки создавались руководствуясь NIH-принципом, но некоторые все-таки имеют особенности и оптимизированы для той или иной области. Например, изначально flv контейнер был разработан для облегчения встраивания его в swf файлы и способности нести screenshare кодек, созданный специально для передачи видеопотока с монитора компьютера. Также, flv содержит мета-информацию с индексом кадров, что удобно для «перемотки» видео при отдачи его при помощи progressive http download. Конечно, надо заметить, что это не единственный контейнер, позволяющий такое.

Это нас подводит к вопросу потокового вещания через интернет. Т.к. далеко не все маршрутизаторы готовы участвовать в IGMP, то мультикаст в интернете не работает. Поэтому для каждого клиента выделается отдельный поток данных и если даже несколько клиентов из одной сети захотят смотреть один и тот же синхронизированный поток, по сети уйдет несколько одинаковых экземпляров данных, по одному экземпляру на каждого.

Задача сервера потокового вещания — отдавать данные со скоростью, достаточной для просмотра, по возможности принимать команды старт, стоп, перемотка и отдавать поток соответственно. Поток отдается одним из потоковых протоколов, например, RTP/RTSP или RTMP. Потоковый сервер ничего не «знает» о самих медиа-данных, кроме мета-информации, по которой он может связать номера кадров с позицией в файле. У потокового сервера нет кодеков, поэтому, как он получил битовый поток из файла с контейнером, так он его и отдает.

Так что, потоковый протокол в некотором роде является контейнером для медиа-данных.