Создаем DIVX video с помощью mencoder

В данной статье описан процесс создания видеороликов DIVX при помощи програмы mencoder. Этот документ не есть пошаговое howto; он предназначен для тех, кто знаком с man mencoder и FAQ.

[Evgueni V. Gavrilov (aquatique at rusunix.org)]

Создаем DIVX video с помощью mencoder

Преамбула N1: все примеры даны относительно MPlayer 1.0pre3 или старше.
Преамбула N2: в качестве исходного материала будет использоваться DVD.
Преамбула N3: этот документ не есть пошаговое howto; он предназначен для тех, кто как минимум прочитал man mencoder и FAQ.


Терминология

Макроблок

Так называется сегмент изображения 16x16 пикселей, включающий себя 4 блока яркости размером 8x8 пикселей и 2 блока насыщенности размером 8x8 пикселей.

Quantizer

Quantizer — некоторое значение качественности макроблока, полученного с указанными настройками. Разбивая картинку на макроблоки кодек различные части изображения кодирует по разному, исходя из тех или иных условий и параметров. Значение 1 соответствует максимально возможному качеству кодирования макроблока. Значение 31 - минимально возможному качеству. О соотношении качество/размер нетрудно догадаться… ;-)

Для более точных рассчетов значений quantizer'а как правило используется 2 прохода кодирования. Во время первого прохода необходимая кодеку информация по каждому кадру собирается в файл. Во время второго прохода кодек использует собранную информацию для более точных рассчетов. По умолчанию этот файл называется divx2pass.log. Он представляет из себя текстовый файл, в который покадрово записаны усредненные метапараметры изображения для каждого кадра.

В старых версиях MPlayer/libavcodec файл divx2pass.log содержал в себе значения quantizer'а, которое можно было анализировать с помощью скрипта countquant.pl. Теперь в файле divx2pass.log на месте значений quantizer'а находится не совсем quantizer*118, поэтому для оценки значений quantizer'а следует к -lavcopts добавлять параметр psnr, в результате чего будет создаваться файл, содержащий соотношения сигнал/шум для каждого кадра, а также значения quantizer'а.

Получить гистограмму, подобную получаемой с помщью старого скрипта countquant.pl, можно воспользовавшись скриптом cq. Вот так примерно выглядит результат его работы:

$ cq psnr_195944.log

2:93762.51%52.64%
3:56237.49%47.36%

Из чего можно понять, что из 1499 кадров видео 937 из них (62.51%) имели среднее значение quantizer'а 2, а 562 (37.49%) — значение 3. В последнем столбике находится средневзвешанная величина наоборот. :-)

Еще один полезный скрипт называется calcbpp.pl: он высчитывает показатель под названием «количество битов на пиксел» (bits per pixel) полученного видео. В достаточно усредненном виде шкала влияния значений этого параметра на визуальное восприятие выглядит так:

значение bppВизуальная характеристика видеоряда
<= 0.10УЖЫС
<= 0.15Очень плохое качество
<= 0.20Будут видны края макроблоков
<= 0.25Хорошее качество
> 0.25Визуально качество не отличается от видеоряда с bpp < 0.25
> 0.30Можно использовать более высокое разрешение

Как уже было отмечено, эта шкала достаточно усреднена. Так фильм с малым количеством динамичных сцен и/или большим количеством несложных однородных кадров и/или с большим количеством сцен с черным фоном может иметь отличное качество и при bpp==0.15, и наоборот, фильму, переполненному сложными текстурами и подвижными часто сменяющимися сценами, будет не всегда достаточно и 0.30 для хорошего качества.


Использование кодека lavc

Видео с постоянным значением quantizer'а

Как правило, современные фильмы на чистых двухслойных DVD не требуют долгих раздумий на то, каким образом их пожать. В большинстве таких случаев на мой взгляд оказывается достаточным использовать постоянное значение quantizer'а (bitrate в этом случае получается переменный): vqscale=2. -lavcopts при этом выглядит например так: vcodec=mpeg4:mbd=2:keyint=300:v4mv:vqscale=2:mpeg_quant:trell:cbp:mv0:qpel (неописанные параметры пока игнорируем).

Полученный таким образом фильм оригинального разрешения 720x576 и соотношения 16:9 на мониторе с соотношением 4:3 будет иметь размеры 1024x576, а фильм с разрешением 720x480 будет иметь размеры 854x480, чего более чем достаточно, даже если не смотреть его в полный экран.

