EVR-CP и синхронизация

Автор V0lt, 10 ноября 2018, 07:48:54

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

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

V0lt

Суть проблемы.
В современных Windows за вывод изображения отвечает Desktop Window Manager. Благодаря ему мы забыли про тиринг при воспроизведении видео. Но есть и проблема. Мы почти не контролируем время отрисовки кадра, т.к. DWM дает задержку, которая может получаться непостоянной.

Есть 3 случая работы DWM:
1. Win7 без Aero. По сути режим работы как в WindowsXP. DWM не работает, можно получить тиринг, если отключить VSync в драйвере.
2. Win7 c Aero. Работает DWM со всеми плюсами и минусами.
3. Win8. Немного изменили DWM и запретили отключать.

На работу DWM влияют количество подключения дисплеев.
Один дисплей - статистике DWM можно верить.
Два дисплея на одной частоте - с одинаковыми дисплеями все хорошо, с разными могут вылезти нюансы.
Два дисплея на разных частотах - статистика DWM начинает сильно врать.
Как правило на втором дисплее ситуация хуже. Есть зависимость от системы. Win8.1 работает лучше, чем Win7.
Для понимания ситуации можно открыть страницу https://www.vsynctester.com/ в разных браузерах и с разным количеством дисплеев.

Режимы "презентации"

D3DPRESENT_INTERVAL_IMMEDIATE позволяет обновлять "буфер" сколь угодно раз. Нарисовал чего-нибудь, подумал, нарисовал что-то другое. А DWM выведет последний результат, который попал на смену кадра. Режим хорош тем, что можно сильно не парится по поводу "выводить кадр или пропускать". В статистике могут быть значения fps больше, чем выдает дисплей (например если смотреть видео 120 fps).
D3DPRESENT_INTERVAL_ONE рисует картинку и ждет смену кадра и выводит. Если у нас кадров больше чем поддерживает дисплей или декодер выдает кадры медленнее чем требуется, то рендерер должен начать сам пропускать кадры.

Тестовые видео
120 fps game video (bf.mp4)

Сборки
MPC-BE.1.5.3.4157 - настройка "Альтернативный VSync" теперь влияет на обычный режим и переключает с D3DPRESENT_INTERVAL_IMMEDIATE на D3DPRESENT_INTERVAL_ONE.
RefreshRate_1 - измеряет частоту экрана и показывает ее в статистике при отключенной опции VSync.
RefreshRate_2 - увеличен интервал измерения, уменьшено количество вычислений.
RefreshRate_3 - добавлен расчет количества ScanLines.
RefreshRate_4 - учитываем большую длительность 0-й сканлинии (VBlack) по сравнению с другими.
RefreshRate_5 - небольшая переделка кода, исправлена опечатка приводящая к периодическим подергиваниям.

Сообщение будет дополняться...

Aleksoid1978

Сейчас в оконном режиме используется значение D3DPRESENT_INTERVAL_IMMEDIATE для D3DPRESENT_PARAMETERS::PresentationInterval. Т.е. рендерер выводит кадр и ничего не ждет. За процесс синхронизации отвечает DWM. Все красиво на бумаге - на деле иногда не очень.

Эксклюзивный режим использует D3DPRESENT_INTERVAL_ONE, при этом отображение на экран будет синхронизировано с вертикальным лучом монитора. Но при этом нет возможности вывести видео с частотой, больше чем частота экрана(ну а зачем оно надо :) ).

Позже примерно накидаю новые опции(в картинках) и пояснения.
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, не так. Про вертикальный луч монитора лучше вообще не вспоминать, он только больше запутывает.

Информацию по D3DPRESENT_INTERVAL_IMMEDIATE и D3DPRESENT_INTERVAL_ONE закинул в шапку.

Различие между режимами легко проверить, если мерять время до и после Present-ов.

Отредактировано

Aleksoid1978

Про ожидание луча написал сам M$
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

Я знаю, везде про VBlack написано. И везде сказано, что обратный луч - это условность (видеокарты и мониторы сейчас иначе работают).
И пока ты не начнешь лезь в функции ловли VBlack-ов, лучше думать о простой "смене кадра".

Добавлено: 2018-11-10 09:45:21

ЦитироватьНо при этом нет возможности вывести видео с частотой, больше чем частота экрана(ну а зачем оно надо smile ).
Надо:
1. Видео с частотой больше, чем частота дисплея.
2. Ускоренное воспроизведение видео.
3. Запустил видео с частотой 23p на дисплее 23 Гц, а в нем появляется рекламная вставка на 59i.
Во всех случаях рендерер должен пропускать кадры.

Aleksoid1978

По опциям - мое предложение следующее:
1 - VSync.
2 - встроенный VSync.

Пояснение:
1 - будет создаваться устройство с параметром D3DPRESENT_INTERVAL_ONE (Для эксклюзивного режима считаем что всегда этот режим активен).
2 - будет работать как сейчас VSync + "Аккуратный VSync". Нет смысла делать отдельно опцию "Аккуратный VSync".

Опции будут независимы друг от друга.
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

D3DPRESENT_INTERVAL_ONE не является VSync-ом. Название неправильное, только запутывает.

Добавлено: 2018-11-10 12:08:56

