Пишу, по большей части, про историю, свою жизнь и немного про программирование.

MJPEG, MPNG, MGIF, MSVG

Я вчера показывал вам «телевизор» про фестиваль в Самаре. Сделано очень просто — уменьшил все сделанные там снимки до 66×44 и сконвертировал их в анимированный ГИФ. Мелковато, конечно, но что делать — ГИФ не очень-то предназначен для фотографических изображений и размер анимации сильно растёт с увеличением размера кадра. Для фотографий в интернете принято использовать формат JPEG.

У JPEG есть свой формат анимации, если так можно выразиться, а точнее — скорее простенький формат видео, так как формат анимации, в моём представлении, помимо кадров должен содержать себе какую-то метаинформацию о кадре, например, задержку перед появлением следующего кадра. Этот формат — разновидность MJPEG (motion JPEG).

Мне давно хотелось посмотреть что у этого формата внутри, сегодня наконец посмотрел. Всё оказалось крайне просто.

В данном случае, MJPEG — формат стримминга (потоковой подачи) видео. Собственно, это даже не формат, а простое соединение JPEG и специального заголовка «multipart/x-mixed-replace», которым может применяться для стриминга чего угодно. Можно, например, подавать не JPEG, а PNG и «изобрести» формат видео MPNG, а то и M(JPEG+PNG+GIF), картинки разных форматов можно перемешивать в любых пропорциях.

Смысл этого заголовка — содержимое которое пришло раньше заменяется тем, что пришло позже. То есть MJPEG — это просто последовательность картинок, у которых этим заголовком указано — когда приходит следующая картинка, ею надо заменить предыдущую. Внутри выглядит это вот таким образом.

Content-type:  multipart/x-mixed-replace;boundary=СТРОКАРАЗДЕЛИТЕЛЬ

--СТРОКАРАЗДЕЛИТЕЛЬ
Content-type: image/jpeg
Content-length: 232311

…бинарное содержимое первой картинки…

--СТРОКАРАЗДЕЛИТЕЛЬ
Content-type: image/jpeg
Content-length: 47474

…бинарное содержимое второй картинки…

СТРОКУРАЗДЕЛИТЕЛЬ надо выбирать так, чтобы она не встретилась в бинарных данных изображения.

Браузерам этот заголовок достался от фирмы Нетскейп, которая когда-то (ещё в версии 1.1) добавила её поддержку в свой браузер. «Микрософт», будучи конкурентом «Нетскейпа», поддержку заголовка в браузер не внедрила. Остальные браузеры заголовок понимают, но каждый немного по-разному.

Например для «Оперы», нужно выдавать данные с задержкой, то есть показали один кадр, ждём пару секунд, ничего с сервера не отдаём, потом следующий. Иначе, «Опера» «хитрит» — показывает следующий кадр, не дожидаясь загрузки предыдущего. Если канал хороший, то мы увидим только последний кадр.

«Файрфокс» единственный, кто хорошо справляется с тем, что кадры могут быть разных размеров — он отображает их правильно, «Опера» масштабирует по первой картинке, «Хром» и «Сафари» глючат — иногда пропускают кадр, иногда ничего не показывают, иногда показывают нормально.

Самое приятное в этом формате — что все современные браузеры считают его картинкой, то есть тег IMG его преспокойно показывает.

Любопытно, что браузеры позволяют сжимать содержимое всего файла и даже каждого кадра отдельно, то есть можно в заголовке кадра поставить «Content-encoding: gzip» и сжать кадр гзипом. Это полезно, если захочется сделать MSVG, например. Ведь SVG-изображения хорошо сжимаются.

Так что, если вы задумались сделать аналог какого-нибудь хостинга анимированных ГИФ и вам наплевать на «Эксплорер» (я посмотрел, девятая версия не поддерживает), сделайте ещё и поддержку MJPEG/MPNG.

11 комментариев
Stac (stacmv.ya.ru) 2011

Крутотенюшка!

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

А как ведет себя IE? Вообще ничего не показывает?

Евгений Степанищев (bolknote.ru) 2011

Комментарий для stacmv.ya.ru:

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

Хм, в принципе можно. Только надо учитывать, что картинка заменяется, а не накладывается.

А как ведет себя IE? Вообще ничего не показывает?

Показывает, что картинка битая. Если бы у меня IE был под рукой, можно было бы поэкспериментировать. Вполне возможно, что IE можно «убедить» показать хоть что-то :)

Roman Ryltsov (alax.myopenid.com) 2011

