7.5. Кодирование кодеком x264

7.5. Кодирование кодеком `x264`
Пред. | Глава 7. Кодирование с MEncoder | След.

## 7.5. Кодирование кодеком `x264`

`x264` — это свободная библиотека для кодирования H.264/AVC видео потоков. Перед началом кодирования Вы должны настроить MEncoder для его поддержки.

### 7.5.1. Опции кодирования x264

Начните, пожалуйста с просмотра раздела `x264` man страницы MPlayer'а. Этот раздел предполагается быть дополнением к странице man. Здесь Вы найдете быстрые подсказки о том, какие опции чаще всего интересуют большинство людей. Страница man более лаконична, но также более полна и порой намного лучше преподносит технические детали.

#### 7.5.1.1. Введение

Это руководство рассматривает две главные категории опций кодирования:

1. Опции, в основном влияющие на соотношение скорость-качество.

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

В конце концов, только Вы можете решать какие опции являются лучшими для Ваших целей. Решение для первого класса опций очень простое: надо только определить, считаете ли Вы, что разница в качестве оправдывает разницу в скорости. Для второго класса опций предпочтения могут быть значительно более субъективными и зависеть от большего числа факторов. Имейте в виду, что некоторые из опций категории "пользовательских предпочтений и специальных требований" могут все же иметь большое влияние на скорость или качество, но это не основное их предназначение. Часть опций из "пользовательских предпочтений" могут даже привести к изменениям, которые выглядят лучше для одних людей и хуже — для других.

Перед тем как продолжить, Вам придется понять, что это руководство использует только одну метрику качества: глобальный PSNR. Краткое описание того, что такое PSNR, смотрите в статье Википедии о PSNR. Глобальный PSNR — это последнее значение PSNR, выводимое на консоль, когда в `x264encopts` включена опция `psnr`. Каждый раз, когда Вы читаете утверждения о PSNR, за ними скрывается предположение, что используются одинаковые значения битпотока.

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

#### 7.5.1.2. Опции, затрагивающие, в основном, скорость и качество

- subq: Из всех опций, позволяющих выбирать между скоростью и качеством, `subq` и `frameref` (смотрите ниже), пожалуй, самые важные. Если Вы заинтересованы в тонкой настройке либо скорости, либо качества, эти две — первое, с чего Вам стоит начать. С точки зрения скорости, опции `frameref` и `subq` очень жестко взаимодействуют друг с другом. Опыт показывает, что с одним ссылочным кадром `subq=5` (настройка по умолчанию) расходует на 35% больше времени, чем `subq=1`. С 6 ссылочными кадрами эта величина достигает 60%. Эффект `subq` на PSNR выглядит довольно постоянным, в отличие от количества ссылочных кадров. Как правило, `subq=5` достигает значения глобального PSNR на 0.2-0.5 дБ большего, чем при `subq=1`. Обычно этого достаточно, чтобы заметить.

  `subq=6` — медленнее и дает лучшее качество при разумной цене. Если сравнивать с `subq=5`, он обычно дает на 0.1-0.4 дБ больший глобальный PSNR ценой потери 25%-100% скорости. В отличие от остальных уровней `subq`, поведение `subq=6` не так сильно зависит от `frameref` и `me`. Вместо этого, эффективность `subq=6` по большей части зависит от количества используемых B-кадров. При обычном использовании это означает, что `subq=6` в сложных, высокодинамичных сценах имеет большое влияние как на скорость, так и на качество, но в сценах с малым количествах движения она не имеет такого эффекта. Имейте в виду, что по-прежнему рекомендуется всегда устанавливать `bframes` в значение, отличное от нуля (смотрите далее).

  `subq=7` — самый медленный режим с наилучшим качеством. По сравнению с `subq=6` он, обычно, улучшает общий PSNR на 0.01-0.05 дБ ценой потери 15%-30% скорости. Поскольку соотношение качества и времени кодирования очень невелико, Вам следует использовать этот режим, только если боретесь за каждый бит, и время кодирования Вас не волнует.

