媒体基金会 EVR 和 DirectX 11
Posted
技术标签:
【中文标题】媒体基金会 EVR 和 DirectX 11【英文标题】:Media Foundation EVR and DirectX 11 【发布时间】:2017-01-13 14:21:21 【问题描述】:我正在尝试在 Windows 10(桌面)上使用 DirectX 11 为 Media Foundation 编写 EVR。 到目前为止我发现的唯一一个解决方案是here 不幸的是,我(和其他许多人一样)不知道如何正确使用它。 有人可以为我指出如何将 MF 与 DirectX 11/12 相结合的正确方向吗?
我正在使用代码来激活我的 EVR:
hr = MFCreateVideoRendererActivate(hwndVideo, &pRendererActivate);
hr = pRendererActivate->SetGUID(MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_CLSID, CLSID_DX11VideoRenderer);
我来到了 MF 要求 GetDeviceID 并在 kernel.dll 中引发异常的地步。我认为混合器和渲染器设备之间存在不匹配。他们的默认设备是 DX9。在我的示例中,我必须提供 DirectX 11 设备 CLSID。
【问题讨论】:
DX11VideoRenderer 是一个全新的渲染器。您不使用 EVR。为了在您的项目中使用它,您需要通过位于 DX11VideoRenderer.h 文件中的 CreateDX11VideoRenderer(Activate) 函数来创建它。然后,您可以在媒体会话中使用激活。为了构建示例,您需要 Windows 8.1 SDK。例如,我认为它与 Visual Studio 2013 一起安装。该SDK自带的Topoedit可用于测试DX11 Video Renderer。 似乎 EVR 概念在 D3D11 中已被弃用,支持简单地编写一个单片 IMFMediaSink 来执行您想要终止流的任何操作。这是有道理的本身。这就是为什么 MS 的 DX11VideoRenderer 示例实现了 IMFMediaSink 并且没有提及 IMFVideoPresenter。只是我的印象;我还在想办法。 话虽如此,在 D3D11 上仍然可以使用 EVR,但正如 here 所述,您需要将 both 混合器和演示器替换为自定义组件,此时 EVR 为场景增加的价值很少,对吧? 以下链接似乎进一步证实,如果您同时提供演示者 和 混音器,您应该能够使用系统提供的 EVR 来驱动 DIrect3D 11,只要您不要将它们标识为 IID_IDirect3DDevice9:social.msdn.microsoft.com/Forums/windowsdesktop/en-US/… 【参考方案1】:DX11VideoRenderer 是展示如何使用基于 Dx11 的演示器的一个很好的示例。但是没有太多的代码 sn-p 来演示如何使用它。
您可以通过两种方式查看:
-
使用regsvr32注册编译好的DX11VideoRenderer COM CLSID,并添加到TopoEdit中。
无需注册即可使用。
调用 LoadLibrary() 到 dll。 调用 GetProcAddress() 获取 DllGetClassObject() 的 pfn。 使用 CLSID_DX11VideoRenderer 和 IID_IClassFactory 调用 pfn 以检索媒体接收器工厂。 使用媒体接收器工厂创建媒体接收器。 将媒体接收器添加到拓扑。代码sn-p:
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();
【讨论】:
以上是关于媒体基金会 EVR 和 DirectX 11的主要内容,如果未能解决你的问题,请参考以下文章
在 ffplay 中获得绿屏:使用 Live555 通过 RTP 流将桌面(DirectX 表面)流式传输为 H264 视频