MPC-BE forum

MPC-BE => Баг Репорт / The bug report => Архив / Archive => Тема начата: V0lt от 17 января 2016, 20:56:45

Название: YCgCo - некорректные цвета [Исправлено]
Отправлено: V0lt от 17 января 2016, 20:56:45
В параметрах видеопотока через MediaInfo иногда можно увидеть параметр "Matrix coefficients" (не путать с "Color primaries" и "Transfer characteristics"). Обычно там записано BT.709. Но есть ролик, в котором значится YCgCo.
Сам ролик называется 静流MAD - 恋文 [Game 1920X1080 30.000fps AVC-yuv444p10 FLAC ASS] - mawen1250.mkv
Оригинала нет. Есть кусок (https://www.sendspace.com/file/ehoqzv).

Теперь самое интересное.
EVR показывает неправильно.
madVR только начиная с версии v0.90.1 показывает правильно.
Наш декодер преобразует из YUV в RGB неправильно.
В LAV Video Decoder при выводе в RGB формате получаются корректные цвета.

Хорошие скриншоты сделал wanezhiling
MPC-BE: http://i.imgur.com/ndwMJMD.png
MPC-HC: http://i.imgur.com/HFsZe4c.png
На самом деле девочка блондинка, а не розоволосая. :D

Причина проста. Никто не понимает матричные коэффициенты YCgCo. Поэтому nevcairiel написал свои функции преобразования YUV в RGB (см. pixconv/yuv2rgb.cpp (https://github.com/Nevcairiel/LAVFilters/blob/master/decoder/LAVVideo/pixconv/yuv2rgb.cpp)).

Баг конечно некритичный и неприоритетный, но упомянуть его стоит.
Название: YCgCo - некорректные цвета [Исправлено]
Отправлено: z_mashine от 17 января 2016, 21:36:52
Цитата: V0ltОригинала нет.
оно?
Название: YCgCo - некорректные цвета [Исправлено]
Отправлено: Aleksoid1978 от 18 января 2016, 01:59:49
Эх - не дошли в свое время у меня руки для переноса его код для YUV->RGB. Он не только корректнее в некоторых случаях(ну вот как этот) - так еще и НАМНОГО быстрее(сам код SSE оптимизирован + используется много-поточность).
Ну и помимо этого у нас свои опции - которые ессно только libswscale.

Если решить вопросы по опциям - то я могу взяться за перенос ...
Название: YCgCo - некорректные цвета [Исправлено]
Отправлено: V0lt от 18 января 2016, 06:37:39
Цитата: z_mashineоно?
Вроде оно. Видеоряд длиннее, а вот сабов нет.

Цитата: Aleksoid1978Если решить вопросы по опциям - то я могу взяться за перенос ...
Там только с одной опцией могут быть проблемы - "Выходные уровни RGB", но я бы ее вообще удалил, т.к. RGB должен быть всегда 0-255.
Название: YCgCo - некорректные цвета [Исправлено]
Отправлено: Aleksoid1978 от 18 января 2016, 07:49:53
Убирать не надо, но я еще бы добавил один пункт - авто(как есть), чтобы механизм преобразования сам определял что надо на выходе.

А вот я бы убрал остальные 2 параметра:
1 - Пресет. У нас сейчас почти все преобразования минуя libswscale, поэтому уже не актуально.
2 - Стандарт. Тоже не нужен - пусть работает авто-определение.
Название: YCgCo - некорректные цвета [Исправлено]
Отправлено: Leo от 18 января 2016, 08:16:05
Цитата: V0ltВроде оно. Видеоряд длиннее, а вот сабов нет.
Скачай, они вшитые. У меня такой же ролик лежит.
Цитата: Aleksoid1978Эх - не дошли в свое время у меня руки для переноса его код для YUV->RGB. Он не только корректнее в некоторых случаях(ну вот как этот) - так еще и НАМНОГО быстрее(сам код SSE оптимизирован + используется много-поточность).
Звучит очень вкусно!
Цитата: V0ltсделал wanezhiling
Это она ;)
Название: YCgCo - некорректные цвета [Исправлено]
Отправлено: Aleksoid1978 от 18 января 2016, 13:34:41
Так - а получается что, libswscale не поддерживает это ?? Кто знает как а ffplay указать выходной тип(ну там NV12/RGB32 и т.д.) ??
Название: YCgCo - некорректные цвета [Исправлено]
Отправлено: wanezhiling от 18 января 2016, 13:48:56
(http://i.imgur.com/KMFweOm.png)

Like LAV, PotPlayer also outputs correct color even with EVR.
Название: YCgCo - некорректные цвета [Исправлено]
Отправлено: Aleksoid1978 от 18 января 2016, 14:05:44
Pot\'s color is right, but NV12 output is totally wrong. For this video type, 10 bit 4:4:4 - must use RGB32 output. Not right auto select in PotPlayer :)
[merge_posts_bbcode]Добавлено: 2016-01-18 21:05:44[/merge_posts_bbcode]

И, кстати, LAV корректно только в RGB выводит данный ролик для любых рендереров кроме madVR. Если же в другие типы - то плохо. С madVR все хорошо - за счет передачи параметра VideoTransferMatrix = 7.

Разработчик Pot тут конечно сделал правильнее - корректную трансформацию в самом декодере делает.
Название: YCgCo - некорректные цвета [Исправлено]
Отправлено: V0lt от 22 января 2016, 20:16:26
Цитата: Aleksoid1978Убирать не надо, но я еще бы добавил один пункт - авто(как есть), чтобы механизм преобразования сам определял что надо на выходе.
Хочу узнать, по какому критерии можно автоматически преобразовывать в RGB 16-232 вместо стандартных 0-255?

ЦитироватьА вот я бы убрал остальные 2 параметра:
1 - Пресет. У нас сейчас почти все преобразования минуя libswscale, поэтому уже не актуально.
2 - Стандарт. Тоже не нужен - пусть работает авто-определение.
1. Тут заковырка с "почти". И это не только редкие форматы, но и обычные, которые при определенных условиях могут не работать на оптимизированных функциях LAV.
Также перед удалением опции, хорошо бы сравнить производительность пресетов и функций LAV.
2. Тут согласен.

ЦитироватьРазработчик Pot тут конечно сделал правильнее - корректную трансформацию в самом декодере делает.
Там совсем неправильно.
Неправильно из YUV 4:4:4 делать YUV 4:2:0.
[merge_posts_bbcode]Добавлено: 2016-01-22 20:16:26[/merge_posts_bbcode]

Есть альтернативная библиотека для конвертирования цветовых форматов - ZIMG.
По описанию и заголовочным файлам там вроде есть все что надо.
Название: YCgCo - некорректные цвета [Исправлено]
Отправлено: V0lt от 07 марта 2016, 21:20:06
В общем ffmpeg содержит фильтр zscale (https://ffmpeg.org/ffmpeg-filters.html#zscale), который как раз использует библиотеку zimg, которая понимает YCgCo.

В результате выполнения следующей команды получаем картинку с правильными цветами.
ffplay -i "MAD - [Game 1280x720 30.000fps AVC-yuv444p10 FLAC ASS] v2 - mawen1250.mkv" -vf zscale=min=\'ycgco\':m=\'709\'[merge_posts_bbcode]Добавлено: 2016-03-07 18:08:38[/merge_posts_bbcode]

Можно min=\'ycgco\' не указывать, т.к. zscale получет этот параметр от декодера.
[merge_posts_bbcode]Добавлено: 2016-03-07 21:20:06[/merge_posts_bbcode]

Но добавлять фильтр zscale, что-то не сильно хочется.
Причина простая. swscale поддерживает все пиксельные форматы ffmpeg, а zscale только часть. Поэтому придется держать две либы, которые в некоторых случаях будут работать одновременно и последовательно. Бред.
Хотелось бы просто дождаться, когда доработают swscale.
Название: YCgCo - некорректные цвета [Исправлено]
Отправлено: Aleksoid1978 от 21 сентября 2016, 04:20:45
Да не стоит из-за одного-двух файлов прикручивать целый фильтр видео-обработки. Как никак - это лишняя затрата процессорного времени(а это влечет за собой повышение нагрузки CPU), даже с учетом того что не будет никакого scale изображения.
[merge_posts_bbcode]Добавлено: 2016-09-21 11:10:06[/merge_posts_bbcode]

По поводу работы с YCgCo - возможно ли шейдерами выполнить 2-х этапное преобразование ??
Поясню - для того чтобы "подкорректировать" конечный RGB можно попробовать сперва перевести RGB -> YUV, а потом уже YUV -> RGB(по нужному алгоритму YCgCo->RGB).

Вот тут есть описание алгоритма https://wiki.multimedia.cx/index.php?title=YCoCg
[merge_posts_bbcode]Добавлено: 2016-09-21 11:20:45[/merge_posts_bbcode]

А вот даже есть что-то связанное с Pixel Shader - http://www.gamedev.net/topic/517500-ycocg-to-rgb-in-a-pixel-shader-almost-there-one-last-problem/
Название: YCgCo - некорректные цвета [Исправлено]
Отправлено: V0lt от 21 сентября 2016, 08:22:27
Есть механизм внешних шейдеров. Пробуй.
Название: YCgCo - некорректные цвета [Исправлено]
Отправлено: Aleksoid1978 от 21 сентября 2016, 09:02:42
Я в них не шарю совершенно.
Видео-рендереры - это по твоей части :)
[merge_posts_bbcode]Добавлено: 2016-09-21 15:54:43[/merge_posts_bbcode]

Хм ... я смог :)
вот код шейдера
// $MinimumShaderProfile: ps_2_0
sampler s0 : register(s0);

static float4x4 rgb2yuv = {
     0.250, 0.500,  0.250, 0.000,
    -0.250, 0.500, -0.250, 0.000,
     0.500, 0.000, -0.500, 0.000,
     0.000, 0.000,  0.000, 0.000
};

static float4x4 yuv2rgb = {
    1.000,  0.000,  1.140, 0.000,
    1.000, -0.394, -0.581, 0.000,
    1.000,  2.028,  0.000, 0.000,
    0.000,  0.000,  0.000, 0.000
};

float4 main(float2 tex : TEXCOORD0) : COLOR {
    // original pixel
    float4 c0 = tex2D(s0, tex);

    // convert RGB to YUV using YCgCo matrix
    c0 = mul(rgb2yuv, c0);
    // convert YUV to RGB
    c0 = mul(yuv2rgb, c0);

    return c0;
}

и вот скрины
EVR Custom + шейдер:
(http://s018.radikal.ru/i506/1609/2e/cff40598b1eet.jpg) (http://radikal.ru/big/8cw0ics610saw)

madVR:
(http://s018.radikal.ru/i527/1609/cc/17755dd5e8b8t.jpg) (http://radikal.ru/big/vifdohx6uu191)
[merge_posts_bbcode]Добавлено: 2016-09-21 16:02:42[/merge_posts_bbcode]

Хотя - все равно отличается от madVR и PotPlayer. Возможно что rgb2yuv должен быть немного другим(я его взял их zimg). У madVR/Pot картинка более сочная/яркая.

Я понял почему такая разница в сочности/яркости - у нас идет вывод в RGB32. Убрал RGB, пошел вывод в YUY2, картинка с шейдером стала более похожая на madVR
Название: YCgCo - некорректные цвета [Исправлено]
Отправлено: V0lt от 21 сентября 2016, 09:46:13
Пожалуйста, дай ссылки на код откуда эти матрицы получил.
Название: YCgCo - некорректные цвета [Исправлено]
Отправлено: Aleksoid1978 от 21 сентября 2016, 11:39:25
Одна матрица yuv2rgb - из наших шейдеров. Вторую - из интернета, на пример отсюда https://de.wikipedia.org/wiki/YCgCo-Farbmodell так же и из исходников zimg - https://github.com/sekrit-twc/zimg/blob/master/src/zimg/colorspace/colorspace_param.cpp#L119
[merge_posts_bbcode]Добавлено: 2016-09-21 17:03:49[/merge_posts_bbcode]

Но скажу так - небольшая неточность в цветах в любом случае будет, т.к. у нас сперва рендерер(либо декодер) делает YUV->RGB с неверными коэффициентами, а потом мы уже делаем шейдером RGB->YUV->RGB.

[merge_posts_bbcode]Добавлено: 2016-09-21 17:37:46[/merge_posts_bbcode]

И вот еще один вариант шейдера:
// $MinimumShaderProfile: ps_2_0
sampler s0 : register(s0);

static float4x4 rgb2yuv = {
     0.299,  0.587,  0.114, 0.000,
    -0.147, -0.289,  0.436, 0.000,
     0.615, -0.515, -0.100, 0.000,
     0.000,  0.000,  0.000, 0.000
};

static float4x4 yuv2rgb = {
    1.000, -1.000,  1.000, 0.000,
    1.000,  1.000,  0.000, 0.000,
    1.000, -1.000, -1.000, 0.000,
    0.000,  0.000,  0.000, 0.000
};

float4 main(float2 tex : TEXCOORD0) : COLOR {
    // original pixel
    float4 c0 = tex2D(s0, tex);
   
    // convert RGB to YUV using YCgCo matrix
    c0 = mul(rgb2yuv, c0);
    // convert YUV to RGB
    c0 = mul(yuv2rgb, c0);

    return c0;
}

По мне он более корректный, т.к. в нем мы преобразуем RGB -> YUV обычным способом(стандартной матрицей), а уже потом полученный "оригинальный" YUV(который на самом деле YCgCo) преобразуем в RGB как и описано в документации.

В итоге работа 2-х этих шейдеров(итоговая картинка) немного отличаются, с последним вариантом немного сочнее и ярче, хоть с RGB выводом в декодере хоть с YUV.
[merge_posts_bbcode]Добавлено: 2016-09-21 18:39:25[/merge_posts_bbcode]

Естественно - шейдер надо применять до ресайза, на оригинальном видео.
Название: YCgCo - некорректные цвета [Исправлено]
Отправлено: V0lt от 21 сентября 2016, 12:09:00
Тут проблема двоякая.

Если на вход рендерера приходит AYUV с матрицей YCgCo, то тут сам рендерер должен разруливать вышеуказанным шейдером. Подобное как раз делает madVR.

Если же на вход рендерера приходит неправильный RGB, тогда рендерер трогать не надо. Т.к. матрицу YCgCo передавать в свойствах неправильно - не бывает таких матриц в RGB формате. Здесь нужно в самом конвертере декодера править. Судя по матрице из шейдера это несложно будет.
Название: YCgCo - некорректные цвета [Исправлено]
Отправлено: Aleksoid1978 от 21 сентября 2016, 12:44:31
Полностью согласен. Правда MadVR делает это в момент преобразован в RGB,  мы так не сможем. А если идет на вход RGB - то конечно это надо в декодере делать, но там libswscale.

И я опять предлагаю перенести код yuv2rgb из LAV, он и быстрее и это умеет.
[merge_posts_bbcode]Добавлено: 2016-09-21 19:33:08[/merge_posts_bbcode]

Свойства передавать только для YUV,  как сейчас и есть.

[merge_posts_bbcode]Добавлено: 2016-09-21 19:36:00[/merge_posts_bbcode]

Вообщем с тебя работа в видео-рендерерах - получение типа матрицы и прикручивание шейдера,  второго - он более правильный. Я же в декодере - передача матрицы и наверное переделка yuv2rgb.
[merge_posts_bbcode]Добавлено: 2016-09-21 19:44:31[/merge_posts_bbcode]

В libswscale так наворочен код что без бутылки не разобрать. Может тикет сделаешь, ссылку на вики дать - я думаю они сами быстрее чем я там буду ковыряться.
Название: YCgCo - некорректные цвета [Исправлено]
Отправлено: V0lt от 21 сентября 2016, 12:51:38
Вывожу формат AYUV с матрицей YCgCo

EVRcp:
VIDEOINFOHEADER2:
dwInterlaceFlags: 0x00000081
dwCopyProtectFlags: 0x00000000
dwPictAspectRatioX: 16
dwPictAspectRatioY: 9
dwControlFlags: 0x00001581
- VideoChromaSubsampling: 5
- NominalRange          : 1 (0-255)
- VideoTransferMatrix   : 0
- VideoLighting         : 0
- VideoPrimaries        : 0
- VideoTransferFunction : 0
dwReserved2: 0x00000000

madVR:
VIDEOINFOHEADER2:
dwInterlaceFlags: 0x00000081
dwCopyProtectFlags: 0x00000000
dwPictAspectRatioX: 16
dwPictAspectRatioY: 9
dwControlFlags: 0x00039581
- VideoChromaSubsampling: 5
- NominalRange          : 1 (0-255)
- VideoTransferMatrix   : 7 (YCgCo)
- VideoLighting         : 0
- VideoPrimaries        : 0
- VideoTransferFunction : 0
dwReserved2: 0x00000000

Надо устранить сию дискриминацию!
Название: YCgCo - некорректные цвета [Исправлено]
Отправлено: Aleksoid1978 от 21 сентября 2016, 13:03:05
Я же сказал - это я сделаю, прям завтра с утра, по Владивостоку конечно же :)
Название: YCgCo - некорректные цвета [Исправлено]
Отправлено: Angel от 21 сентября 2016, 15:15:17
это как раз то, о чем я писал на руборде. правда я не мог подкрепить свои слова цифрами и такими вот выкладками, но факт остаётся фактом: лучше для просмотра аниме чем мадВР еще ничего не придумали и об этом предупреждают почти во всех ветках на трекерах где раздается 10-битный контент.
Название: YCgCo - некорректные цвета [Исправлено]
Отправлено: Aleksoid1978 от 21 сентября 2016, 16:16:17
Вот патч для видео-декодера. Я немного усложнил - передаем данные пл YCgCo матрице ТОЛЬКО для EVR Custom/Sync, т.е. только для Custom Allocator.

https://yadi.sk/d/SWQy37WBvVFz6
Название: YCgCo - некорректные цвета [Исправлено]
Отправлено: V0lt от 21 сентября 2016, 21:26:42
А почему не передавать всем рендерерам? Они ведь должны игнорировать неизвестные им данные. Баг, который наблюдался на XP, нас ведь теперь не ограничивает?
[merge_posts_bbcode]Добавлено: 2016-09-21 21:26:42[/merge_posts_bbcode]

Я просто заменил
if (dxvaExtFormat->VideoTransferMatrix > DXVA2_VideoTransferMatrix_SMPTE240M) {
    dxvaExtFormat->VideoTransferMatrix = DXVA2_VideoTransferMatrix_Unknown;
}
на
if (dxvaExtFormat->VideoTransferMatrix > 7) {
    dxvaExtFormat->VideoTransferMatrix = DXVA2_VideoTransferMatrix_Unknown;
}
И все рендереры такое переварили без проблем. В свойствах входного пина всех EVR-ов появилась строка VideoTransferMatrix   : 7 (YCgCo). На остальных не было, но это и не важно - главное работают.

Только системный на тестах затупил и подцепился к MEDIASUBTYPE_P010, но он так тупит и без этого изменения.
Название: YCgCo - некорректные цвета [Исправлено]
Отправлено: Aleksoid1978 от 22 сентября 2016, 00:13:31
Можно конечно и так, по простому.