MPC Video Renderer

Автор V0lt, 24 февраля 2018, 19:10:59

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

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

V0lt

Идеи.
1. Собирать все шейдеры батником, который засунуть предварительный этап сборки MpcVideoRenderer.
2. Так же через батник на предварительном этапе генерировать заголовочные файлы, а не объекты. Суть в том, что мы уходим от глючного компилятора ресурсов.

Добавлено: 2018-11-29 06:45:50

Патч дать не смогу, т.к. в очередной раз отменил все изменения. Вечером сделаю.
И нету там ничего такого, что было бы не так. Добавленный код для нового шейдера вообще ничем особенным не выделяется и написан был полностью с нуля раз 5.

V0lt

Патч после которого вылезает Баг 1 - https://yadi.sk/d/nVinwq1_-sTCZA
Ошибка проявляется при вызове FindResourceW для resid равным 790.
HRSRC hrsrc = FindResourceW(nullptr, MAKEINTRESOURCEW(resid), L"SHADER");
if (!hrsrc) {
    return E_INVALIDARG;
}

Баг 2 можно получить, если начать менять цифры в #define IDF_SHADER_*.
В данном случае SizeofResource начнет выдавать значения, не соответствующие размерам файлов .CSO.

На неизмененной ревизии от 29.11.2018 багов нет.

V0lt

В общем так.
Функции FindResource, LoadResource, SizeofResource при задании первого параметра nullptr загружают ресурсы приложения, а не текущего модуля.
Как сделать по другому - непонятно. MFC подключать не буду.

Aleksoid1978

Да все понятно, надо просто поискать хорошо :)

HRESULT CDX9VideoProcessor::CreateShaderFromResource(IDirect3DPixelShader9** ppPixelShader, UINT resid)
{
    if (!m_pD3DDevEx || !ppPixelShader) {
        return E_POINTER;
    }

    static const HMODULE hModule = (HMODULE)&__ImageBase;

    HRSRC hrsrc = FindResourceW(hModule, MAKEINTRESOURCEW(resid), L"SHADER");
    if (!hrsrc) {
        return E_INVALIDARG;
    }
    HGLOBAL hGlobal = LoadResource(hModule, hrsrc);
    if (!hGlobal) {
        return E_FAIL;
    }
    DWORD size = SizeofResource(hModule, hrsrc);
    if (size < 4) {
        return E_FAIL;
    }

    return m_pD3DDevEx->CreatePixelShader((const DWORD*)LockResource(hGlobal), ppPixelShader);
}
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

Спасибо. Поправил. :-)
Решение не документировано в MSDN. "Спасибо" MS. :mad:

Тут была подстава в том, что идентификаторы уже добавленных шейдеров совпадали с аналогичными ресурсами MPC-BE (так проще перетягивать наработки). И соотвественно работало нормально. А вот что-то новое добавить и приехали. Реально не понимаешь, что вообще происходит. Все ведь по документации.

V0lt

Aleksoid1978
Есть вопрос по работе RGB32.
Когда мы создаем обычный медиатип с положительной высотой, то для RGB это означает обратный порядок строк (снизу вверх). Эта дичь прёт со времен появления формате BMP. Но в видеокарте нормальный порядок строк (сверху вниз). Для обхода этой проблемы есть разные решения

1. Рендерер сам переворачивает строки при копировании в видеопамять. Сейчас так сделано в экспериментальном видеорендерере. Наш декодер в этом случае тоже делает переворот на последней стадии преобразования. Все это не очень оптимально по скорости (хотя явных тормозов нет, наш код этого не допускает).

2. Рендерер соединятся с декодером и модифицирует медиатип. Высота становиться отрицательной, декодер это учитывает. Так сделано в EVR-ах. Лишних изменений порядка строк больше нет.
Вопрос: Как такое сделать в нашем рендерере?

3. Можно модифицировать сам декодер, чтобы тот создавал для RGB32 медиатип, у которого по умолчанию высота отрицательная.
Вопрос: Можно такое провернуть с нашем декодером? Мне для тестов нужно.

V0lt

