目标是实现用于视频处理和与外部应用程序同步的自定义MFT。细节并不重要。 我想要实现的第一步是使用DXVA视频处理或DXVA-HD启动和运行MFT。我无法这样做。
这是我做的: 我开始使用源输入节点(我的网络摄像头),MFT(MFT_Grayscale示例)和EVR构建拓扑。 我把它包含在一个小应用程序中。拓扑工作,我可以看到相机的单色流。 现在我想更改MF_Grayscale示例的代码,使其支持DXVA视频处理,并可以使用VideoProcessBlt方法提供的硬件加速。 Microsoft文档提供了一些信息,但我无法实现正在运行的MFT。
到目前为止我做了什么:
GetAttributes
中,我指出此MFT为MF_SA_D3D_AWARE
。ProcessMessage
中,我处理消息MFT_MESSAGE_SET_D3D_MANAGER
以获取设备句柄,IDirect3DDeviceManager9
和IDirectXVideoProcessorService
。SetInputType
方法中,我使用此处描述的方法
https://msdn.microsoft.com/en-us/library/windows/desktop/ms694235(v=vs.85).aspx
获得DXVA2_VideoDesc结构
并遵循此代码
https://msdn.microsoft.com/en-us/library/windows/desktop/cc307964(v=vs.85).aspx
创建视频处理设备。另外我使用创建表面
IDirectXVideoProcessorService->CreateSurface
GetOutputStreamInfo
中,dwFlags
变量如下所示: pStreamInfo->dwFlags =
MFT_OUTPUT_STREAM_PROVIDES_SAMPLES |
MFT_OUTPUT_STREAM_WHOLE_SAMPLES |
MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER |
MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE;
直到这里,一切似乎都没问题。现在我的问题(对不起,我不能更具体):
我是否需要调整GetOutputAvailableType/SetOutputType
方法?
在ProcessInput
方法中,我获得IMFSample
并提取IMFMediaBuffer
。根据我的函数调用,缓冲区不管理IDirect3DSurface9
。
我是否必须将缓冲区的数据存储到Direct3D表面?
在ProcessOutput
方法中,我想将输入帧转发到输出。 VideoProcessBlt
应该从输入到输出产生1:1的blit。
文档说:
获取当前未使用的可用表面。
如何确定表面是否正在使用?
我该如何输出表面?我应该使用MFCreateVideoSampleFromSurface
还是MFCreateDXSurfaceBuffer
?
不幸的是,我真的迷失了,无法使用文档取得任何进展。
现在的情况是我看不到任何视频输出(窗口有默认的窗口背景颜色),并且网络摄像头在第一帧(LED关闭后)停止捕获帧。除此之外没有任何反应 - 应用程序只是继续运行而没有显示任何内容。
我希望有人可以帮助我。如果有人能指导我使用DXVA视频处理或DXVA-HD进行MFT的示例代码,我将不胜感激。我找不到任何东西......
由于
答案 0 :(得分:1)
获取Media Foundation示例的最简单方法是下载并安装Microsoft Windows SDK for Windows 7和.NET Framework 4'来自http://www.microsoft.com/en-us/download/details.aspx?id=8279。安装样本,然后在' v7.1 / Samples / Multimedia / MediaFoundation'中找到它们。 媒体基金会的样本据说是在微软的Code Gallery网站上,但我一直无法在那里找到它们。 Windows SDK版本不再包含这些示例。
与您的问题直接相关的示例可能是Decoder,DXVA_HD,DXVA2_VideoProc,EVRPresenter,MPEG1Source和topoedit。
我现在无法提供帮助,因为我目前正在努力解决一些相同的问题。
答案 1 :(得分:1)
我是否必须调整GetOutputAvailableType / SetOutputType方法?
是。您需要像往常一样提供属性,没有特殊要求。
我是否必须将缓冲区的数据存储到Direct3D表面?
是。这样做时你需要关心IDirect3DDeviceManager9和LockDevice,因为EVR可以同时使用表面。
如何确定表面是否正在使用?
特别是当表面可以自由使用时,你必须要小心。您的MFT需要实现IMFAsyncCallback接口。使用MFCreateVideoSampleFromSurface后,您将查询IMFTrackedSample接口并调用SetAllocator。 Invoke方法将告诉您表面何时空闲。
我该如何输出表面?我应该使用MFCreateVideoSampleFromSurface还是MFCreateDXSurfaceBuffer?
因为您使用的是IDirectXVideoProcessorService-> CreateSurface,所以MFCreateVideoSampleFromSurface是正确的位置。您可以通过IMFSample输出曲面。
检查此项目:
在MFTDxva2Decoder和MFSkDxva2Renderer下,你会发现一些dxva2处理。