科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件DirectShow入门之构建Graph图常用技术

DirectShow入门之构建Graph图常用技术

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

本文主要讲述了Graph图构建过程中常用的技巧。

作者:智慧的鱼 来源:天极开发 2007年10月16日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
如何删除graph中的所有filter

  很简单的,采用IFilterGraph::RemoveFilter函数

// Stop the graph.
pControl->Stop();
// Enumerate the filters in the graph.
IEnumFilters *pEnum = NULL;
HRESULT hr = pGraph->EnumFilters(&pEnum);
if (SUCCEEDED(hr))
{
 IBaseFilter *pFilter = NULL;
 while (S_OK == pEnum->Next(1, &pFilter, NULL))
 {
  // Remove the filter.
  pGraph->RemoveFilter(pFilter);
  // Reset the enumerator.
  pEnum->Reset();
  pFilter->Release();
 }
 pEnum->Release();
}

  如何利用Capture Graph Builder构建Graph图表

  Capture Graph Builder可以用来构建大多数的filter图表,并不仅仅是捕捉graph。本文简单介绍了如何利用Capture Graph Builder来构建graph。

  Capture Graph Builder暴露了ICaptureGraphBuilder2接口指针,首先创建一个capture builder,和一个filter图表管理器对象,然后用图表管理器对象指针初始化Capture Graph Builder。代码如下:

IGraphBuilder *pGraph = NULL;
ICaptureGraphBuilder2 *pBuilder = NULL;
// Create the Filter Graph Manager.
HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL,CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGraph);
if (SUCCEEDED(hr))
{
 // Create the Capture Graph Builder.
 hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL,CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2,
(void **)&pBuilder);
 if (SUCCEEDED(hr))
 {
  pBuilder->SetFiltergraph (pGraph);
 }
};

  连接filter

  ICaptureGraphBuilder2::RenderStream方法可以同时将两个或者三个filter连接成一个链(chain)。通常情况下,当每个filter只有一个输出pin和一个输入pin时,这个方法就才,适用。

  我们现在先忽略前两个参数,第三个参数是一个IUnknown指针,指向一个filter或者输出pin。第五,六个参数指向IBaseFilter指针。RenderStream就将三个filter连接成一个链。例如,假设A,B,C 是三个filter,每个filter只有一个输出pin和一个输入pin。

  下面的代码可以将B连接到A上,将B连接到C上。

RenderStream(NULL, NULL, A, B, C)

  所有的连接都是智能化的,如果是将两个filter相连,你可以将中间的参数设置为NULL:

RenderStream(NULL, NULL, A, NULL, C)

  也可以调用两次这个函数创建一个更长的链条。

RenderStream(NULL, NULL, A, B, C)
RenderStream(NULL, NULL, C, D, E)

  如果最后的一个参数设置为NULL,这个方法就自动的为graph设置一个renderer filter。如果是视频就设置成Video Renderer,如果是音频就设置为DirectSoundRenderer。因此RenderStream(NULL, NULL, A, NULL, NULL)等价于 RenderStream(NULL, NULL, A, NULL, R)
这里R指的是Render Filter。

  如果你在第三个参数指定的是filter,而不是pin,你就要在第一二个参数里指定使用那个输出pin用于连接。

  第一个参数只适用于捕捉filter,它指定pin的所属种类的GUID,具体的设置可以参考Pin Property Set.,但是下面的两个种类对于所有的filter都有效。

PIN_CATEGORY_CAPTURE
PIN_CATEGORY_PREVIEW

  如果捕捉filter不支持捕捉和预览,RenderStream方法就增加一个Smart Tee来分割数据流。

  如果播放文件,要将捕捉filter和一个mux filter连接起来,第二个参数指明了媒体类型:

MEDIATYPE_Audio
MEDIATYPE_Video
MEDIATYPE_Interleaved (DV)

  查询filter和pin的接口指针

  当你建立一个graph后,也许你需要查询graph中的filter和pin暴露的接口指针。例如,一个捕捉filter也许暴露了IAMDroppedFrames接口,它的输出pin也许暴露了IAMStreamConfig接口。

  查询接口最简单地方法就是使用ICaptureGraphBuilder2::FindInterface方法。这个方法遍历整个graph的filter和pin,直到他找到合适的filter。你可以指定开始的filter,然后指定搜索的方向,(向上搜索还是向下搜索)。

  下面的代码在一个视频预览pin上搜索IAMStreamConfig接口

IAMStreamConfig *pConfig = NULL;
HRESULT hr = pBuild->FindInterface(&PIN_CATEGORY_PREVIEW,&MEDIATYPE_Video,pVCap,IID_IAMStreamConfig,
(void**)&pConfig
);
if (SUCCESSFUL(hr))
{
 /* ... */
 pConfig->Release();
}

  查找pin

  如果你需要在某个filter上查询某个接口,可以用ICaptureGraphBuilder2::FindPin方法,代码如下:

IPin *pPin = NULL;
hr = pBuild->FindPin(
pCap, // Pointer to the filter to search.
PINDIR_OUTPUT, // Search for an output pin.
&PIN_CATEGORY_PREVIEW, // Search for a preview pin.
&MEDIATYPE_Video, // Search for a video pin.
TRUE, // The pin must be unconnected.
0, // Return the first matching pin (index 0).
&pPin); // This variable receives the IPin pointer.
if (SUCCESSFUL(hr))
{
/* ... */
pPin->Release();
}

查看本文源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章