MPC Video Renderer

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

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

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

Aleksoid1978

Если IDXGISwapChain* не поддерживается текущей системой - то ты его и не получишь. Именно так в данный момент с ID3D11VideoContext1 - если система его не поддерживает, то просто ты его не получаешь и все.
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

Хочу добавить интерфейс IMFVideoProcessor. Не могу понять куда его добавлять: в CVideoRendererInputPin::GetService() или CMpcVideoRenderer::GetService()?
Вроде должен быть в самом фильтре, а не пине.

Aleksoid1978

Ну конечно в фильтр.
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

В общем кое-что прикрутил, но дальше затык.

FGManager мой интерфейс находит и добавляетс в корзину m_pUnks.AddTail(pMFVP). Плеер ищет m_pGB->FindInterface(IID_PPV_ARGS(&m_pMFVP), TRUE), но обламывается на QueryInterface() в CFGManager::FindInterface().
В принципе логично. Я ведь IMFVideoProcessor сделал предком CMpcVideoRenderer, а так похоже не надо было делать.
[merge_posts_bbcode]Добавлено: 2018-04-29 16:28:01[/merge_posts_bbcode]

Типа интерфейсы полученные через от IMFGetService должны сами реализовывать QueryInterface, и не пересекаться с CMpcVideoRenderer::NonDelegatingQueryInterface().  :|

[merge_posts_bbcode]Добавлено: 2018-04-30 08:08:54[/merge_posts_bbcode]