MPEG видео, который лежит на DVD также можно оценивать с помощью bpp, поэтому этот метод может оказаться малоэффективным для фильмов с низким bpp (большая длительность, низкий поток) или фильмов, изображение в которых зашумлено.

Видео с переменным значением quantizer'а

В пределах кадра значения quantizer'а для разных макроблоков могут иметь различные значения. Это порой позволяет существенно сократить размер получаемого файла и/или сконцентрировать внимание кодека на те участки, которым требуется более качественное изображение и использовать макроблоки с худшим качеством на участках с малой детализацией или подвижностью, той или иной степени освещенности.

Крайне рекомендуется использовать 2 прохода при создании видео с переменным значением quantizer'а, даже если планируется создать видео небольшого размера с низким качеством. Для двухпроходного кодирования к lavcopts добавляются параметры vpass=1 и vpass=2 в первом и втором проходе соответственно.

Начнем с параметров, которые определяют работу кодека в целом:

vbitrate

Это собственно bitrate для видеопотока. Задача quantizer'а уместить полученную совокупность макроблоков в этот поток. Это еще не означает, что полученный файл будет содержать видео именно такого потока. Это всего лишь предел, за который quantizer'у запрещено перешагивать. При кодировании чрезмерно динамичных фильмов с постоянными сменами кадра не стоит бояться установить этот параметр в 1800 или даже 2400. Посмотрев средневзвешанные значения quantizer'а можно оценить, насколько близко quantizer подошел к пределу.

vqmin, vqmax

Как можно догадаться из названий параметров — это минимально и максимально допустимые значения quantizer'а. По умолчанию этот диапазон 2-31. Попробуйте сжать кусочек видео с постоянным quantizer'ом 2, а затем 31. Сравнив полученные результаты можно определиться в пределах. ;-) Я редко использую максимальное значение более 10 при кодировании качественных и высокодинамичных фильмов.

vme

Алгоритм оценки движения макроблоков. На одних фильмах может вполне хорошо себя показывать алгоритм по умолчанию (vme=4), на других — экспериментальный алгоритм X1 (vme=5). Пробуйте на кусках видео и оценивайте размеры файлов и гистограмму значений quantizer'а. Не забудьте посмотреть полученные результаты. :-)

vqcomp

Этот параметр регулирует «компрессию» значений quantizer'а между кадрами. По-умолчанию он равен 0.5, что не всегда достаточно для мгновенной смены режима quantizer'а между сценами либо на высокодинамичных сценах, а следовательно, сцена с высокой детализацией при появлении после сцены с низкой детализацией будет сначала размыта либо нечетко отрисована. В таком случае я бы порекомендовал сделать несколько пробных кусков со значениями от 0.6 до 0.8 и посмотреть на полученное видео и значения quantizer'а. Другая сторона медали — скорость снижения потока на малоподвижных или неподвижных сценах. То есть если этому параметру присвоено высокое значение (> 0.7), то изменение потока в сторону уменьшения будет происходить медленнее, нежели чем со значнием по умолчанию 0.5.

vqblur

Этот параметр указывает, насколько нужно усреднять значения quantizer'а относительно значений предыдущих кадров. По умолчанию он равен 0.5, т.е. усредняет наполовину. В некоторых ситуациях это может привести к уродованию облаков, морской пены, брызг и т.п. Посему в зависимости от содержания его можно выставить в 0.25 а то и того меньше.

mbd

Алгоритм кодека, принимающий решение, каким будет макроблок на том или ином основании. Рекомендую использовать значение 1, если планируете создавать не очень качественное видео (при таком алгоритме макроблок, требующий меньше всего битов будет выбран), и значение 2, если планируете создать видео хорошего качества.

trell

Этот параметр заставляет находит наиболее оптимальный режим для каждого макроблока, исходя из количества ошибок (разницы оригинального и сжатого макроблока) на основании отношения освещенности к битрэйту и размера полученного макроблока в разных режимах. Замедляет кодирование, но в результате получаются более похожие на оригинал макроблоки.

cbp

Грубо говоря более придирчивый trell. Может использоваться только с trell.

mv0

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

qpel

Этот параметр позволяет создавать некоторого рода компенсацию движения макроблоков за счет использования в расчетах до ¼ каждого пиксела. Задействовать или не задействовать qpel зависит исключительно от динамичности фильма: в динамичных фильмах эта возможность позволит уменьшить размер и сделать движения макроблоков более естественными. Если же картинка преимушественно статичная — qpel только увеличит время кодирования, не оказав видимого влияния на результат.

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

