YCgCo - некорректные цвета [Исправлено]

Автор V0lt, 17 января 2016, 20:56:45

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

V0lt

В параметрах видеопотока через MediaInfo иногда можно увидеть параметр "Matrix coefficients" (не путать с "Color primaries" и "Transfer characteristics"). Обычно там записано BT.709. Но есть ролик, в котором значится YCgCo.
Сам ролик называется 静流MAD - 恋文 [Game 1920X1080 30.000fps AVC-yuv444p10 FLAC ASS] - mawen1250.mkv
Оригинала нет. Есть кусок.

Теперь самое интересное.
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).

Баг конечно некритичный и неприоритетный, но упомянуть его стоит.

z_mashine


Aleksoid1978

Эх - не дошли в свое время у меня руки для переноса его код для YUV->RGB. Он не только корректнее в некоторых случаях(ну вот как этот) - так еще и НАМНОГО быстрее(сам код SSE оптимизирован + используется много-поточность).
Ну и помимо этого у нас свои опции - которые ессно только libswscale.

Если решить вопросы по опциям - то я могу взяться за перенос ...
AMD Ryzen 5 3600 /GIGABYTE B450 Gaming X /AMD Radeon R9 16Gb@3200 /Kingston 500Gb M.2 /GTX 1650 /Samsung U28R550UQI /OLED Philips 55OLED707 /Yamaha RX-V471 + NS-555 + NS-C444 + NS-333 + YST-SW215

V0lt

Цитата: z_mashineоно?
Вроде оно. Видеоряд длиннее, а вот сабов нет.

Цитата: Aleksoid1978Если решить вопросы по опциям - то я могу взяться за перенос ...
Там только с одной опцией могут быть проблемы - "Выходные уровни RGB", но я бы ее вообще удалил, т.к. RGB должен быть всегда 0-255.

Aleksoid1978

Убирать не надо, но я еще бы добавил один пункт - авто(как есть), чтобы механизм преобразования сам определял что надо на выходе.

А вот я бы убрал остальные 2 параметра:
1 - Пресет. У нас сейчас почти все преобразования минуя libswscale, поэтому уже не актуально.
2 - Стандарт. Тоже не нужен - пусть работает авто-определение.
AMD Ryzen 5 3600 /GIGABYTE B450 Gaming X /AMD Radeon R9 16Gb@3200 /Kingston 500Gb M.2 /GTX 1650 /Samsung U28R550UQI /OLED Philips 55OLED707 /Yamaha RX-V471 + NS-555 + NS-C444 + NS-333 + YST-SW215

Leo

Цитата: V0ltВроде оно. Видеоряд длиннее, а вот сабов нет.
Скачай, они вшитые. У меня такой же ролик лежит.
Цитата: Aleksoid1978Эх - не дошли в свое время у меня руки для переноса его код для YUV->RGB. Он не только корректнее в некоторых случаях(ну вот как этот) - так еще и НАМНОГО быстрее(сам код SSE оптимизирован + используется много-поточность).
Звучит очень вкусно!
Цитата: V0ltсделал wanezhiling
Это она ;)

Aleksoid1978

Так - а получается что, libswscale не поддерживает это ?? Кто знает как а ffplay указать выходной тип(ну там NV12/RGB32 и т.д.) ??
AMD Ryzen 5 3600 /GIGABYTE B450 Gaming X /AMD Radeon R9 16Gb@3200 /Kingston 500Gb M.2 /GTX 1650 /Samsung U28R550UQI /OLED Philips 55OLED707 /Yamaha RX-V471 + NS-555 + NS-C444 + NS-333 + YST-SW215

wanezhiling



Like LAV, PotPlayer also outputs correct color even with EVR.

Aleksoid1978

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 тут конечно сделал правильнее - корректную трансформацию в самом декодере делает.
AMD Ryzen 5 3600 /GIGABYTE B450 Gaming X /AMD Radeon R9 16Gb@3200 /Kingston 500Gb M.2 /GTX 1650 /Samsung U28R550UQI /OLED Philips 55OLED707 /Yamaha RX-V471 + NS-555 + NS-C444 + NS-333 + YST-SW215

V0lt

Цитата: 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.
По описанию и заголовочным файлам там вроде есть все что надо.

V0lt

В общем ffmpeg содержит фильтр 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.

Aleksoid1978

Да не стоит из-за одного-двух файлов прикручивать целый фильтр видео-обработки. Как никак - это лишняя затрата процессорного времени(а это влечет за собой повышение нагрузки 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/
AMD Ryzen 5 3600 /GIGABYTE B450 Gaming X /AMD Radeon R9 16Gb@3200 /Kingston 500Gb M.2 /GTX 1650 /Samsung U28R550UQI /OLED Philips 55OLED707 /Yamaha RX-V471 + NS-555 + NS-C444 + NS-333 + YST-SW215

V0lt

Есть механизм внешних шейдеров. Пробуй.

Aleksoid1978

Я в них не шарю совершенно.
Видео-рендереры - это по твоей части :)
[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 + шейдер:


madVR:

[merge_posts_bbcode]Добавлено: 2016-09-21 16:02:42[/merge_posts_bbcode]

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

Я понял почему такая разница в сочности/яркости - у нас идет вывод в RGB32. Убрал RGB, пошел вывод в YUY2, картинка с шейдером стала более похожая на madVR
AMD Ryzen 5 3600 /GIGABYTE B450 Gaming X /AMD Radeon R9 16Gb@3200 /Kingston 500Gb M.2 /GTX 1650 /Samsung U28R550UQI /OLED Philips 55OLED707 /Yamaha RX-V471 + NS-555 + NS-C444 + NS-333 + YST-SW215

V0lt

Пожалуйста, дай ссылки на код откуда эти матрицы получил.