Комментарий для Евгения Степанищева:

Первый раз встречаю формулировку «mJPEG» — так еще никто не называл :) Обычно это M-JPEG. Motion JPEG, кстати, тоже неудачное название, так как на заре нелинейного монтажа под этим термином понималось иное, а именно — видеоизмененная кодировка JPEG несовместимая той, что нам известна сейчас.

Евгений Степанищев (bolknote.ru) 2011

Комментарий для alax.myopenid.com:

Вот я что-то сам не знаю почему я букву «m» маленькой написал :) А  «MJPEG» пишут часто, в «Википедии» например.

Motion JPEG, кстати, тоже неудачное название, так как на заре нелинейного монтажа под этим термином понималось иное, а именно — видеоизмененная кодировка JPEG несовместимая той, что нам известна сейчас.

MJPEG — это любой формат видео, где каждый кадр кодируется в JPEG без учёта разницы между кадрами.

Евгений Степанищев (bolknote.ru) 2011

Комментарий для alax.myopenid.com:

Сейчас поменяю букву :)

Roman Ryltsov (alax.myopenid.com) 2011

Комментарий для Евгения Степанищева:

<blockquote>MJPEG — это любой формат видео, где каждый кадр кодируется в JPEG без учёта разницы между кадрами. </blockquote>

Ну это не совсем так. Еще до появления x-mixed-replace в системах нелинейного монтажа использовался другой Motion JPEG, где каждый кадр был почти JPEG, но не JPEG.

Евгений Степанищев (bolknote.ru) 2011

Комментарий для alax.myopenid.com:

<blockquote>

Как мне ещё написать, что HTML писать не надо? :-(

Ну это не совсем так. Еще до появления x-mixed-replace в системах нелинейного монтажа использовался другой Motion JPEG, где каждый кадр был почти JPEG, но не JPEG.

Вполне может быть, я не знаю.

Roman Ryltsov (alax.myopenid.com) 2011

Комментарий для Евгения Степанищева:

<blockquote> Извини, даже подсказка ж есть...

В интернете MJPEG имел ограниченное применение из-за неподдержки IE’ом, но тем не менее с тех еще давних пор не почил в истории из-за того, что был подхвачен производителямо оборудования и добрая половина IP камер умеет отдавать видео в том числе и так.

Но еще до этого времени профессиональное оборудование видеозахвата уже реализовывало сжатие в железе (скорость работы винчестеров не позволяла писатьь видео бес сжатия) и там были свои особенности. То ли из-за особенностей «железной» реализации, то ли еще из-за чего, часть оборудования или это было повально использовала модификацию формата — одна из таблиц была статической и исключалась из картинки, соотвественно кадр был чуть меньше (не думаю, что это было принципиально даеж тогда), но при этом оборудование тех времен вполне могло работать «в железе» с таким видеопотоком. Вот это все безобразие называлось так же Motion JPEG’ом (M-JPEG, MJPEG, MJPG).

С увеличением мощностей, от этой затеи быстро отказались, а server push JPEG over HTTP наоборот постепенно набрал обороты. Правда, сейчас эта технология опять является аутсайдером. Для передачи видео по сети стандартным является протокол RTP, в съемке JPEG сильно потеснен MPEG-4’ым. Но этот M-JPEG все еще жив благодаря своей простоте и врядли быстро растратит эту популярность.

Евгений Степанищев (bolknote.ru) 2011

Комментарий для alax.myopenid.com:

Даже PSP поддерживает два вида MJPEG ( http://ru.wikipedia.org/wiki/PSP ):

Motion JPEG Linear (PCM)
Motion JPEG Linear (μ-Lau)

Roman Ryltsov (alax.myopenid.com) 2011

Комментарий для Евгения Степанищева:

Даже PSP поддерживает два вида MJPEG ( http://ru.wikipedia.org/wiki/PSP ):
Motion JPEG Linear (PCM)
Motion JPEG Linear (μ-Lau)

Это бессмысленный набор слов. JPEG относится к видео, PCM и μ-Lau (правильно: μ-Law) — термины из мира аудио.

Так что это на wiki какая-то бессмысленная цитата, видимо поулчившаяся после какого-то неудачного перевода.

Скорее всего речь идео о том, что PSP умеет проиргывать файлы AVI, в которых видео часть — MJPEG, а аудио часть — PCM или ADPCM типа μ-Law.

Евгений Степанищев (bolknote.ru) 2011

Комментарий для alax.myopenid.com:

Наверное так, да.