Немного о lossless кодировании видео в Linux - сжатие видео без потерь

Некоторое время назад была потребность в том, чтобы сжать видеофайл без потерь в Linux (lossless compression) и воспроизводить сжатый фильм без пропуска кадров. Задача в меру прикладная, и может быть, кому-нибудь будет интересно.

Итак, мы имеем установленный mencoder в Debian GNU/Linux и настойчивое желание сжимать видео без потерь.

Сжимаем видео с помощью Mencoder
Для этого мы отобрали пару кодеков с lossless и начали сжимать наш видеоролик. Исходно в нашем распоряжении был видеоролик размером 341 Мб, в котором полутоновая картинка перемещалась по экрану. Нужно было сжать без потерь ролик так, чтобы он и места занимал немного, и воспроизводился без торможений.


Сжатие FFV1
Сначала сжимали кодеком FFV1 командой:

mencoder -ovc lavc -lavcopts vcodec=ffv1 video-before.avi -o video-compressed-ffv1.avi
Сжалось до 18Мб, что очень хорошо. Однако при попытке такой сжатый файл воспроизвести, возникли проблемы: Mplayer (как и другие) сильно грузит процессор и видео не успевает воспроизводиться с заданным FPS. О том, какие страдания были с воспроизведением и как мы их героически решали, будет сказано ниже.


Сжатие huffyuv
Ещё один метод сжатия без потерь, но жмёт он хуже, чем FFV1, зато быстрее воспроизводится и меньше грузит процессор. При этом использовали mencoder для сжатия huffyuv с параметрами:
mencoder -ovc lavc -lavcopts vcodec=ffvhuff:vstrict=-1:pred=2:context=1:format=422p video-before.avi -o video-compressed-ffvhuff.avi
Получилось видео на 99Мб, что тоже неплохо. Однако при воспроизведении оказалось, что происходит конвертирование в другое цветовое пространство 420p и мы решили отказаться от такого финта:
mencoder -ovc lavc -lavcopts vcodec=ffvhuff:vstrict=-1:pred=2:context=1 video-before.avi -o video-compressed-ffvhuff-420.avi
при этом сэкономили ещё почти 20 Мб - фильм стал занимать 80Мб и воспроизводиться чуть глаже.

Остановившись на сжатии huffyuv без опции format=422p, мы стали перебирать варианты воспроизведения видео с минимальными тормозами. История на этом не кончается...


Воспроизведение видео с помощью Mplayer
Видео у нас сжато слабо, воспроизводить надо без задержек и железо скажем сразу весьма чахлое. Как проигрывать видео в таких условиях?

Перво-наперво, используем замечательные возможности Mplayer по выводу видео куда и на что угодно: поэкспериментировать с параметром -vo было здравой идеей, и через некоторое время мы остановились на варианте -vo gl и -vo sdl для нашей задачи. Однако иксы - это хорошо, но хочется выводить видео на чёрный экран без всяких засветок.

Далее, чтобы отвязаться от дисковой подсистемы как можно больше, используем возможность Mplayer кешировать видео:
mplayer -vo gl -cache 65535 -cache-min 98 video-compressed-ffvhuff.avi
Это значит, что мы просим сделать Mplayer кеш на 64Мб и заполнять его не менее чем на 98%. Это сильно помогло делу, но это ещё не всё.

Условия нашей задачи в меру экзотические: нужно проигрывать видео без масштабирования, "как есть", и желательно на чёрном экране без фона, с максимально возможной плавностью. Всё осложняется тем, что компьютер, на котором видео будет воспроизводиться, управляется Windows, и Linux там можно задействовать только в режиме LiveCD.

Идём дальше и привлекаем для наших нужд Knoppix. В арсенале его параметров загрузки есть неприметный параметр fb1280x1024 для работы с framebuffer. Замечательное дело, и мы решили этим воспользоваться. У нас теперь появилась графическая консоль, чёрная и мрачная, как полярная ночь.

Теперь, чтобы воспроизвести сжатое нами видео, копируем видео в память на Knoppix в каталог Desktop. После этого воспроизводим наше многострадальное видео в консоли так:
mplayer -vo fbdev -cache 65535 -cache-min 98 -quiet video-compressed.avi
Ключик -quiet нужен для того, чтобы при воспроизведении Mplayer не выводил статистику в бегущей строке. Всё, после этого получаем фильм на чёрном экране, который воспроизводится плавно и без затей.

