Пользователь
0,0
рейтинг
16 января 2012 в 13:19

Дизайн → Проблема TV/PC диапазонов видео из песочницы

postimage

Привет, хабр!

Хочу поведать о своём недавно проведённом исследовании, в котором я изучил проблему несоответствия TV/PC диапазонов при сжатии/воспроизведении видео. Проблема эта довольно мелочная, но в то же время достаточно массовая, из-за неё я частенько раньше винил кодеки сжатия в изменении цветов.


Пример

Представьте, вы вернулись только что с отпуска, были в местечке N и сделали на мероприятии M суперские фотографии на свой, несомненно, отличный фотоаппарат F. Сбрасываете вы фотографии на компьютер, и понимаете — руки чешутся сделать видео-коллаж и показать всю эту красоту друзьям. Сказано — сделано, устанавливаете любимый видео-редактор, подправляете контрастность, гамму, всё делаете так, чтобы было максимально красиво. И вот проект уже готов: перед вами свежеиспечённый видеофайл. Запускаете для проверки и… Что-то не так, как будто уменьшили контраст и насыщенность. А что если другим кодеком?? Попробовали другой кодек — то же самое. Ладно, главное чтобы на DVD было всё нормально. Записываете клип на DVD — и цвета, действительно, стали на свои места… Как же так?

Предыстория

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

Но, чёрно-белая картинка не очень удовлетворяла людей, всё-таки зрение у нас цветное, поэтому совсем скоро появилось цветное телевидение. В цветных телевизорах так же использовался кинескоп, но для передачи цвета в нём использовались, так же как и в современных мониторах, красно-зелёно-синие пиксели. Тут стал вопрос, как передавать сигнал, что бы при этом сохранялась обратная совместимость с чёрно-белыми телевизорами? Можно, конечно, было бы вещать на соседней частоте помимо яркости, ещё и 3 цветовых канала, но, во-первых, диапазон частот, выделенный на канал, был довольно узкий, во-вторых, это сложнее, т. к. получаем в итоге 4 цветовых канала. Так математики и инженеры придумали передавать в дополнение к яркостному каналу два цветовых «хроматических» — синего и красного, получаемых как разность яркости из соответствующего цветового канала, получая из RGB цветовое пространство (Y, Cb=B-Y, Cr=R-Y). Весь цветовой диапазон можно вычислить исходя из этих трёх каналов. Более того, зрение человека менее чувствительно к цветам, поэтому это позволило сократить разрешение цветовых каналов в два раза, практически не потеряв в качестве картинки. То есть разрешение яркостного канала в PAL-кадре 720x576, а цвета для него передавались в разрешении 360x576 (так называемая 4:2:2 цветовая субдискретизация). Но как именно преобразовывать Яркость (Y) и цветовые хроматические каналы (Cb, Cr) в RGB и наоборот?

Так, в 1982 году, был заложен стандарт преобразования YCbCr<=>RGB, называется он CCIR 601 (с 1992 года — BT.601). Основываясь на результатах многочисленных экспериментов по восприятию цвета человеком, яркость определяется как сумма красного, зеленого и синего с коэффициентами 77/256, 150/256 и 29/256, соответственно.



В результате преобразования из RGB=>YCbCr получается сокращённый диапазон яркости (16-235) и цветности (16-240). Как указано в стандарте, значения 0 и 255 могут использоваться для синхронизации, а значения 1-15 и 236-254 считаются некорректными, и будут отображаться как чёрный и белый. Позже, эти сужения диапазонов перенеслись и на цифровое видео, в результате чего узкий диапазон стал стандартом в видео. Хотя для видео высокой чёткости разработали уже другой стандарт преобразования цветов — BT.709, отличающийся от BT.601 лишь коэффициентами.

