DirectShow入门之动态构建FilterGraph

DirectShow入门之动态构建FilterGraph,第1张

DirectShow入门之动态构建FilterGraph,第2张

本文档主要描述了过滤图的动态构建技术。

动态重新连接

当进行引脚连接时,应用程序通常会停止讨论图形。然而,有些过滤器支持动态连接的引脚。


图1

如上所示,我们希望动态移除过滤器2。有两个必要条件:

(1)滤波器3(引脚D)必须支持IPinConnection接口(该接口可以保证滤波器即使在非停止状态下也能重新连接该引脚);

(2)滤波器1上的输出管脚,即管脚A,在重新连接期间必须阻塞数据发送线程。重连时,A脚和d脚不允许数据传输,如果“重连”是由filter1发起的(在filter1内完成),那么Filter 1应该有一个内部机制来阻塞数据发送线程;如果“重新连接”是由应用程序完成的,则要求过滤器1(引脚A)实现IPinFlowControl接口。

动态重新连接的一般步骤如下:

(1)阻塞滤波器1上的数据流线程(引脚A)。

(2)重新连接针脚A和针脚D,必要时插入新的过滤器。

(3)再次启动过滤器1(引脚A)上的数据发送线程。

我们来看看第一步;

(1)阻塞滤波器1上的数据流线程(引脚A)。

Ipflow control:: block可以在同步和异步模式下工作。

如果在异步模式下使用block函数,应首先创建一个win32事件,然后将事件句柄作为参数传递给Block函数,Block函数将立即返回,然后调用WaitForSingleObject方法等待事件被触发。如下所示:

//创建一个事件

HANDLE hEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
if (hEvent!= NULL)
{
//阻止数据流。
HR = pflow CONTROL-> Block(AM _ PIN _ FLOW _ CONTROL _ Block,he vent);
if(successed(HR))
{
//等待pin结束。
DWORD dwRes = WaitForSingleObject(he vent,dw milliseconds);
}
}

如何同步调用Block函数,给它传一个空参数就行了。这样,该功能将继续阻塞,直到引脚完全准备好通过样本,阻塞停止。如果过滤器处于暂停状态,阻塞时间可能会无限期延长。所以,不要在你的主线程中同步调用这个函数,可以启动一个新的线程或者使用异步的方法。

(2)重新连接针脚A和针脚D,必要时插入新的过滤器。

这里可以使用IGraphConfig::Reconnect或者igraphconfig:: reconfigure进行引脚重连(IGraphConfig的接口可以从Filter Graph Manager中获得)。重新连接比重新配置更容易使用。它主要做以下事情:

1.将过滤器2置于停止状态,然后将其移除;

2.如果需要,可以在过滤器图形中添加新的过滤器;

3.重新连接相关引脚;

4.将新添加的过滤器置于暂停或运行状态,以使其与过滤器图形同步。例子如下:

pGraph->AddFilter(pNewFilter,L“为图形新建过滤器”);
pConfig-> Reconnect(
pPinA,//重新连接该输出引脚...
pPinD,//...到这个输入引脚。
pMediaType,//使用此媒体类型。
pNewFilter,//通过此筛选器连接它们。
NULL,
0);

在实践中,如果您觉得Reconnect不够灵活,也可以使用Reconfigure方法来代替。这种方法可以通过应用程序中的回调函数重新连接pin。若要使用Reconfigure方法,必须在应用程序中实现IGraphConfigCallback接口。

在重新配置调用之前,如前所述阻塞数据发送线程,然后通过以下步骤发送未处理的数据:

1.在过滤器末端的输入引脚上调用ipin connection::notifyendorfstream。在这种情况下,它是引脚d,将win32事件传递给此引脚。

2.然后,在连接到需要阻止发送数据的上游过滤器的输出管脚的输入管脚上调用Ipin::EndOfStream方法。在这个例子中,如果最远的上游数据输出引脚是引脚A,那么与之相连的输入引脚是引脚B,调用引脚B上的IPin::EndOfStream方法。

3.等待触发事件。当引脚D收到流结束通知时,表示图中没有数据流,因此重新连接该引脚是安全的。

IGraphConfig::Reconnect的处理将会自动完成。

(3)再次启动过滤器1(引脚A)上的数据发送线程。

只需调用IPinFlowControl::Block,如下:pFlowControl->Block(0,NULL);

过滤器链(过滤器链)

首先,我们需要了解什么是滤链。见下图:


图2

1.滤波器链是相互连接的滤波器链路,链路中的每个滤波器至多有一个输入引脚和至多一个输出引脚;

2.此筛选器链接中的数据流不依赖于链接外的其他筛选器。

如上图所示,A–B、C–D、F–G–H、F–G、G–H都是滤波器链,同时一个滤波器链只能包含一个滤波器,所以A、B、C、D、E、F、G都是独立的链,因为E包含两个输入引脚,所以任何包含E的都不是滤波器链。

过滤器链通过IFilterChain接口操作,该接口可从过滤器图形管理器获得。

Ifierchain提供了以下操作过滤器链的方法:

IFilter Chain:: Start Chain启动链

Ifilter chain:: stop chain停止链

Ifilter chain:: pause chain暂停链

IFilter Chain:: Remove Chain从图形中删除链。

没有什么特别的方法来添加一个链。这与添加过滤器的常规方法相同。首先用IFilterGraph::AddFilter在graph中添加一个滤镜,然后还有iGraphBuilder:: Connect,iGraphBuilder:: Render等方法。

当图形运行时,过滤链可以在运行和停止状态之间切换;当图形处于暂停状态时,过滤器链可以在暂停和停止状态之间切换。以上是滤波器链仅有的两种状态转换。

位律师回复
DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
白度搜_经验知识百科全书 » DirectShow入门之动态构建FilterGraph

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情