- frameref: `frameref` по умолчанию установлена в 1, но это не значит, что ее стоит устанавливать в 1. Только увеличение `frameref` до 2 дает прирост PSNR примерно на 0.15дБ за счет уменьшения скорости на 5-10%; похоже, что это неплохая цена. `frameref=3` дает примерно 0.25дБ PSNR сверх `frameref=1`, что должно быть видимой разницей. `frameref=3` медленнее примерно на 15%, чем `frameref=1`. К сожалению, улучшение очень быстро сходит на нет. От `frameref=6` можно ожидать прироста PSNR лишь на 0.05-0.1 дБ по сравнению с `frameref=3` с дополнительной потерей 15% скорости. Выше `frameref=6` качество обычно увеличивается очень незначительно (хотя на всем протяжении этой дискуссии Вам следует иметь в виду, оно может значительно изменяться в зависимости от исходного материала). В довольно типичном случае `frameref=12` улучшит глобальный PSNR всего на 0.02дБ по сравнению с `frameref=6`, ценой 15%-20% скорости. При таких высоких значениях `frameref`, единственная действительно хорошая вешь, о которой может быть сказано, состоит в том, что дальнейшее ее увеличение почти никогда не будет вредить PSNR, но увеличение качества будет трудно даже измерить, не говоря уже о его заметности.

  ### Замечание:

  Увеличение `frameref` до чрезмерно высоких значений может и обычно наносит вред эффективности кодирования, если CABAC отключен. С задействованным CABAC (настройка по умолчанию), возможность установки `frameref` "слишком высоким" на данный момент выглядит слишком далекой, чтобы об этом беспокоиться, а в будущем оптимизации могут вообще убрать такую возможность.

  Если Вас заботит скорость, разумным компромиссом будет использовать низкие значения `subq` и `frameref` в первом проходе, а затем увеличить их во втором. Обычно, это обладает ничтожным отрицательным эффектом на конечное качество: Вы, возможно, потеряете вплоть до 0.1дБ PSNR, что должно быть слишком малой разницей, чтобы её заметить. Однако, различные значения `frameref` могут иногда повлиять на решение о выборе типа кадра. Скорее всего, это довольно редкие крайние случаи, но если Вы хотите быть точно уверенными, посмотрите, содержит ли Ваше видео полноэкранные периодически вспыхивающие изображения или очень большие паузы, которые могут стать причиной принудительной вставки I-кадра. Настройте `frameref` в первом проходе так, чтобы она была достаточно большой для содержания длительности цикла вспыхивания (или паузы). Например, если сцены вспыхивают и гаснут между двумя изображениями в течении трёх кадров, установите `frameref` равным 3 или выше. Эта проблема, возможно, очень редко появляется для живой съемки, но она иногда возникает при записи видео игр.

- me: Эта опция используется для выбора метода оценки движения. Изменение этой опции оказывает прямое влияние на соотношение скорость-качество. `me=dia` лишь на несколько процентов быстрее, чем поиск по умолчанию, ценой не больше 0.1дБ глобального PSNR. Значение по умолчанию (`me=hex`) — разумный выбор между скоростью и качеством. `me=umh` немного, вплоть до 0.1дБ, улучшает глобальный PSNR, соответствующее падение скорости меняется в зависимости от `frameref`. С высокими значениями `frameref` (например, 12 или около того), `me=umh` примерно на 40% медленнее, чем настройка по умолчанию `me=hex`. С `frameref=3`, падение скорости уменьшается до 25%-30%.

  `me=esa` использует исчерпывающий поиск, который работает слишком медленно для практического применения.

- partitions=all: Эта опция задействует использование сегментов 8x4, 4x8 и 4x4 в предсказанных макроблоках (в дополнение к стандартным). Ее включение приведет к довольно постоянной 10%-15% потере в скорости. Эта опция практически бесполезна для исходного материала, содержащего только небольшое движение, тем не менее, для некоторого высокодинамичного материала, особенно с большим количеством мелких движущихся объектов, следует ожидать прироста около 0.1дБ.