По поводу того что Альтернативны VSync бесполезен.
Он вообще то управляет D3DPRESENT_INTERVAL для оконного режима в случае отключенного Aero.
m_d3dpp.PresentationInterval = (bCompositionEnabled || m_bAlternativeVSync) ? D3DPRESENT_INTERVAL_IMMEDIATE : D3DPRESENT_INTERVAL_ONE;И борется с тирингом, который как раз возможен для такого случая.
IDC_DSVMR9ALTERNATIVEVSYNC      "Reduces tearing by bypassing the default VSync built into D3D."
Добавлено: 2018-11-10 12:33:44

Я в r4156 удалил опцию "Альтернативный VSync". Ресурсы не трогал, а лишь скрыл контролы в коде.

judelaw

немного погонял тестовые билды на вин10 с 1 и 2 экранами. Крутил ранее тестируемый файл хоккей (NHL 2018-11-04 RS TBL@OTT 720p60 National_SN.mkv). И хотя с 2-я экранами ситуация хуже, но все же, как и ранее на другом железе, остановился на v3(или 2). В режиме Flipex часто срывалась синхронизация, когда фокус переводил на другой экран или открывал во время воспроизведения какое либо окно. Срывалась и долго не восстанавливалась. На v3 даже если и срывалась (при загрузке системы внешними процессами), срыв был кратковременный и очень быстро восстанавливался и дальше шло ровно.
Короче v3 наиболее показалась удачная

svn же хуже всех тестовых версий

ПыСы. Случился забавный момент, Поначалу вообще не мог добиться нормальной синхронизации ни с каким билдом. Потом просто отключил один экран через win+p и включил заново. И глюки прекратились ))
Я к тому, что нюансов может быть много, но на DWM я бы полагался менее всего

V0lt

Собрал сборку 1.5.3.4157. Причина в том, что r4156 оказалась проблемной. Например для моей системы "Альтернативный VSync" нужен для нормального воспроизведения при отключенном Aero.
Бонусом сделал так, чтобы "Альтернативный VSync" переключал режим презентации и при включенном Aero, и на Win8+.

Aleksoid1978

По поводу определения реальной частоты экрана без VSync - как-то уж сильно дергано, не возможно понять. Ну и с показаниями когда включен VSync что-то уж не совпадает.

Добавлено: 2018-11-12 10:52:31

Вот предлагай свой вариант, про который говорил до этого - https://yadi.sk/d/8N0xRlnKRRf9Ew
В нем 2 опции VSync и Internal VSync.

Пояснение:
VSync - создание D3D устройства с параметром PresentationInterval = D3DPRESENT_INTERVAL_ONE. Т.е. в данном случае за сихронизацию(плавность вывод - да называем как хотим) отвечает Direc3D9.

Internal VSync - тот механизм VSync что сейчас в SVN + "Аккуратный VSync".

Опции не зависимы друг от друга, могут по отдельности и могут и дополнять друг-друга.

P.S. В папке 2 билда - второй немного отличается работой Internal VSync(если в SVN и в 1-ом билде в некоторых местах идут проверки на включенный DWM(Aero) - то во втором билде проверяется на PresentationInterval).

Почему решил именно так - да потому что в SVN  PresentationInterval = D3DPRESENT_INTERVAL_ONE невозможно "заюзать" без встроенного механизма VSync.  Ну и так же не зависит от DWM(Aero).
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По поводу определения реальной частоты экрана без VSync - как-то уж сильно дергано, не возможно понять. Ну и с показаниями когда включен VSync что-то уж не совпадает.
Хоть кто-то проверил :-) Больше или меньше показывает?

Добавлено: 2018-11-12 19:17:56

Сделал второй билд, с ним должно быть получше. А вообще надо значение ScanLines правильно определять, чтобы совсем точно было.


Добавлено: 2018-11-12 20:45:55

Поясню, что такое сканлинии.
Допустим есть разрешение 1680x1050. Оно будет хитро уложено как 1840x1088 (см. картинку).

Вот эти 1088 пикселей по высоте и есть искомые сканлинии.
По идее это значение надо как-то получить из системы, но плеер его считает.

Aleksoid1978

Эти самые скан линии могут быть разными для одного и того же разрешения, особенно когда создаёшь кастомное разрешение для правильной частоты :)

Добавлено: 2018-11-13 08:46:57

Второй билд по выводу реальной частоты экрана получше - но все равно намного хуже чем с VSync.
Вот у меня моник 60hz, с VSync во первых сами циферки(особенно после запятой) не так сильно скачут, во вторых почти всегда показывает 59.9хх периодами 60.0хх(примерно раз в 3-5 секунд).

В тестовом билде цифры скачут как сумашедшие, с 59 меняется на 60 наверное каждый кадр.
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

Сделал 3 билд в нем определяется количество сканлиний. Если определилось неправильно, то можно на время включить режим "VSync" и значение будет откорректировано.
Подергивания остались, но Я примерно знаю где подкрутить...

V0lt

В общем собрал билд 5. Работает ровно.

Aleksoid1978

Ну да - 5 билд уже можно сказать отлично. Само по себе конечно такая быстрая "смена" циферок малость раздражает(в отличии от того же madVR) - но мы то рисуем каждый кадр.
Ну и если в madVR(на моем мониторе) выводится 60.000хх - то что в твоем билде, что с VSync - у нас меняется периодами с 59 на 60, и меняются 59.9хххх и 60.0хххх. Короче аккуратность меньше(или больше) :)

Но в любом случае - заливай.
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