Добавил поддержку DVD-Video совместно с декодером Mpeg2DecFilter и LAV Video Decoder.
Деинтерлейс не работает, меню не переключает (ходить только через навигацию в плеере или в свойствах DVD Navigator), но картинка есть. :-)
Microsoft DTV-DVD Video Decoder виснет.
DVD в формате PAL роняют Mpeg2DecFilter. :)

V0lt

Спасибо Aleksoid1978, работа с DVD более менее налажена.

Осталась проблема с Microsoft DTV-DVD Video Decoder. Как оказалась она вылазит и на обычных файлах.
Kubo-001.mkv

V0lt

Я предлагаю убрать поддержку декодирования DXVA2 (временно?) при использовании видеопроцессора D3D11.
Причина: очень костыльный код, с которым тяжело работать.

Убрана в d52a699 (19.01.2019).

V0lt

Тормоза при воспроизведении DVD лечатся, если заменить предка CBaseRenderer на CBaseVideoRenderer.
Но в этом случае у нас 2 статистики. :)

V0lt

Некоторые итоги.

Режим DX9
- Добавлен выбор методов ресайза.
- Добавлена поддержка субтитров

Режим DX11
- Добавлена обработка форматов RGB и YUV444 с помощью шейдеров

Добавлено: 2019-03-13 18:25:24

По поводу предложения убрать ресайз средствами видеопроцессора DXVA2.
Я категорически против этого. Одна из причин, по которой Я занялся разработкой видеорендерера, заключалась в том, что EVR-CP не умеет делать ресайз средствами DXVA2 (хак для Intel не в счет). Такое умеет делать обычный EVR, но он не дает нам дополнительных фич (субтитры, HDR). Использование видеопроцессором DXVA2 - это самый оптимальный по ресурсам способ получения картинки на экране. Урезать его возможности - неправильно. Я сомневаюсь, что мы сможем сделать более производительную обработку видео на шейдерах с сопоставимым качетсвом.
Я надеюсь моя позиция была услышана.


Добавлено: 2019-03-13 19:17:33

По поводу добавить вывод режима декодера.
Просто не хочу тащить тонны кода из EVR-CP в MpcVR. Все эти хуки и прочие извращения, чтобы показать то, что и так можно узнать в свойствах декодера или по наличию иконки "GPU". Вот делать больше нечего.

V0lt

О компиляции шейдеров в рантайм.
Microsoft рекомендует использовать функцию D3DCompile. Она находиться в библиотеке D3dcompiler_47.dll. На Windows 7 эту библиотеку можно установить с помощью обновления KB4019990. А вот на Windows 8.1 она похоже уже встроена в систему. Если это так, то получается, что для режима DirectX 11 нет проблем с компиляцией шейдеров на лету.

Aleksoid1978

Это же отлично. Тогда не надо будет хранить в ресурсах кучу шейдеров, ну как минимум для DX11.

Добавлено: 2019-04-21 12:13:33

А узнать встроена или нет легко - ставим по быстрому на виртуалку чистые Win8/8.1/10 и после установки в командной строке выполняем:
where D3dcompiler_47.dll
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

С нашим рендерером Mpeg2DecFilter при декодировании DVD валиться при вызове BitBltFromI420ToNV12().
C EVR-CP при тех же входных параметрах все нормально. :(

Добавлено: 2019-04-30 20:32:52

Если отключить вывод в планарных YUV, то падает на BitBltFromI420ToYUY2Interlaced().

Похоже инициализация Mpeg2DecFilter для EVR-CP и MPC VR происходит по разному.

V0lt

Падение Mpeg2DecFilter опять только на PAL дисках. Именно на них происходит переключение разрешения с 720x480 на 720x576.

Добавлено: 2019-05-03 20:52:52

Еще наблюдение
На NTSC и PAL дисках CCustomAllocator::SetProperties вызывается 2 раза. Оба раза запрашивается буфер 1x552960.

Если выбрать LAV декодер, то на NTSC дисках 2 раза запрашивается буфер 4x552960. А вот на PAL дисках появляется 3-й запрос 4x663552.

PS:
768*480*12/8 = 552 960
768*576*12/8 = 663 552

Добавлено: 2019-05-03 21:24:04

В общем Mpeg2DecFilter как-то фигово поддерживает механизм QueryAcept. Но EVR почему-то справляется.
LAV декодер нормально поддерживает механизм QueryAcept, поэтому наш VR работает корректно.