- bframes: Если Вы занимались кодированием с другими кодеками, то могли заметить, что B-кадры не всегда полезны. В H.264 это изменилось: есть новые техники и типы блоков, возможные в B-кадрах. Обычно, даже примитивный алгоритм выбора B-кадров может дать значимую выгоду для PSNR. Интересно заметить, что использование B-кадров обычно отчасти ускоряет второй проход, а также может ускорить однопроходное кодирование, если отключено адаптивное принятие решения о B-кадрах.

  С отключенным адаптивным принятием решения о B-кадрах (`nob_adapt` в `x264encopts`), оптимальное значение этой опции обычно не превышает `bframes=1`, иначе могут пострадать высокодинамичные сцены. С включенным адаптивным принятием решения о B-кадрах (поведение по умолчанию), можно безопасно использовать более высокие значения; кодировщик уменьшит количество B-кадров в сценах, где они повредят сжатию. Кодировщик редко решает использовать больше, чем 3 или 4 B-кадра; установка этой опции в любое более высокое значение не будет иметь большого эффекта.

- b_adapt: Заметьте: она включена по умолчанию.

  Когда эта опция включена, кодировщик будет использовать разумно быстрый процесс принятия решения для уменьшения количества B-кадров, используемых в сценах, которые от этого не сильно выиграют. Вы можете использовать `b_bias` для тонкой настройки того, насколько "счастлив" будет кодировщик использованию B-кадров. Потеря в скорости при использовании адаптивных B-кадров на данный момент весьма невелика, но таково же и потенциальное улучшение качества. Тем не менее, хуже от этого обычно не становится. Заметьте, что эта опция влияет на скорость и решение о типе кадра только в первом проходе. `b_adapt` и `b_bias` не имеют эффекта в последующих проходах.

- b_pyramid: С тем же успехом Вы можете включить эту опцию, если используете >=2 B-кадров; Вы получите небольшое улучшение качества без потери в скорости, как и говорит man руководство. Имейте в виду, что такое видео не может быть прочитано основанными на libavcodec декодерами, созданными ранее, чем примерно 5 Марта 2005.

- weight_b: В обычных случаях эта опция не дает большого улучшения. Однако, в проявляющихся или затухающих сценах взвешенное предсказание дает довольно большую экономию битпотока. В MPEG-4 ASP затухание обычно лучше кодируется последовательностью дорогих I-кадров; использование взвешенного предсказания в B-кадрах делает возможным преобразовать хотя бы часть из них в значительно более меньшие B-кадры. Потери в скорости кодирования минимальны, поскольку не требуется делать дополнительные принятия решений. Вдобавок, вопреки расхожему мнению, взвешенное предсказание не сильно влияет на требования декодера к CPU при прочих равных условиях.

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

- threads Эта опция позволяет породить потоки для параллельного кодирования на нескольких CPU. Вы можете вручную выбрать количество создаваемых потоков или, что лучше, установить `threads=auto` и позволить `x264` определить количество доступных CPU и выбрать соответствующее количество потоков. Если у Вас многопроцессорная машина, Вам следует всерьез задуматься об использовании этой опции, так как она может увеличить скорость кодирования линейно в зависимости от числа CPU ядер (около 94% на ядро), незначительно уменьшая PSNR (примерно 0.005 дБ для двухпроцессорной, 0.01 дБ — для четырехпроцессорной машины).

#### 7.5.1.3. Опции, относящиеся к различным предпочтениям