В общем сделал регулировку яркости, контрасности и прочего (MPCVR_IMFVideoProcessor_1.diff). Но теперь вылетает CUnknown при закрытии плеера. :(

Aleksoid1978

Надо в конструктор CUnknown передавать GetOwner() от фильтра, а не NULL.
Типа так : CUnknown(L"CDX9VideoProcessor", pFilter->GetOwner())
[merge_posts_bbcode]Добавлено: 2018-04-30 15:15:58[/merge_posts_bbcode]

Ну или от CDX9VideoProcessor, сам уже проверь.
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

В первом случае регулировки не работают, во втором - падает на QueryInterface.
[merge_posts_bbcode]Добавлено: 2018-05-02 06:35:41[/merge_posts_bbcode]

Сделал регулировки для DX9, CUnknown не использовал. Позже будет для DX11.

У MS для одной и той же фичи каждый раз новый способ задания параметров. :(
Извините, вам запрещён просмотр содержимого спойлеров.

[merge_posts_bbcode]Добавлено: 2018-05-02 11:01:53[/merge_posts_bbcode]

В общем на DX11 при прямом вызове m_pVideoContext->VideoProcessorSetStreamFilter() может падать.
D3D11 CORRUPTION: ID3D11DeviceContext::VideoProcessorSetStreamFilter: Two threads were found to be executing functions associated with the same Device[Context] at the same time. This will cause corruption of memory. Appropriate thread synchronization needs to occur external to the Direct3D API (or through the ID3D10Multithread interface). 252 and 5580 are the implicated thread ids. [ MISCELLANEOUS CORRUPTION #28: CORRUPTED_MULTITHREADING]Мютекс не помогает. Похоже придется делать через промежуточные параметры.

Aleksoid1978

Значит надо не напрямую вызывать - а из кода рисования.
[merge_posts_bbcode]Добавлено: 2018-05-03 20:29:07[/merge_posts_bbcode]

К DX11 можно прикрутить вывод 3D, но нет нужного оборудования(а так понимаю там вывод во frame-packing)
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

К режиму DX9 удалось прикрутить детектор частоты дисплея. Он получился намного проще, чем в EVR-CP. Основной цикл выглядит так:
   if (0L != D3DKMTWaitForVerticalBlankEvent(&we)) {
        return;
    }
    m_Ticks[0] = GetPreciseTick();
    unsigned i = 1;

    while (0L == D3DKMTWaitForVerticalBlankEvent(&we)) {
        m_Mutex.lock();
        m_Ticks[i] = GetPreciseTick();
        bool stop = m_bStop;
        m_Mutex.unlock();

        Sleep(5); // need for Windows 7 :(

        if (stop) {
            break;
        }
        i ^= 1;
    }
Есть нехороший момент с Windows 7, без принудительного Sleep(5) отображение кадров стопориться. В Windows 8.1 нормально.
В режиме DX11 еще не проверял.

V0lt

Вести с полей.

Добавлена поддержка медиатипов с FORMAT_VideoInfo (нужно для Generate Still Video)
Добавлена поддержка ARGB32 и RGB24 на входе (теперь не нужен системный Color Space Converter).
DX9: Если на входе RGB, то на Nvidia и AMD используется шейдерная интерполяция. При отсутствии интерполяции используется StretchRect(D3DTEXF_POINT).

Замечания.
Режим DX11 в некоторых ситуациях может работать некорректно, им некогда было заниматься.
Подсчет частоты дисплея для DX9 из-за проблем временно отключен.

Добавлено: 2018-11-27 19:18:58

В планах сделать поддержку YCbCr 4:4:4 8-бит. Я пробовал сделать поддержку AYUV через DXVA2_VideoProcSoftwareDevice, картинка есть, но интерполяция ужасна. В общем тут есть варианты.
1. Использовать DXVA2_VideoProcSoftwareDevice только для преобразования в RGB, а изменять размеры шейдерами. Но этот вариант мне не нравиться, т.к. любого нестандарта (типа YCoCg) придется добавлять корректирующий прогон шейдером.
2. Преобразование в RGB делать программно (для 4:4:4 оно не шибко тяжелое). Изменять размеры шейдерами. Способ хорош, тем что процесс перегона в RGB можно перевести на стороннюю либу.
3. Засовывать картинку как есть в X8R8G8B8. Преобразовать в нормальный RGB и изменять размеры шейдерами.

Aleksoid1978

По хорошему - это входящие данные в RGB 4:4:4, 8 или 10 бит в зависимости от данных. Ну и потом уже шейдерами делать что душе угодно.

Но сишный код перевода в RGB 4:4:4 будет не быстр.
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 4:4:4 будет не быстр.
Перевод AYUV в XRGB производиться линейно, пиксель в пиксель и требует лишь несколько простых арифметических операций. Это не YV12 на входе, когда приходиться пиксели собирать по всему кадру и хрому восстанавливать.
Я пока планирую переводить AYUV в XRGB на шейдерах, а софтовый держу в уме как запасной и контрольный.

Добавлено: 2018-11-28 06:41:20

На работе заметил баг. Запускаю плеер (отладочная версия). Окно появляется на основном дисплее. Перетаскиваю окно на дополнительный дисплей. Запускаю воспроизведение - получаю исключение в системной dll.

Win8.1 x64, два одинаковых FullHD монитора, подключенные к одной видеокарте Nvidia.

V0lt

2-3 дня потерял из-за багов с ресурсами.

Баг 1. Есть баг с ресурсами из файла. Программа нормально компилируется, но функция FindResource дает ошибку.
Думал, что как-то связано с нумерацией, но нет.

Баг 2. Опять программа нормально компилируется, но вместо правильных данных функция LoadResource будет выдавать какой-то левак. Долго не мог понять почему элементарный шейдер не работает. Потом проверил, что выдает SizeofResource - размер не совпал с исходным файлом.

Даже не знаю чего и делать. Бред полный. Если только шейдеры ввести в основной проект.

Aleksoid1978

Ну так в MPC-BE же все работает, ты по аналогии сделал ??

P.S. Я сравнил ресурсы в собранном .ax - содержимое и размер идентично .cso файлам.
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

Типа так и было, пока я test_shader.cso не добавил. И тут этот бред начался.

Aleksoid1978

Ну значит добавил как-то не так - 100%
Давай патч/код - гляну.
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