2015-03-01

Сравнение качества преобразования цветового пространства в Baka Encoder и Avisynth

сд;нч; Подразумевая, что сборки x264 / x265 и параметры кодирования идентичны, кодирование RGB видео при помощи Baka Encoder обеспечит более высокое качество на выходе по сравнению с MeGUI или другими инструментами, задействующими Avisynth или libav для преобразования цветового пространства. Вот фрагмент распределения ошибки возникшей при кодировании тестового изображения (контраст увеличен):

Сравнение распределения ошибки возникшей после кодирования тестового изображения при помощи Avisynth и Baka Encoder.

На самом деле достаточно сложно чем-то выделиться среди других фронтэндов для x264 / 265. Разработка Baka Encoder была изначально сфокусирована по большей части на удобстве использования. В то время я в основном кодировал напрямую посредством шелл скриптов или задействовал MeGUI в качестве фронтэнда, так что я попытался создать инструмент который бы позволил эффективное ручное редактирование настроек, в то же время предоставляя удобный графический интерфейс для контроля за процессом кодирования. Старые версии Baka Encoder использовали прямой подход и отдавали преобразование цветового пространства и ресемплинг на откуп встроенным в x264 фильтрам. Оно производилось при помощи библиотеки swscale, которая встроена вместе с другими компонентами libav во многие из сборок x264. swscale обеспечивает приемлемое качество для таких преобразований, но только в направлении из YCbCr в RGB, так как изначально она была задумана только для декодирования (как, впрочем, и остальная libav и ffmpeg). Производить преобразование RGB -> YCbCr на могла только с использованием простой 8-битной целочисленной арифметики и только с использованием матрицы bt601. Простым решением было бы пойти по пути MeGUI и скинуть груз преобразований цветового пространства на Avisynth, принимая на вход только .avs скрипты (или генерируя их) с дописыванием функции ConvertToYV12(). Но, в свою очередь, у Avisynth не было поддержки большой глубины цвета, 4:4:4 и 4:2:2 сабсемплинга (их поддержка была добавлена в последних нестабильных сборках) и задействовалась все та же простая целочисленная арифметика (однако с несколько более качественным округлением). Мне не удалось найти никаких библиотек, надлежащим образом реализующих преобразование цветового пространства, так что я решил написать свою, с арифметикой с плавающей точкой и точным округлением.

Визуальное представление цветового пространства YCbCr.

Начиная с версии 1.2, Baka Encoder использует свое внутреннее преобразование цветового пространства и ресемплинга. В этой статье я опишу простой тест для сравнения операции преобразование цветового пространства в Baka Encoder с функцией ConvertToYV12(), доступной в Avisynth. Задумка в этом тесте весьма проста: взять какое-нибудь подходящее RGB видео, преобразовать его в YCbCr с сабсемплингом 4:2:0, осуществить lossless кодирование с помощью x264, преобразовать его обратно в RGB и сравнить с оригиналом. В качестве исходного видео я взял два сгенерированных изображения градиента, одно с разрешением 640x360, второе с разрешением 1920x1080, и содержащие полный тоновый градиент переходящий в чистый черный и чистый белый. Полагаю, что это хороший выбор для теста преобразования цветового пространства, так как такой градиент покрывает большую часть ключевых цветов, в то время как SD и HD разрешения изображений позволят протестировать как матрицу bt601, так и матрицу bt709..

Тестовое изображение градиента, SD версия.
Тестовое изображение градиента, SD версия.

Для того, чтобы сделать видео из этого неподвижного изображения я задействую следующий Avisynth скрипт:

ImageSource(file_path, end = 25, use_DevIL=true)
AssumeFps(25)

Он выдаст одну секунду RGB видео с 25 дублированными RGB кадрами. Baka Encoder закодирует такой скрипт автоматически осуществляя преобразование цветового пространства с использованием надлежащей матрицы (если не переопределено в файле конфигурации). Чтобы задействовать Avisynth, добавляется функция ConvertToYV12:

ConvertToYV12(matrix="rec601")

для SD видео и

ConvertToYV12(matrix="rec709")

для HD видео.

После кодирования всех 4 видео с использованием lossless пресета в Baka Encoder v1.3.2 полученные .mp4 файлы преобразуются обратно в RGB опять же при помощи Avisynth:

ffVideoSource(file_path)
ConvertToRGB(matrix="rec601")

или

ffVideoSource(file_path)
ConvertToRGB(matrix="rec709")

Совмещение выходных изображений с оригинальными и сужение входного диапазона до 0-7 для повышения наглядности дает следующие изображения (Avisynth слева, темнее цвет - меньше ошибка):

Разница с оригиналом SD изобращения преобразованного Avisynth.
Разница с оригиналом SD изобращения преобразованного Avisynth.
Разница с оригиналом SD изобращения преобразованного with Baka Encoder.
Разница с оригиналом SD изобращения преобразованного with Baka Encoder.

Разница с оригиналом HD изобращения преобразованного Avisynth.
Разница с оригиналом HD изобращения преобразованного Avisynth.
Разница с оригиналом HD изобращения преобразованного Baka Encoder.
Разница с оригиналом HD изобращения преобразованного Baka Encoder.

И статистика собранная с этих изображений:

Результаты тестирования преобразования цветового пространства.
Результаты тестирования преобразования цветового пространства.

Сразу хотелось бы отметить, что, поскольку преобразование RGB в YCbCr (особенно с TV диапазоном) в обоих направлениях ведет к потерям и ресэмплинг с 4:4:4 до 4:2:0 также ведет к потерям, выходное видео получается с потерями, даже несмотря на использование lossless пресета. Хотя бы удалось избежать потерь из-за самого кодека. Как видно из таблицы выше, лишь примерно 1/10 всех пикселей SD видео и примерно 1/5 всех пикселей HD видео точно сохранили свое первоначальное значение. Эта разница прежде всего обусловлена тем фактом, что в HD видео соседние пиксели более близки по цвету в сравнении с SD вариантом, так что снижение сэмплирования цветоразностных каналов не так сильно на них влияет. Еще одна бросающаяся в глаза деталь - это вертикальные цветные полосы. Они показывают, как меняются каналы распределения ошибки при переходе через границы поддиапазонов оттенка.

Однако важнее то, что в обоих случаях преобразование цветового пространства выполненное Baka Encoder дает более хорошие результаты, улучшая порядка 1% пикселей SD изображения, порядка 4% пикселей HD изображения и значительно сокращая количество пикселей с высоким значением погрешности. Более того, Baka Encoder предлагает надлежащую поддержку видео с большой глубиной цвета, что позволяет ему показывать еще более хорошие результаты при работе с 16 bpp видео на входе и с 10 bpp видео на выходе x264 / x265.

Все использованные в этом тесте файлы доступны для скачивания: