directx-11ms-media-foundation

Media Foundation EVR and DirectX 11


I am trying to write an EVR for Media Foundation using DirectX 11 on Windows 10 (Desktop). The only one solution I have found so far is here Unfortunately I don't know (as many others) how to correctly use it. Does somebody can point me to the right direction on how to combine MF with DirectX 11/12 please?

I am using the code for activate my EVR:

hr = MFCreateVideoRendererActivate(hwndVideo, &pRendererActivate);
hr = pRendererActivate->SetGUID(MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_CLSID, CLSID_DX11VideoRenderer);

I came to the point where MF asks for GetDeviceID and an exception is raised in kernel.dll. I think that there is a mismatch between a mixer and renderer device. Default device for them is DX9. In my example I must provide a DirectX 11 device CLSID.


Solution

  • DX11VideoRenderer is a good example to show how to use Dx11 based presenter. However there aren't much code snippet to demonstrate how to use it.

    There are two ways you could look into:

    1. Register the compiled DX11VideoRenderer COM CLSID using regsvr32, and add it in the TopoEdit.
    2. Use without register.

      • Call LoadLibrary() to the dll.
      • Call GetProcAddress() to get pfn of DllGetClassObject().
      • Call above pfn with CLSID_DX11VideoRenderer and IID_IClassFactory to retrieve the media sink factory.
      • Use media sink factory to create media sink.
      • Add media sink to topology.

    Code snippet:

    typedef HRESULT(_stdcall *PFN_GetClassObject)(REFCLSID, REFIID, LPVOID*);
    HMODULE hSink = NULL;
    PFN_GetClassObject pfn = NULL;
    HRESULT hr = E_FAIL;
    IClassFactory *pMediaSinkFactory = NULL;
    IMFMediaSink *pMediaSink = NULL;
    
    hSink = ::LoadLibraryEx(L“DX11VideoRenderer.dll”, 
                NULL, 
                LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);
    
    if(hSink)
        pfn = (PFN_GetClassObject)GetProcAddress(
                hSink, 
                "DllGetClassObject");
    
    if(pfn)
        hr = pfn(CLSID_DX11VideoRenderer, 
                IID_IClassFactory, 
                (LPVOID*)&pMediaSinkFactory);
    
    if(pMediaSinkFactory){
        pMediaSinkFactory->CreateInstance(NULL, 
            __uuidof(IMFMediaSink), 
            (LPVOID*)&pMediaSink);
        pMediaSinkFactory->Release();
    }