DirectShow学习
+ -

DirectShow 动态重联

2021-02-26 117 22

在大多数DirectShow筛选器中,当图形正在活动地流式传输数据时,无法重新连接管脚。应用程序必须在重新连接管脚之前停止图形。但是,某些过滤器在图形运行时确实支持pin重新连接,这一过程称为动态重新连接。这可以由应用程序或图形中的过滤器来完成。

作为示例,请查看下图中的图形。
1614323079923

动态重新连接的一种方案可能是在图运行时从图中删除过滤器2,然后用另一个筛选器替换它。要使此场景正常工作,必须满足以下条件:

  • 过滤器3上的输入引脚(引脚D)必须支持IPinConnection接口。此接口允许在不停止过滤器的情况下重新连接管脚。
  • 过滤器1上的输出引脚(引脚A)必须能够在重新连接时阻止媒体数据流。在重新连接期间,没有数据可以在插脚A和插脚D之间传输。通常,这意味着输出引脚必须支持IPinFlowControl接口。但是,如果过滤器1是启动重新连接的筛选器,则它可能有某种内部机制来阻止自己的数据流。

动态重连包括以下步骤:

  • 阻止来自插脚A的数据流。
  • 可能通过新的中间滤清器将针脚A重新连接到Pin D。
  • 解除锁定Pin A,以便数据再次开始流动。

第一步 阻止数据流
若要阻止数据流,请在pin A上调用IPinFlowControl::block。可以异步或同步调用此方法。要异步调用该方法,请创建Win32事件对象并将事件句柄传递给块方法。方法将立即返回。使用诸如WaitForSingleObject之类的函数等待向事件发出信号。该引脚在阻止数据流时向事件发出信号。例如:

// Create an event
HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (hEvent != NULL)
{
    // Block the data flow.
    hr = pFlowControl->Block(AM_PIN_FLOW_CONTROL_BLOCK, hEvent); 
    if (SUCCEEDED(hr))
    {
        // Wait for the pin to finish.
        DWORD dwRes = WaitForSingleObject(hEvent, dwMilliseconds);
    }
}

要同步调用该方法,只需传递值NULL而不是事件句柄。现在该方法将阻塞,直到操作完成。在准备好交付新Sample之前,这可能不会发生。如果过滤器暂停,这可能需要任意的时间长度。因此,不要从主应用程序线程进行同步调用。使用工作线程,或者异步调用该方法。

第二步 重新连接管脚

要重新连接管脚,请查询IGraphConfig接口的筛选器图形管理器,并调用IGraphConfig::reconnect或IGraphConfig::Reconfigure。重新连接方法更易于使用;它执行以下操作:

  • 停止中间过滤器(示例中的过滤器2)并将其从图形中删除。
  • 如果需要,添加新的中间过滤器。
  • 连接所有针脚。
  • 暂停或运行任何新筛选器,以匹配图形的状态。
  • 重新连接方法有几个可选参数,可用于指定针连接的介质类型和要使用的中间筛选器。例如:
    pGraph->AddFilter(pNewFilter, L"New Filter for the Graph");
    pConfig->Reconnect(
      pPinA,      // Reconnect this output pin...
      pPinD,      // ... to this input pin.
      pMediaType, // Use this media type.
      pNewFilter, // Connect them through this filter.
      NULL, 
      0);
    

如果Reconnect方法不够灵活,可以使用Reconfigure方法,该方法调用应用程序定义的回调方法来重新连接管脚。要使用此方法,请在应用程序中实现IGraphConfigCallback接口。

在调用Reconfigure之前,阻止来自输出引脚的数据流,如前所述。然后按如下所示,推送正在重新连接的图形部分中仍挂起的任何数据:

  • 在重新连接链中最下游的输入管脚(示例中的管脚D)上调用IPinConnection::NotifyEndOfStream。传入Win32事件的句柄。
  • 在输入管脚上调用IPin::EndOfStream,该管脚位于阻止数据流的输出管脚的下游。(在本例中,数据流在插脚A处被阻塞,因此您可以在插脚B上调用EndOfStream。)
  • 等待事件发出信号。输入管脚(管脚D)在接收到流结束通知时向事件发送信号。这表示没有数据在管脚之间传输,并且调用者可以安全地重新连接管脚。

请注意,IGraphConfig::Reconnect方法自动处理前面的步骤。如果您使用的是Reconfigure方法,那么只需要执行这些步骤。

在将数据推送到图形中之后,调用Reconfigure并将指针传递给IGraphConfigCallback接口。过滤器图形管理器将调用您提供的IGraphConfigCallback::configure方法。

第三步 取消阻止数据流
重新连接管脚后,通过调用第一个参数的值为零的IPinFlowControl::Block来解除数据流的阻塞。

HID人机交互QQ群:564808376    UAC音频QQ群:218581009    UVC相机QQ群:331552032    BOT&UASP大容量存储QQ群:258159197    STC-USB单片机QQ群:315457461    USB技术交流QQ群2:580684376    USB技术交流QQ群:952873936   

0 篇笔记 写笔记