Скорость воспроизведения в Mplayer
На всякий случай, если потребуется запускать фильм с другой скоростью, всегда можно попросить Mplayer изменить число кадров в секунду (вплоть до 1 кадра в секунду) так:
mplayer -fps 1 video-compressed.avi
Эта команда будет воспроизводить фильм со скоростью 1 кард в секунду.
(спасибо тов.linuxfreshman за наводку)

Выводы и ссылки
Воспроизведение таких огромных файлов с большим FPS (у нас это 40FPS) - действительно непростая задача, на любой ОС. Надеюсь, что эта заметка пригодится не только нам, но и тем, кто хочет сжимать видео без потерь. Напоследок приведу интересную ссылку на перечень кодеков, который имеется в арсенале libavcodec.

12 комментариев: |высказаться!| RSS-лента дискуссии.|
Анонимный комментирует...

Интересный материал!
Хотелось бы еще увидеть статью о lossless в звуке :)

Анонимный комментирует...

NVIDIA GF8xxx и старше с VDPAU и вот уже загрузка процессора при вопроизведении x264 не превышает и 10%. ^^

linuxfreshman комментирует...

хорошая статья.
Мне сейчас нравится запускать видеофайлы в mplayer без gui. Правда возник один вопрос. Как перематывать видео покадрово назад? Вперед это получается с помошью клавиши английской точки.

virens комментирует...

2 duke комментирует...
Интересный материал!
Спасибо. На самом деле, по lossless написано довольно мало, и нам пришлось потерзать старину Гугла, чтобы выискать нужные сведения.

Хотелось бы еще увидеть статью о lossless в звуке :)
Увы, но обработка звука находится вне поля моих профессиональных интересов. Большая часть файлов у меня в MP3 (ибо на дисках только в этом распространяется), часть в ogg (которые кодировал с CD-Audio).

2 Анонимный комментирует...
NVIDIA GF8xxx и старше с VDPAU и вот уже загрузка процессора при вопроизведении x264 не превышает и 10%.
Дык где ж я такое возьму!? :-)

2 linuxfreshman комментирует...
Правда возник один вопрос. Как перематывать видео покадрово назад?
Интересный вопрос. Быстрое загугление ответа не принесло: народ говорит, что жмите на точку . и мотайте вперёд, а про назад ссылаются на avidemux.

Нам назад пока не надо. Но иногда надо поменять скорость воспроизведения, что делается замечательным ключиком -fps

Анонимный комментирует...

А кодеком Nuppel никто не пользовался?

Анонимный комментирует...

virens комментирует...

2 Анонимный комментирует...
NVIDIA GF8xxx и старше с VDPAU и вот уже загрузка процессора при вопроизведении x264 не превышает и 10%.
Дык где ж я такое возьму!? :-)

По крайней мере GF8600 дешевле двухъдерного процессора, да и кушать электричества компьютер будет меньше. ^^

virens комментирует...

2 Анонимный комментирует...
А кодеком Nuppel никто не пользовался?
Нет. А какие от него бенефиты? Гуглёж показал навскидку, что явных как-то не просматривается. Буду благодарен за примеры.

Unknown комментирует...

Насколько знаю Nuppel это формат записи видео без потерь(но при желании потери можно внести). Mencoder для кодирования в этот формат использует кодек nuv.

Анонимный комментирует...

Кажется вы перепутали местами исходное видео и сжатое в команде, которая кодирует в FFV1.

Анонимный комментирует...

+1
перенесите -o перед последним видео
mencoder -ovc lavc -lavcopts vcodec=ffv1 video-before.avi -o video-compressed-ffv1.avi

virens комментирует...

2 Пуляев комментирует...
Насколько знаю Nuppel это формат записи видео без потерь
Спасибо, поглядим.


2 Анонимный и LeX комментирует...
перенесите -o перед последним видео
Да, есть промах :-)
Перенёс, обновил пост. Большое спасибо!

Анонимный комментирует...

Почему про x264 не ниписали? Он lossless умеет :)

Отправить комментарий

Подписаться на RSS-ленту комментариев к этому посту.