- Двухпроходное кодирование: Выше советовалось всегда использовать кодирование в два прохода, но все же существуют причины этого не делать. Например, если Вы захватываете TV трансляцию и кодируете в реальном времени, придется использовать однопроходный режим. К тому же один проход очевидно быстрее, чем два; если Вы используете точно такой же набор опций в обоих случаях, двухпроходной режим медленнее почти вдвое.

  Все же существует очень хорошие причины использовать кодирование в два прохода. Во-первых, управление битпотоком однопроходного режима не является телепатом и часто делает необоснованный выбор, потому что не может видеть общую картину. Например, предположим, что Вы имеете двухминутное видео, состоящее из двух независимых частей. Первая половина — очень динамичная сцена, продолжающаяся 60 секунд и требующая сама по себе битпоток примерно 2500 кбит/сек, чтобы прилично выглядеть. Сразу за ней следует гораздо менее требовательная 60-секундная сцена, которая хорошо выглядит при 300 кбит/сек. Предположим, Вы запросили битпоток 1400 кбит/сек; в теории этого достаточно для удовлетворения потребностей обеих сцен. В этом случае управление битпотоком в однопроходном режиме сделает пару "ошибок". Во-первых, оно установит битпоток в 1400 кбит/сек для обеих частей. Первая часть может оказаться чрезмерно квантованной, что приведет к недопустимо выглядящему и неоправданно блочному изображению. Вторая часть будет существенно недостаточно квантованной; она может выглядеть отлично, но цена битпотока для этого качества будет полностью неоправданной. Чего намного труднее избежать, так это проблемы перехода между двумя сценами. В первых секундах малодинамичной части квантователь будет чрезвычайно превышен, потому что управление битпотоком все еще ожидает встретить такие же требования к битпотоку как и в первой части. Этот "ошибочный период" с чрезвычайно превышенным квантованием будет выглядеть раздражающе неприятно и использовать на самом деле меньше, чем 300 кбит/сек, требуемых ему для того, чтобы прилично выглядеть. Существуют способы смягчить эффект от подобных подводных камней однопроходного режима, но они могут иметь склонность к усилению неверного предсказания битпотока.

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

  Более того, два прохода занимают не двойное время по сравнению с одним. Вы можете настроить опции первого прохода на более быструю скорость и низкое качество. Если хорошо выберете опции, Вы получите очень быстрый первый проход. Полученное качество во втором проходе будет несколько ниже, потому что предсказание размера менее точно, но разница в качестве обычно слишком мала, чтобы быть заметной. Попробуйте, например, добавить `subq=1:frameref=1` в `x264encopts` первого прохода. Затем, при втором проходе, используйте более медленные, с лучшим качеством опции: `subq=6:frameref=15:partitions=all:me=umh`

- Кодирование в три прохода? x264 предоставляет возможность делать желаемое количество последовательных проходов. Если Вы указали `pass=1` при первом проходе, используйте затем `pass=3` в последующем проходе, этот проход будет одновременно читать статистику предыдущего прохода и записывать свою собственную. Дополнительный проход, следующий за этим, будет иметь очень хорошую основу для осуществления очень точных предсказаний размеров кадров при выбранном квантователе. На практике, общее улучшение качества от использования этого режима близко к нулю и, вполне возможно, третий проход приведет к немного худшему глобальному PSNR, чем у предыдущего прохода. При обычном использовании три прохода помогают, если Вы при двух проходах получаете либо плохое предсказание битпотока, либо плохо выглядящие переходы между сценами. Это отчасти то, что наверняка будет происходить на очень коротких клипах. Существуют также особые случаи, когда три (или более) проходом удобны для продвинутых пользователей, но, для краткости, это руководство не включает в себя описание этих особых случаев.

- qcomp: `qcomp` управляет соотношением количества бит, отданных "дорогим" высокодинамичным и "дешевым" малодинамичным кадрам. Один крайний случай: `qcomp=0`, предназначен для истинно постоянного битпотока. Обычно это сделает высокодинамичные сцены выглядящими просто ужасно, в то время как малодинамичные сцены будут, возможно, выглядеть абсолютно великолепно, но при этом будут использовать во много раз больший битпоток, чем им необходимо, чтобы выглядеть лишь превосходно. Другая крайность: `qcomp=1`, добивается примерно одинакового параметра квантования (QP). Постоянный QP не выглядит плохо, но большинство людей думают, что более разумно частично снизить битпоток в сильно дорогих сценах (где потеря качества не очень заметна) и перераспределить их в сцены, которые легче закодировать с отличным качеством. `qcomp` по умолчанию установлена в 0.6, что по мнению многих людей может быть несколько мало (также часто используется 0.7-0.8).