Directshow获取颜色空间分辨率
void GetColorSpaceResolution(){ HRESULT hr; AM_MEDIA_TYPE *pmt = NULL; VIDEOINFOHEADER *pvi = NULL; VIDEO_STREAM_CONFIG_CAPS scc; IAMSt......
DirectShow时钟时间
DirectShow定义了两个相关的时钟时间:参考时间和流时间。参考时间是参考时钟返回的绝对时间。(见参考时钟。)流时间是相对于图形上次开始运行的时间定义的。图形运行时,流时间等于参考时间减去开始时间。图形暂停时,流时间保持在暂停时的流时间。寻道操作后,流时间重置为零。图形停止时,流时间未定义。当媒......
DirectShow 事件产生
要处理DirectShow事件,应用程序需要一种方法来确定事件何时在队列中等待。过滤器图形管理器提供了两种方法:窗口通知:每当出现新事件时,过滤器图形管理器就会向应用程序窗口发送用户定义的窗口消息。事件信号:如果队列中有DirectShow事件,Filter Graph Manager将向Windo......
DirectShow 图形过滤(Filter)管理器介绍
Filter Graph Manager也是一个COM组件,它是DirectShow的控制中心,它控制Filter的运行。它有以下几个功能:协调各个Filter的状态。Filter有运行,暂停,停止三种状态,在Filter Graph中,各个Filter的状态必须协调一到,否则会引起冲突。Filte......
DirectShow播放UVC设备第二路码流方法
双码流播放Graphi图如上。双码流视频设备有两路捕获输出pin, RenderStream函数只会连接第一路pin,要播放第二路码流需要手动获取第二路pin,然后去连接解码器,再手动连接render,就可以显示了。示例代码// m_pGB 是 IGraphBuilder对象// m_pBF......
DirectShow 体系结构
DirectShow技术是建立在DirectDraw和DirectSound组件基础之上的,它通过DirectDraw对显卡进行控制以显示视频,通过DirectSound对声卡进行控制以播放声音。DirectShow的体系结构如下图所示:DirectShow 位于应用层中。它使用一种叫 Filter......
DirectShow实现视频的实时显示并抓图,可以设置视频参数
DirectShow抓图其实是使用IBasicVideo(IID_IBasicVideo)接口获取数据源,进行存储即可。IGraphBuilder* m_pGraphBuild = NULL;hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_......
DirectShow 过滤器之间数据交互
过滤器通过pin连接,连接的两个PIN在在上游过滤器叫做输出pin,下游过滤器的叫做输入pin。数据从上游过滤器传递给下游过滤器通过这两个上游过滤器的输出pin到下游过滤器的输出pin实现。通常,下游过滤器通过IMemInputPin::Receive来接收来自上游过滤器输出pin发送的数据。上下游......
DirectShow数据流
本节介绍DirectShow的数据的工作方式进行介绍。通过滤器之间数据交互一节可知,数据是存在buffer中的。而每个buffer都由一个名为media sample的COM对象包装,该对象实现了IMediaSample接口。Sample由另一种类型的对象(称为分配器)创建的,它由IMemAlloc......
DirectShow 简介
DirectShow是微软Windows操作系统平台关于多媒体架构的一套API接口。使用DirectShow,应用程序可以执行高质量的视频和音频播放或采集。DirectShow提供高质量的多媒体流捕获和播放。它支持多种格式,包括Advanced Systems Format(ASF)、Motion ......
DirectShow Samples和Allocators
在看本节前,我们首先明确2个概念。通过前面的章节可知:Samples是DirectShow各过滤器之间传输的数据的封包。Allocators是用于创建Samples的分配器。本节将详细介绍Allocators和Sample的原理。当一个过滤器通过其输出管脚将多媒体数据传输给另一个过滤器(通过其输入管......
DirectShow 接收事件
过滤器图形管理器公开了三个支持事件通知的接口。IMediaEventSink包含筛选器发布事件的方法。IMediaEvent包含应用程序检索事件的方法。IMediaEventEx继承并扩展IMediaEvent接口。过滤器通过调用Filter Graph Manager上的IMediaEventSi......
DirectShow数据传输协议
DirectShow数据传输协议定义为了进行数据交换,DirectShow的过滤器(filter)必须支持相关的数据传输协议,这个传输的协议叫做transports。当2个图形过滤器的pin相连接后,它们必须支持相同的transports,除非它们进行数据交换。通常,传输要求其中一个管脚支持特定接口......
DirectShow实时源
实时源(也称为推送push源)实时接收数据。示例包括视频捕获和网络广播。通常,活动源无法控制数据到达的速率。如果满足以下任一条件,则筛选器被视为实时源:过滤器从IAMFilterMiscFlags::GetMiscFlags方法返回AM_FILTER_MISC_FLAGS_IS_SOURCE标志,并......
DirectShow 过滤器的状态
过滤器有三种可能的状态:停止、暂停和运行。暂停状态的目的是提示图形中的数据,以便run命令立即响应。过滤器图形管理器控制所有状态转换。当应用程序调用IMediaControl::Run、IMediaControl::Pause或IMediaControl::Stop时,图形过滤管理器会在所有过滤器上......
关注公众号
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!