Как же правильно должно сжиматься и воспроизводиться видео? Видеофайл, если он сжат в одной из яркостно-хроматических схем (а это подавляющее большинство кодеков, лишь в несжатом видео используется RGB), должен быть закодирован в узкий TV-диапазон яркости (16-235). Т. к. монитор использует всё-таки RGB-вывод, то декодер должен преобразовать YCbCr в RGB с полным диапазоном 0-255. Это почти идеальная схема, но почему почти? А вот почему:
  1. Искусственное сжатие диапазонов — из 256 оттенков серого мы получаем 220 (из 8-ми бит, по сути, получаем чуть больше 7-ми бит), причём отсутствуют объективные причины, зачем нужно сжимать диапазон, кроме как ради совместимости. Мы сознательно ухудшаем качество картинки.
  2. Каждый пиксель видео проходит от файла до точки на мониторе через кучу разных фильтров (декодер, программа плеер, рендеринг, видеодрайвер). По пути в этой длинной цепи может быть сделано много преобразований, в результате чего теряется качество из-за постоянного сужения диапазона.
  3. Из-за того, что некоторые фильтры игнорируют сужение диапазонов, а некоторые видео закодированы ошибочно в полном диапазоне, вместо узкого, другие фильтры пытаются это исправлять, в итоге получается ещё большая запутанность.


Эксперимент

Я решил провести эксперимент, протестировать, как ведут себя различные плееры/драйверы при воспроизведении стандартного узкого диапазона (16-235) и для видео, закодированного в полном (0-255) диапазоне. Для этого я взял PNG картинку с серым градиентом от 0-255, через AviSynth отдавал её наиболее популярному и современному енкодеру x264. Использовал я три скрипта avs, первый читал картинку и отдавал её «как есть», в RGB формате (как несжатое видео):

rgb.avs
ImageReader("palette.png", end=24)


Во втором и третьем файле выполнял конвертирование в YV12 цветовое пространство в полный диапазон по двум стандартам BT.601 и BT.709:

pc601.avs
ImageReader("palette.png", end=24)
ConvertToYV12(matrix="PC.601")


pc709.avs
ImageReader("palette.png", end=24)
ConvertToYV12(matrix="PC.709")


Далее я осуществлял сжатие несколькими вариантами. Дело в том, что в x264 есть два параметра, которые могут влиять на результат: --input-range [TV, PC] и --range [TV, PC]. В старых версиях x264 за это отвечал параметр --fullrange.

colortest.cmd
x264.exe --preset veryslow --crf 1 --output rgb.mp4 rgb.avs
x264.exe --preset veryslow --crf 1 --input-range TV --range TV --output rgb-tv-tv.mp4 rgb.avs
x264.exe --preset veryslow --crf 1 --input-range TV --range PC --output rgb-tv-pc.mp4 rgb.avs
x264.exe --preset veryslow --crf 1 --input-range PC --range TV --output rgb-pc-tv.mp4 rgb.avs
x264.exe --preset veryslow --crf 1 --input-range PC --range PC --output rgb-pc-pc.mp4 rgb.avs

x264.exe --preset veryslow --crf 1 --output pc601.mp4 pc601.avs
x264.exe --preset veryslow --crf 1 --input-range TV --range TV --output pc601-tv-tv.mp4 pc601.avs
x264.exe --preset veryslow --crf 1 --input-range TV --range PC --output pc601-tv-pc.mp4 pc601.avs
x264.exe --preset veryslow --crf 1 --input-range PC --range TV --output pc601-pc-tv.mp4 pc601.avs
x264.exe --preset veryslow --crf 1 --input-range PC --range PC --output pc601-pc-pc.mp4 pc601.avs

x264.exe --preset veryslow --crf 1 --output pc709.mp4 pc601.avs
x264.exe --preset veryslow --crf 1 --input-range TV --range TV --output pc709-tv-tv.mp4 pc709.avs
x264.exe --preset veryslow --crf 1 --input-range TV --range PC --output pc709-tv-pc.mp4 pc709.avs
x264.exe --preset veryslow --crf 1 --input-range PC --range TV --output pc709-pc-tv.mp4 pc709.avs
x264.exe --preset veryslow --crf 1 --input-range PC --range PC --output pc709-pc-pc.mp4 pc709.avs


В результате получил 15 файлов. После проверки гистограммы с помощью AviSynth получил, что без указания параметров --range и --input-range, видео сжимается так, как подаётся, иначе происходит конверсия диапазонов средствами x264. То есть гладкую гистограмму обеспечивают только файлы pc601.mp4 и pc709.mp4, но т. к. эти стандарты отличаются лишь коэффициентами для хроматических каналов, для нашей серой шкалы разницы между ними не будет, тестировать я буду только два файла — rgb.mp4 и pc601.mp4 (узкий и полный диапазон соответственно).

