如何在Windows桌面应用程序中使用Intel硬件MJPEG解码器MFT来处理MediaFoundation SourceReader?

3
我正在使用MediaFoundation SourceReader技术开发USB摄像头流媒体桌面应用程序。该摄像头支持USB3.0并提供1080p MJPG视频格式分辨率的60fps。
我使用软件MJPEG解码器MFT将MJPG转换为YUY2帧,然后将其转换为RGB32帧以在窗口上绘制。但是,使用此软件解码器时,我只能在窗口上呈现30fps而不是60fps。我在这个网站上发布了一个问题,并得到一些建议,建议使用Intel硬件MJPEG解码器MFT来解决帧丢失问题。
当调用IMFTransform :: ProcessInput()方法时,我遇到了错误0xC00D36B5-MF_E_NOTACCEPTING。为了解决这个错误,MSDN建议异步使用IMFTranform接口。因此,我使用IMFMediaEventGenerator接口为每个In / Out样本获取事件。成功地,我只能处理一个输入样本,然后连续IMFMediaEventGenerator :: GetEvent()方法返回MF_E_NO_EVENTS_AVAILABLE错误(GetEvent()是同步的)。
我尝试为SourceReader和IMFTransform配置异步回调,但MFAsyncCallback :: Invoke方法没有调用,因此我计划使用GetEvent方法。
我有什么遗漏吗?如果是的话,有人指导我如何将Intel硬件解码器集成到我的项目中吗?

你尝试过先在TopoEdit中组装拓扑结构吗? - Mgetz
感谢您的回复,Mgetz。相机支持YUY2和MJPG视频格式。最初,相机播放YUY2视频格式,需要更改为MJPG格式。我知道如何在DirectShow中构建图形。但我不知道如何从YUY2切换到MJPG视频格式。您能告诉我如何为MJPG格式组装拓扑结构吗?此外,我已将此解码器添加到MediaSession拓扑结构中,一切都成功了,但在事件中收到了0XC00D5212(MF_E_TOPO_CODEC_NOT_FOUND)的错误代码。 - Emily
因此,建议尝试使用附带SDK的topoedit实用程序来组装拓扑并测试其是否有效。如果您无法在topoedit中构建拓扑,则可能是不可能的。 - Mgetz
感谢您的回复Mgetz。我忘了提到我已经使用topoedit工具来流式传输MJPG视频格式。但是,我无法为MJPG格式组装拓扑结构。您知道如何组装/从YUY2切换到MJPG格式吗? - Emily
1个回答

2
Intel硬件MJPEG解码器MFT是一个异步的MFT,如果您直接管理它,您需要应用异步模型。您似乎正在这样做,但您没有提供使问题明确化的信息。是的,您应该使用上面链接文章中描述的事件模型中的ProcessInput和ProcessOutput部分。当您获得第一帧时,您应进一步调试以使其能够平稳连续处理。
当您使用像媒体会话或源阅读器之类的API时,Media Foundation本身会处理MFTs。在适当的情况下,它能够进行同步和异步消费。然而,在这种情况下,您没有使用IMFTransform调用,甚至从您模糊的描述中来看,您的使用方式是错误的。

谢谢您纠正我的错误,Roman。我已经注册了一个异步回调并尝试获取异步事件,但是我没有从IMFAsyncCallback::Invoke()获得任何事件。您能告诉我如何为SourceReader注册异步回调并访问硬件MFT吗? - Emily
我已经成功为MFT注册了IMFAsyncCallback回调。我收到了MFTransformNeedInput事件两次以处理输入样本,但是根本没有调用MFTransformHaveOutput事件。我附上了我在项目中使用的代码。请查看我的代码的Dropbox链接:https://www.dropbox.com/s/t6figfl9b2kyp6y/HwMJPEGDecoderMFT_Code_Query.txt?dl=0。我在代码中注释了ProcessOutputSample()方法并进行了检查,不断接收到MFTransformNeedInput事件类型。您能告诉我我做错了什么,为什么我没有收到ProcessOutputSample吗? - Emily
@Abika:这只是一段代码片段,我不喜欢其中的一些地方,但更重要的是它无法运行,我也不确定导致你遇到问题的原因是什么。我绝对不喜欢你在由关键部分保护的代码片段中顺序执行WaitForSingleObject的方式。 - Roman R.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接