Показать сообщение отдельно
Старый 13.01.2021, 19:16   #2
Жрец Нефтиды
Модератор
 
Аватар для Жрец Нефтиды
 
Регистрация: 15.07.2012
Адрес: Санкт-Петербург
Сообщений: 1,395
Сказал(а) спасибо: 344
Поблагодарили 539 раз(а) в 368 сообщениях
Вес репутации: 624
Жрец Нефтиды has a reputation beyond reputeЖрец Нефтиды has a reputation beyond reputeЖрец Нефтиды has a reputation beyond reputeЖрец Нефтиды has a reputation beyond reputeЖрец Нефтиды has a reputation beyond reputeЖрец Нефтиды has a reputation beyond repute
По умолчанию Максимально точная конвертация HEVC (h265) bt2020 10 bit в h264 bt709 8 bit

Задача: конвертировать HEVC (h265) bt2020 10 bit в привычный h264 bt709 8 bit таким методом, чтобы конвертант максимально точно соответствовал оригиналу.
Замечу, что на сегодняшний день я не считаю h264 устаревшим, и если приходится пережимать, то жму только в него. Бесполезно (пока) просить меня помочь конвертировать в h265.
Всё, изложенное здесь, идеально работает на Windows. Не знаю, сработает ли на Пингвине.
Поехали.
При помощи mkvtoolnix-gui, который я называю "матрёшечник", создаём файл, в котором только одна видео дорожка. Назовём его 11.mkv.
Казалось бы, для декодирования на поверхности лежит способ, описанный мною ещё в теме про XVID, а именно, через скрип Ависинта:
LoadPlugin("ffms2.dll")
LoadPlugin("SplineResize.dll")
FFVideoSource("11.mkv", fpsnum=24000, fpsden=1001)
assumefps(24000,1001)
Spline144Resize(1920, 1080)
Но не прокатит. Да, ffms2.dll лихо декодирует HEVC. На том сочтёт свою миссию выполненной. А в степень возводить Марина Цветаева будет? В результате конвертант получится блёклым. По этой же причине не прокатит такой простенький бат-файл:
ffmpeg.exe -i 11.mkv -vf scale=1920:1080:flags=bicubic,format=yuv420p
(Параметры кодирования я в нём не записал.)
Делаем так.
Скачиваем последний официальный релиз ffmpeg.exe. Желательно отсюда, здесь есть и 32-х битные релизы:
[Для просмотра данной ссылки нужно зарегистрироваться]
Скачиваем обязательно статическую версию!
В одной папке располагаем bat-файл, 11.mkv и ffmpeg.exe.
bat-файл пишем так:
ffmpeg.exe -i 11.mkv -vf format=yuv420p16,zscale=dither=none:primaries=709: transfer=709:matrix=709:npl=100:w=1920:h=1080:filt er=spline36,colorspace=all=bt709:iall=bt709:format =yuv420p:dither=none -aspect 16:9 -codec:v libx264 -x264-params qp=16:no-deblock=1:ipratio=1:pbratio=1:no-psy=1:no-fast-pskip=1:no-dct-decimate=1:deadzone-inter=0:deadzone-intra=0:subme=9:colorprim=bt709:transfer=bt709:col ormatrix=bt709:level=4.1 01.mkv
pause
Подробное объяснение параметров на русском языке.
Если какие-либо описанные ниже параметры представлены в Медиаинфо, то их название здесь будет соответствовать названию в официальном русском интерфейсе Медиаинфо.
-i 11.mkv имя входного файла
-vf Эта команда указывает, что дальше последуют видео фильтры. Видео фильтры – это не опции. Это именно видео фильтры. В какой последовательности ты их напишешь, в такой они и будут применены для обработки видео. Поэтому принципиально важно написать их в нужной последовательности. Один видео фильтр отделяется от другого запятой. У видео фильтра могут быть параметры, они же опции, одна или несколько. Если у фильтра есть опции, то формат записи таков. После имени фильтра пишется знак равенства. После знака равенства пишется имя опции, дальше снова знак равенства, после него значение опции. Если количество опций больше одной, то после значения первой опции ставится двоеточие, далее снова опция=значение, и так далее. Вот опции можно записывать в любой последовательности.
Когда мы напишем команду с дефисом впереди, это будет значить, что видео фильтры закончились.
format=yuv420p16 Поднимаем битность до 16. Само по себе это не улучшает и не ухудшает видео. Данное действие может показаться странным. Но в нём заложен глубокий жреческий смысл: мы заставим компьютер производить вычисления с максимальной точностью. Особенно актуальным это будет для альтернативного варианта, когда пропишем гамма-коррекцию. Округление до 8 бит будет производиться в самом конце, перед подачей видео на кодер. Начинать обработку с повышения битности до 16 можно считать признаком хорошего тона.
zscale= Запускаем видео фильтр zscale с множеством опций.
Перед началом конвертирования исследуй 11.mkv Медиаинфо. В списке обязательно должны быть три значения: "Основные цвета" ("Color primaries"), "Характеристики трансфера" ("Transfer characteristics") и "Коэффициенты матрицы" ("Matrix coefficients"). Если они есть – а, скорее всего, так и будет, – то используешь прикреплённый bat-файл, как он есть. Если Медиаинфо не показывает этих значений, то в опции zscale нужно дописать ещё три опции:
primariesin=2020 Для входного потока задаём "Основные цвета" – "BT.2020". Только задаём, ничего не преобразуя.
transferin=smpte2084 Для входного потока задаём трансфер, который в Медиаинфо называется PQ (Perceptual Quantizer). Вот так, немножко необычно. Только задаём, ничего не преобразуя.
matrixin=2020_ncl Для входного потока задаём "Коэффициенты матрицы" – "BT.2020 non-constant". Только задаём, ничего не преобразуя.
Рассматриваем остальные опции.
dither=none Отключить добавления зерна. По умолчанию и так отключено, но подстрахуемся.
primaries=709 Основные цвета преобразуем в bt709. В руководстве к этому фильтру написано, что значение опции записывается "709" (а не "bt709"). Поэтому так и пишем.
transfer=709 Трансфер преобразуем в bt709.
matrix=709 Коэффициенты матрицы преобразуем в bt709.
npl=100 Объяснено в первом посту. Если мы зададим npl больше 100, например, 400, то это будет значить, что мы пытаемся загнать 400 нит в математическую модель, рассчитанную на 100 нит. В результате получим тёмную картинку. Если мы зададим npl меньше 100, например, 50, то получим ядовито-яркие цвета.
Замечу, что я нигде, даже на англоязычных ресурсах, не нашёл хорошего объяснения опции npl. Наш форум лучший.
w=1920 Ширина в пикселях выходящего кадра.
h=1080 Высота в пикселях выходящего кадра.
Все помнят, что ресайз уместен только в сторону уменьшения размера.
filter=spline36 Алгоритм ресайза. Пожалуй, самый лучший.
Что лучше: вначале трансформировать цвета, а потом произвести ресайз, или наоборот? Однозначно я не берусь ответить на этот вопрос. Мы могли бы принудительно задать последовательность этих действий, написав два фильтра zscale. Но мне представляется разумным предоставить самому фильтру возможность решать, в какой последовательности что делать. Поэтому я единым махом записал и трансформацию цветов, и ресайз в опциях фильтра. Будем считать, что программисты фильтра умные.
Запятую видишь? Это значит, что видео фильтр zscale закончил свою работу.
До сих пор мы шли на 16 битах.
colorspace=all=bt709:iall=bt709:format=yuv420p:dit her=none При помощи фильтра colorspace трансформируем 16-ти битный формат в стандартный формат yuv420p, работающий на восьми битах. Здесь как раз и происходит понижение битности до 8. В этом фильтре bt никак не изменяется, так как all и iall мы задали одинаковыми. Изменяется здесь только формат. Почему бы просто не написать format=yuv420p ? Мои тонкие исследования показали, что если мы так просто напишем, то при пересчёте битности дробь будет округляться до целого всегда в меньшую сторону, то есть простым отбрасыванием десятичной части. В фильтре же colorspace округление до целого производится по законам математики, то есть 0.5 и больше округляется в большую сторону. (В самом начале bat-файла битность мы поднимали, там можно было написать просто format= .)
Видео фильтры закончились.
-aspect 16:9 Задаём видимое соотношение сторон. В данном примере оно и так 16:9, но в другом случае видимое соотношение сторон может и не соответствовать пиксельному соотношению сторон.
С классическим математически точным декодированием закончено. Прежде, чем пойти дальше, минута отдыха. Я просмотрел очень много форумов на эту тему, и русскоязычных, и англоязычных. И почувствовал себя астролётчиком, прилетевшим с планеты Фрина на планету парадоксов. Количество советов, позволяющих получить правильную цветовую гамму, можно пересчитать по пальцам одной руки. Причём все они повторяют один другого: вначале идёт фильтр линеаризации, то есть значения заменяются приближёнными, само же преобразование в 709 выполняется там ещё в два фильтра. Какая погрешность набежит? Конструкции, предлагаемой мной, где одним фильтром производится трансформация, я не обнаружил нигде. Теперь, возможно, такие конструкции появятся. На здоровье, только большое пожалуйста – со ссылкой на сюда. Наш форум лучший!
Однако!
Делая всё, как описано у меня здесь, мы получим видео, у которого на светлых участках мелкие детали засвечены, а на тёмных – затемнены. Это не очень заметно, но при покадровом просмотре можно отследить. Издержки преобразования стандарта, отличающегося от bt709. Нам предстоит решить двуединую задачу: понизить яркость ярких участков и поднять яркость тёмных участков. Есть красивый выход. Задаём npl=200. Видео станет более тёмным. Засветка деталей на ярких участках исчезнет. Тёмные детали подсветим гамма-коррекцией. При этом гамма-коррекция должна идти непременно после фильтра zscale (а не до него). Гамму прописываем через фильтр lut (фильтр eq не используем, он понижает битность до 8).
Есть две принципиально разные гамма-коррекции, хоть и похожие по конечному визуальному результату: 1. Возвести в степень планар яркости. 2. Разжать планарный формат до RGB и возвести в степень каналы R, G и B. Второй подход мне представляется более правильным, его и будем использовать.
Поскольку здесь мы будем и выполнять ресайз, и разжимать до RGB, то в самом начале bat-файла не только поднимем битность до 16, но и превратим формат 420 в 444. Вот здесь мы столкнёмся с тонкостью, описание которой я не нашёл во всей великой Сети. Если фильтром format мы будем только поднимать битность, то битность поднимется, а информационная наполненность видео не изменится. Но если фильтром format мы будем преобразовывать формат 420 в 444, то, кроме смены формата, будет ещё и производиться дизеринг. Поэтому для преобразования 420 в 444 будем использовать colorspace.
Смотрим прилагаемый bat-файл. В самом первом фильтре там прописано "bt709". Это не ошибка жреца. Именно при такой записи фильтр colorspace будет только преобразовывать 420 в 444 и поднимать битность до 12, и ничего больше делать не будет. Что нам и нужно. Если бы мы написали "bt2020", то видео было бы подвергнуто некоторой обработке. Увы, 16 в colorspace нет. Поэтому в следующем фильтре мы только поднимаем битность до 16 – тут дизеринга не будет.
Записав в первом фильтре "bt709", мы "навесили ярлык" на видео, что оно bt709. Реально никаких изменений не произвели. (Вспоминаем басню про льва и ярлык.) Поэтому в фильтре zscale мы явно указываем в опциях параметры входного видео.
Когда yuv444p16 будет преобразовываться в rgb48 фильтром format, то тут дизеринга тоже не будет.
Значение gamma=0.78 я получил эмпирически.
Вот здесь мы подошли к сильному преимуществу предлагаемого мной bat-файла. При гамма-коррекции мы возводим в степень 16-ти битное видео. (На самом деле здесь возводятся в степень десятичные числа от 0 до 1, представляющие из себя относительные значения яркости каналов r, g и b, после чего относительные значения яркости переводятся в абсолютные целочисленные значения.) Целочисленные деления у 16-ти битного видео расположены в 256 раз чаще, чем у 8-битного. Поэтому когда мы перейдём к 8-битному, то выбывания целочисленных значений на шкале 0-255 не будет. То есть конвертант будет смотреться на 8-ми битном мониторе лучше, чем если бы мы просматривали на этом же 8-ми битном мониторе непосредственно исходник.
Таким образом, мы встали перед сложной дилеммой: либо произвести конвертацию математически точно, но получить результат, не на сто процентов радующий глаз, либо слегка отойти от математической точности, но получить приятное для просмотра видео. Я выбираю второе.
Прилагаю архив с двумя гарантированно работающими bat-файлами: для математически точного результата и для результата, радующего глаза. Выбирай.
Если нужно, чтобы bat-файл перезаписывал уже существующий конечный файл с таким же именем без дополнительного вопроса, то после ffmpeg.exe нужно записать -y
В следующем посту разберём опции кодирования и оставшиеся тонкости.
Вложения
Тип файла: zip bat файлы.zip (957 байт, 1009 просмотров)

Последний раз редактировалось Жрец Нефтиды; 09.02.2021 в 21:02.
Жрец Нефтиды вне форума   Ответить с цитированием Вверх