Протестировал я воспроизведение этих файлов на 4-рёх компьютерах, везде стоит Windows 7 и кодеки ffdswow и K-Lite Codec Pack. Результат занёс в табличку:

table

Пояснение к таблице:
normal — правильное отображение
in — неправильное отображение, диапазон 16-235 не маштабирован до 0-255
out — неправильное отображение, диапазон 0-255 маштабирован по ошибке, в результате образовалась обрезка диапазона.

Вот скриншоты результатов в плеере MPC-HC:


Стоит отметить, что настройки диапазонов есть практически в каждом фильтре. В моём случае эта настройка есть и в ffdshow video decoder, в рендерах Lav, Haali, в настройках драйвера видеокарты, и также можно заставить преобразовывать диапазон в плеере (есть специальный шейдер). Однако почему-то переключение диапазона в ffdshow video decoder не влияла на результат. Настройка в драйвере не везде влияет на результат, там, где он влиял, я занёс в таблицу (строка настройки видеокарты). Кроме того, при DXVA и CUDA аппаратном ускорении, правильным считается только диапазон 16-235, не говоря уже о телевизорах.

Также заодно протестировал два видео-редактора:
  1. VirtualDub — диапазон не трогает, если нет конверсии в из YV12/YUV2 в RGB и наоборот, иначе делает преобразование диапазонов, фильтры работают в RGB, при отображении в программе делает преобразование TV->PC.
  2. AviDemux — диапазон не меняет (попросту не работает с RGB источниками), фильтры работают с YUV2, при отображении в программе конверсия TV->PC.


Итоги

Из таблицы видно, что получаем мы в итоге полную путаницу: как будет отображаться видео — зависит от многих параметров, таких как используемый кодек, плеер, тип рендеринга и драйвера. Тут главное понимать, в чём собственно проблема, и если получится, исправить.

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

Как с этим бороться? Сразу приходит на ум — в метатэгах указывать используемый диапазон, этот метод даже уже реализован (существует флаг fullrange), но, к сожалению, очень часто этот флаг игнорируется. Поэтому:
  1. разработчикам — необходимо заботиться об реализации влияния такого флага, а также сделать правильное отображение видео в своих плеерах/кодеках, если необходимо преобразование диапазона;
  2. пользователям, если возникла проблема с цветами, попробовать настроить параметры (в кодеке/плеере/драйвере), или попробовать другой плеер;
  3. обработчикам видео — знать о существовании такой проблемы, и правильно сжимать (кодировать в диапазоне 16-235 или хотя бы указывать флаг fullrange).


скачать архив с экспериментом

Ссылки

Wikipedia YCbCr
Wikipedia Rec. 601
Wikipedia Rec. 709
Wikipedia 4:2:2
Wikipedia Цветовая субдискретизация
Павел @PaulZi
карма
85,5
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Дизайн