v4mv

Этот параметр позволяет каждому макроблоку иметь 4 вектора движения. Я бы рекомендовал использовать эту возможность везде, за исключением некоторых видов анимации. Вкупе с qpel эта возможность позволяет кодеку лучше определять движения макроблоков, а следовательно и иметь меньший размер.

mpeg_quant

Этот параметр указывает на использование MPEG quantizer'а вместо H.263 (который стоит по умолчанию). Рекомендуется (за исключением случая, когда вы создаете видео для потокового вещания).

vlelim & vcelim

Каждый макроблок содержит в себе блоки яркости и насыщенности. Эти параметры указывают пороги изменений яркости и насыщенности, не достигнув которых значения quantizer'а останутся прежними для блоков яркости и насыщенности. Другими словами, насколько чувствителен кодек к изменениям яркости и насыщенности в макроблоке, и при каких изменениях яркости и насыщенности пересчитывать весь макроблок.

Порог изменения яркости (vlelim) желательно выставлять в отрицательное число: чем выше его абсолютная величина, тем более аморфен будет кодек к изменению яркости в макроблоке. Естественно, это уменьшит размер получаемого файла и увеличит различие между макроблоками, сделав их очертания и изменения картинки более видимыми и дискретными на каком-то промежутке времени.

Соответственно, порог изменения насыщенности (vcelim) желательно устанавливать в положительное число.

Одним из важных факторов при установке этих параметров является соотношение абсолютных величин, которое не должно быть слишком большим. Будет неплохо, если это соотношение будет в районе 2.0. Увеличивать соотношение свыше 3.0 практически не имеет смысла, ибо в таком случае quantizer может «свалится» в минимальное или максимальное допустимое значение, либо переход от уменьшения света к потемнению будет очень резким, что увеличит эффект квадратиков (особенно на градиентных текстурах).

Неплохими парами этих параметров являются эти:

vlelimvcelim
-23
-35
-47

Как видно из этого набора, желательно избегать одинаковых абсолютных величин для того, чтобы изменения насыщенности реже учитывались кодеком, нежели изменения яркости (за исключением пары -1 и 1 которая придаст кодеку максимальную чувствительность к изменениям блоков яркости и насыщенности). Это опять же позволяет более точно передать цвет сложных текстур, особенно с градиентом, избавиться от следов на изображении.

Чем ближе абсолютные значения этих параметров к 0, тем чувствительнее будет кодек к измененям яркости/насыщенности, и, возможно, тем чаще блоки яркости/насыщенности макроблока будут изменяться (а следовательно и пересчитываться весь макроблок).

Маскировка

Маскировка является одним из основных средств, позволяющих снизить (ухудшить) значения quantizer'а в тех или иных макроблоках, предоставив таким образом освобожденные единицы потока тем макроблокам, которые в них больше нуждаются. Не стоит устанавливать этим значениям слишком большие величины, иначе это может привести к существованию максимально качественного макроблока по соседству с минимально качественным там, где в этом не было необходимости, ибо кроме блоков освещенности в макроблоке есть еще и блоки насыщенности. Еще одним артефактом, порожденным большими значениями этих параметров, будет эффект оволосения/разводов.

Маскировка светлых и темных участков: lumi_mask & dark_mask

Как можно понять из названий — маскировка темных и светлых участков.

В большинстве случаев значения от 0.01 до 0.15 дают неплохой результат. Попробуйте создать небольшой кусочек видео с lumi_mask=1.0, а затем с dark_mask=1.0 — это позволит лучше понять эффект маскирования на основании освещенности. Также рекомендуется сравнить гистограммы распределения значений quantizer'а видеопотока с маскировкой и без. Не следует сильно (> 0.03) маскировать и светлые, и темные участки одновременно.

Маскировка сложности макроблоков: scplx_mask & tcplx_mask

При обсчете макроблока и выборе значения quantizer'а для него учитывается сложность содержащегося в нем изображения. Различают 2 типа сложности макроблока:

  • текстурная или пространственная сложность макроблока, которая зависит от разницы между содержанием текущего и предыдущего макроблока
  • векторная или временная сложность, которая, как можно понять из названия, зависит от изменения вектора движения макроблока