- keyint: `keyint` — единственная возможность выбора между удобством перемещения по файлу и эффективностью кодирования. По-умолчанию `keyint` установлена в 250. В материале с 25fps это гарантирует возможность перемещения с точностью до 10 секунд. Если Вы считаете, что более важным и полезным будет перемещение с точностью до 5 секунд, установите `keyint=125`; это немного ухудшит качество/битпоток. Если Вы заботитесь только о качестве, но не о перемещаемости, Вы можете установить значение этой опции в более высокое значение (понимая, что улучшение будет убывающим, вплоть до исчезающе малого или даже нулевого). Видео поток по-прежнему будет иметь точки перемещения, пока в нем есть какие-то изменения сцен.

- deblock: Этот раздел может быть несколько спорным.

  H.264 определяет простую процедуру удаления блочности в I-блоках, которая использует предустановленные степени обработки и пороговые значения в зависимости от QP рассматриваемого блока. По-умолчанию, блоки с высоким QP обрабатываются сильнее, а в блоках с низким QP удаление блочности вообще не производится. Предустановленые степени обработки, определенные стандартом, тщательно подобраны и имеют хорошие шансы быть PSNR-оптимальными для любого видео, которое Вы пытаетесь кодировать. Опция `deblock` позволяет указать смещения предустановленных пороговых значений деблокинга.

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

  Первая и самая важная вещь, которую нужно знать о in-loop фильтре удаления блочности состоит в том, что пороговые значения по умолчанию практически всегда PSNR-оптимальны. В редких случаях, где они неоптимальны, идеальное смещение будет плюс минус 1. Изменение параметров деблокинга на большие значения фактически гарантирует ухудшение PSNR. Усиление фильтра размажет больше деталей; ослабление — оставит больше квадратиков.

  По определению плохая идея уменьшать пороги деблокинга, если Ваш исходный материал в основном имеет небольшую пространственную сложность (т.е. не имеет множества деталей или шума). In-loop фильтр делает весьма неплохую работу по сокрытию появляющихся артефактов. Однако, если исходный материал имеет высокую пространственную сложность, артефакты будут практически незаметны. Это происходит потому, что ореолы имеют склонность выглядеть как детали или шум. Зрительное восприятие легко замечает отсутствие деталей, но ему не так легко обратить внимание на неверно изображенный шум. Когда речь идет о субъективном качестве, шум и детали в некоторой степени взаимозаменяемы. Уменьшая силу фильтра удаления блочности, Вы, скорее всего, увеличиваете ошибку, добавляя ореолы, но глаз этого не замечает, поскольку он путает артефакты с деталями.

  Однако, это по-прежнему не оправдывает уменьшение силы фильтра. Вы в большинстве случаев можете получить более качественный шум при помощи постобработки. Если результат кодирования при помощи H.264 выглядит слишком смазанным или размытым, попробуйте поиграть с `-vf noise`, при воспроизведении закодированного фильма. `-vf noise=8a:4a` должна скрыть большинство мелких артефактов. Ее результат почти наверняка будет выглядеть лучше, чем полученный при помощи махинаций с фильтром удаления блочности.

### 7.5.2. Примеры настроек кодирования

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

Все настройки кодирования проверялись на тестовом видео 720x448 @30000/1001 fps с целевым битпотоком 900кбит/сек, на машине AMD-64 3400+ с 2400 МГц и 64-х битном режиме. Для каждой настройки кодирования указаны измеренная скорость кодирования (в кадрах в секунду) и потеря PSNR (в дБ) по сравнению с настройкой "очень высокое качество". Поймите, пожалуйста, что в зависимости от Вашего материала, типа машины, прогресса разработки Вы можете получить сильно отличающиеся результаты.

Описание | Опции кодирования | скорость (в fps) | Относительная потеря PSNR (в дБ)
--- | --- | --- | ---
Очень высокое качество | `subq=6:partitions=all:8x8dct:me=umh:frameref=5:bframes=3:b_pyramid=normal:weight_b` | 6fps | 0дБ
Высокое качество | `subq=5:8x8dct:frameref=2:bframes=3:b_pyramid=normal:weight_b` | 13fps | -0.89дБ
Быстро | `subq=4:bframes=2:b_pyramid=normal:weight_b` | 17fps | -1.48дБ

Пред. | Наверх | След.
7.4. Кодирование кодеком `Xvid` | Начало | 7.6. Кодирование семейством кодеков `Video For Windows`