Комментарии (20)

  • 0
    А почему не используете madVR? forum.doom9.org/showthread.php?t=146228
    • +1
      Слышал о madVR, использовать, конечно, можно, но как заставить поставить его миллиону пользователей, для которого вы создаёте видео? Домохозяйки обычно ставят либо ничего не ставят, либо ставят что-то популярное (например, k-lite), а о вещах для энтузиастов они совершенно не в курсе…
      • 0
        Ну домохозяйки даже с настройками EVR/VMR7/VMR9 возиться не будут. Так что это статья явно не для них.
  • 0
    Жесть. В своё время задавался этим же вопросом, но успокоился, настроив MPC HC так, чтобы рамки у фильмов были чёрными. А оказывается ещё и обрезка бывает :)
    • 0
      Обрезка, слава богу, бывает значительно реже — если только видео сжато в нестандартный полный диапазон. Чаще бывает не масштабирование 16-235 до полного диапазона, из-за чего как раз получаются «серые рамки».
  • 0
    Обратно-совместимый TV-диапазон это конечно здорово, только мне видится более правильным full-диапазон (нет потерь при преобразовании для обратной совместимости и обратно). И надеюсь, что в будущем обратная совместимость требоваться не будет.

    Т.е. мне кажется, что при создании видео лучше создавать его в full-диапазоне. Сейчас можно будет некими телодвижениями, а в будущем потомки спасибо скажут :)

    P.S. интересно, а как к азным диапазонам относятся современные телевизоры?
    • 0
      Мне тоже кажется использование полного диапазона более правильным, но, к сожалению, большинство фото/видеокамер снимают также в узком диапазоне. То есть, даже преобразовав его в полный диапазон, мы от этого ничего не выиграем (из 220 оттенков цветов мы не получим 256).
      • 0
        Сейчас потихонечку оформляется тенденция к XvYCC aka x.v.Color в потребительских продуктах, что не может не радовать.

        Линейные и логарифмические RGB модели удобны для расчётов и просты для понимания, но де факто являются избыточными не только с точки зрения возможностей потребительского оборудования, но и с точки зрения физиологии зрительного восприятия человека. По сему для цифрового кинематографа, цветовым пространством для отображения SMPTE выбрали CIE XYZ.
        x.v.Color — попытка рационально использовать мёртвые зоны BT.709, для расширения отображаемой палитры цветов, актуальными оттенками.
    • 0
      По поводу современных телевизоров, только что попробовал воспроизвести на Asus O! Play Air и на lg 32lv3700. Как я и предполагал, они ведут себя по стандарту — масштабируют 16-235 в 0-255.
  • 0
    Это всё прекрасно и интересно… но зачем для редактирования фотографий использовать видео-редактор?
    • 0
      Имелось ввиду сделать видео коллаж (когда фоточки красиво меняются местами с разными эффектами и под музычку)
    • 0
      Например чтобы источник был заведомо с полноценным диапазоном?
  • 0
    Большинство телевизоров все-таки не дружат с входным диапазоном 0-255. Но с другой стороны, по-моему, за последние 4 года вышло всего около десятка Blu-ray дисков в полном PC диапазоне. Один из последних — третьи звездные войны и на нем очень интересно экспериментировать. Т.е. при преобразовании иногда действительно появляются дополнительные детали на экране :) (ссылка на 2 огромные картинки)
    • 0
      Огорчу вас, но формат Blu-Ray так же соответствуют стандарту BT.709, и также подразумевает узкий (16-235) диапазон. Ссылка на сравнение показывает лишь правильное преобразование YCbCr=>RGB и неправильное. В первом скрине диапазон 16-235 правильно масштабирован до 0-255, а во втором нет — остаются без изменений. Тем самым мы получаем, что чёрный цвет получается тёмно-серым (16), а белый — светло серым (235).
      Подтверждение: раз, два.
      Как было отмечено выше, только в новом стандарте xvYCC используется полный диапазон (к слову его поддержка в HDMI началась с версии 1.3).
      • 0
        а тогда почему во втором «сером» скрине деталей на облаках больше?
        • 0
          Кажется я подозреваю в чём тут проблема. Тут как я понимаю два видео, первое обычное, как задумано авторами, второе получено масштабированием полнодиапазонного видео до 16-235, именно поэтому оно не контрастное.
          Я сейчас взял первую картинку в фотошопе сделал Levels Output — 16, 235, и получил почти вторую картинку, кроме как раз деталей в облаках.
          То есть — в принципе, ничто не мешает хранить в файле полный диапазон, но отображаться должен лишь диапазон 16-235 масштабированный до 0-255. Именно поэтому, как мне кажется, второе видео некорректно, хотя деталей да, несомненно больше. Для проверки, возьмите оба видео, и посмотрите их гистограмму, наверняка как раз у первого видео будет полный диапазон, а у второго — как раз узкий.
          • 0
            И вот тут скорее всего и обнаружится что далеко не все телевизоры или, тем более, проекторы сумеют правильно замаштабировать входной диапазон 0-255 в правильное изображение без потери деталей в светлых и темных местах.
        • 0
          То есть первое видео полнодиапазонное, но авторами задумано отображение узкого диапазона, и скрин показан уже масштабированного 16-235 => 0-255.
          У второго видео на этапе обработки сжали диапазон, после чего делается обратное масштабирование 0-255 => 16-235=>0-255, получаем второй скрин с деталями в облаках.
          Хотя более правильно было бы смотреть первое видео с отключённым итоговым преобразованием, получилась бы картинка как на втором скрине, но при этом мы не сужаем ещё больше диапазон.
  • 0
    Однако почему-то переключение диапазона в ffdshow video decoder не влияла на результат.

    Там нужно то ли сначала включить преобразование в другой тип цвета, то ли включить постобработку.
  • НЛО прилетело и опубликовало эту надпись здесь

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.