Если векторную (временную) сложность макроблока при умеренной динамике можно достоверно передать с помощью 4 векторов движения макроблока (v4mv) в совокупности с qpel, то текстурную сложность макроблока можно достоверно передать только путем увеличения quantizer'а. То есть именно этот параметр позволит некоторым образом выборочно размыть детализацию для того, чтобы использовать более высокие значения quantizer'а там, где без этого не обойтись.

Начать можно с небольших значений диапазона от 0.01 до 0.15. Артефакты, порождаемые большими значениями этих параметров, визуально сходны с предыдущим типом маскировки.

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

Маскировка внутри макроблока — p_mask

Этот тип маскировки имеет меньше всего артефактов, ибо он маскирует сложность всего содержимого макроблока. Устанавливать и оценивать результат следует также, как и с вышеупомянутой маскировкой.

naq (normalize adaptive quantization)

Как можно понять из аббривеатуры, этот параметр используется для нормализации значений quantizer'а в макроблоках всего кадра, если значение вышло за рамки допустимых границ (vqmin/vqmax/vbitrate) из-за использования маскировки (lumi_mask/dark_mask/scplx_mask/tcplx_mask). Нормализацией значений quantizer'а стоит пользоваться очень осторожно. Лучше будет, если предварительно создать видеоряд с нормализацией и без нормализации. Это позволит более визуально оценить влияние нормализации. Как правило в случаях, если маскировка используется неинтенсивно, можно обойтись и без нормализации, но все же, в большом количестве случаев (особенно в высокодинамичных и ярких фильмах) эта возможность оказывается очень полезной.

B–frames (vmax_b_frames)

B–frames — двунаправленные кадры как правило с несколько худшим разрешением, нежели у I/P–кадров. Они могут помочь, если требуемое качество видео не умещается в требуемый поток. Такие кадры вставляются между обычными кадрами. Я крайне редко использую больше 1 B-кадра между обычными (P) кадрами. 1 B-кадр можно без опаски использовать для видео с чрезстрочностью, однако в случае с progressive NTSC нужно быть внимательнее.


Использование XviD

Кодек XviD имеет несколько фундаментальных отличий от lavc. Основным отличием является подход, при котором XviD сам подбирает большое количество параметров, опираясь свойства изображения и основы визуального восприятия. Особенно это проявляется в случаях, когда требуемое видео не умещается в требуемый поток. Из этого вытекает небольшое количество параметров, передаваемых кодеку с помощью параметра -xvidencopts.

Существует 3 режима кодирования: постоянный bitrate, постоянный quantizer (VBR) и двупроходное кодирование. Первый режим используется, если указан только bitrate. Второй режим используется, если в xvidencopts присутствует параметр fixed_quant (например fixed_quant=2). Третий режим (двупроходное кодирование) используется в случае, если в xvidencopts присутствует параметр pass.

Основным параметром естественно является bitrate. Он ничем не отличается от vbitrate кодека lavc. :-)

XviD может создавать interlaced video. Для этого достаточно указать параметр interlacing. При этом если уменьшается размер оригинального изображения, не нужно забывать указывать, что interlace нужно сохранять. За это отвечает 3–ый параметр фильтра scale, например scale=640:480:1:0:50.

Еще одна полезная возможность — gmc (global motion compensation). Это позволяет кодеку определять неподвижные участки изображения на фоне подвижных, что может существенно сэкономить bitrate.

Параметр chroma_me позволяет использовать информацию из блока насыщенности для оценки движения макроблоков. Параметр chroma_opt позволяет использовать информацию из блока насыщенности в фильтрах. В зависимости от оригинального видео эти параметры могут быть как полезными, так и бесполезными.

Оценка движений макроблоков с использованием DCT по умолчанию отключена. Включается она установкой параметра vhq в значение, отличное от 0. Значения от 2 до 4 используют от умеренной до максимальной оценки движения макроблоков. Соответственно используя vhq=4 мы получаем очень медленное кодирование, но максимальную оценку движения макроблоков.

Параметр psnr как можно догадаться включает создание файла, содержащего отношение сигнал/шум, который потом можно использовать для оценки распределения значений quantizer'а.

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

Как видим, особо варьировать тут нечем, однако не стоит забывать про внешние фильтры mplayer. В случае с XviD они являются очень полезным инструментом.

max_bframes является аналогом параметра vmax_b_frames lavc. По умолчанию XviD создает не больше 2–х B–кадров. Я бы порекомендовал устанавливать его в 1, т.е. создавать не больше 1 B-кадра подряд.

