[DirectShow]put_Owner返回E_NOINTERFACE的思考

在MFC对话框中使用DirectShow播放视频时,尝试将渲染窗口设为主窗口的子窗口,但put_Owner返回E_NOINTERFACE。问题出在RenderFile和设置窗口顺序上,正确顺序应先RenderFile再设置窗口。理解RenderFile如何构建Filter Graph,并通过调整代码顺序解决问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MSDN一开始介绍DirectShwo的时候就给出了一个列子“How To Play a File“,代码如下:

这是一个控制台程序,Render会创建一个自己的窗口来播放视频。如果在MFC的对话框中执行这段代码,就会出现两个窗口,一个是Render创建的播放窗口,一个是程序的主窗口。MSDN告诉我们,可以把Render创建的窗口设置为主窗口的子窗口。这样,播放窗口就会贴附在主窗口上。使用IVideoWindow接口实现,代码如下:

 

 

运行程序,执行RenderFile()函数,发现效果没变,还是两个窗口,怎么回事呢?单步调试跟踪发现,pWnd->put_Owner没有返回S_OK,而是返回E_NOINTERFACE,无效的接口指针,很奇怪,pWnd是一个有效的值,但是随后的几个函数执行都是返回E_NOINTERFACE。很明显,窗口设置不成功,没辙,只好世界各地寻找不成功的原因。
对比了DXSDK/Samples/C++/DirectShow/Editing/StillCap中的例子发现,pGraph->RenderFile()函数与pWnd->put_Owner()的执行顺序反了。于是把hr = pGraph->RenderFile(L"C://Example.avi", NULL)放到hr = pGraph->QueryInterface(IID_IVideoWindow,(void**)&pWnd)之前执行,OK,达到了效果,所有执行都返回S_OK。

虽然找到了错误的地方,也达到了效果,不过,使用一项技术,总还是要弄明白原理。于是我把MSDN中相关的内容又好好的看了一遍,发现原来如此:

在这个例子中,看不到添加任何filter的影子,既没有Source Filter ,又没有Render Filter,仅仅一句RenderFile()。是的,RenderFile()干了所有的事情。
首先IGraphBuilder::RenderFile()调用IGraphBuilder::AddSourceFilter()向Graph中添加一个Source Filter。IGraphBuilder::AddSourceFilter()会根据文件扩展名或者是文件头等信息智能选取一个匹配文件的Source Filter。
然后IGraphBuilder::RenderFile()调用IGraphBuilder::Render()完成剩下的Graph的生成。IGraphBuilder::Render()会从Source Filter的output pin开始寻找每一个匹配此pin的Filter加入到链路中来,直到找到一个Render Filter为止。当整个链路完成,也就代表Graph生成,可以调用pControl->Run()运行Graph了。
虽然IVideoWindow是由Filter Graph Manager暴露,但是IVideoWindow设置属性却是对Render Filter。在没有执行RenderFile之前,Graph中没有连接RenderFile,因此IVideoWindow的设置无效。

参考资料来自MSDN:
ms-help://MS.MSDNQTR.v90.en/directshow/htm/intelligentconnect.htm
ms-help://MS.MSDNQTR.v90.en/directshow/htm/igraphbuilderaddsourcefilter.htm
ms-help://MS.MSDNQTR.v90.en/directshow/htm/igraphbuilderrenderfile.htm
ms-help://MS.MSDNQTR.v90.en/directshow/htm/usingwindowedmode.htm

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值