Другие возможности

denoiser (шумоподавитель)

Я предпочитаю использовать высококачественный шумоподавитель (hqdn3d). Этот шумоподавитель в указанной ему мере сглаживает яркость:насыщенность:временное_движение, что предоставляет возможность кодеку создать макроблоки с более высоким значением quantizer. Временное движение в данном контексте обозначает некоторую недолгую подвижность в макроблоке, что очень часто встречается в фильмах, снятых со светопленки или в низкокачественных DVD.

Прежде чем пользоваться им, следует внимательно вглядеться в изображение, и выяснить, что следует сгладить.

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

interlacing

Различное видео с различными типами чрезстрочности обрабатывается по-разому. Так по-моему мнению снимать чрезстрочность PAL лучше с помощью libavcodec's deinterlace filter (-vf lavcdeint) или median deinterlacer (-vf pp=md).

В случае если в NTSC–video interlace используется вкупе с telecine, еще более выгодным вариантом будет фильтр softpulldown вместе с ivtc=1, или filmdint. Последний может быть запущен с параметром verbose=1, на основании чего можно понять последовательность полей и наличие telecine вообще :-). Вдобавок фильтр filmdint имеет более быструю реализацию обрезания краев изображения. Не забудьте указать оригинальное кол-во кадров в секунду — 23.976023976024 (24000/1001).

Очень важно при этом подсказывать кодеку, что исходное видео содержит чрезстрочность (interlacing) — ilme. При указании этого параметра оценка движения макроблоков будет производиться с учетом чрезстрочности, что даст результат в виде более четких и мягких движениях и отсутствии дискретности движения.

cropping (обрезание пустых мест)

Настоятельно рекомендую обрезать пустоту вокруг. Это связано с тем, что макроблоки по этим краям будут требовать для себя больший видеопоток, что естественно пойдет в ущерб качеству или размеру. В наборе видеофильтров есть прекрасный фильтр cropdetect, который «подскажет», какие параметры нужно передать фильтру crop. Однако не стоит забывать, что каждый макроблок имеет размер 16x16 пикселей, то есть ширина и высота обрезанного видео должны быть кратны 16. Лучше немного заехать на изображение, чем оставить черную полосу в 2-3 пиксела.

Взаимоисключения

Как известно, правила кроме исключений порождают и взаимоисключения. Наиболее выраженными взаимоисключения для lavc являются:

  • scplx_mask/tcplx_mask и deblocking фильтры (например из набора postprocessing)
  • большие значения при маскировке и trell

Примеры lavcopts/vf для двухпроходного кодирования

Чистый двуслойный DVD: Star Wars Episode II «Attack Of The Clones»:

  • -lavcopts vcodec=mpeg4:mbd=2:trell:cbp:mv0:vbitrate=3012:v4mv:vqmin=2:vqmax=9:mpeg_quant:vlelim=-3: vcelim=5:lumi_mask=0.02:dark_mask=0.06:p_mask=0.05:autoaspect:psnr
  • -vf filmdint=crop=720:352:0:64,hqdn3d=4:3:5

Подтемненный однослойный DVD: Resident Evil:

  • -lavcopts vcodec=mpeg4:mbd=2:mv0:vbitrate=2082:v4mv:vqmin=2:vqmax=9:mpeg_quant:vlelim=-3:vcelim=5: lumi_mask=0.02:dark_mask=0.06:scplx_mask=0.03:p_mask=0.07:autoaspect:psnr:naq:trell:cbp:qprd
  • -vf filmdint=crop=720:464:0:16,hqdn3d

Для просмотра на windows

  • BSPlayer: плэйер, у которого не едет крыша от v4mv; также среди его полезных свойств есть возможность устанавливать пользовательский aspect (соотношение сторон), что может быть удобно для просмотра video, оригинал которого имел соотношение сторон отличное от 1:1 (4:3), но во время кодирования черные края были обрезаны;
  • ffdshow: windows-вариант кодека libavcodec и XviD

Credits (литература)

При создании этого документа использовались man mencoder, документация из дистрибутива и кое-какие мысли умных людей из списка рассылки mplayer-users. Ну и конечно же собственный опыт. ;-)

© 2003-2004

Статья взята с сайта OpenNet.

[ опубликовано 31/05/2004 ]

Evgueni V. Gavrilov (aquatique at rusunix.org) - Создаем DIVX video с помощью mencoder   Версия для печати