Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1087334
  • 博文数量: 282
  • 博客积分: 10865
  • 博客等级: 上将
  • 技术积分: 2480
  • 用 户 组: 普通用户
  • 注册时间: 2006-05-12 12:35
文章存档

2017年(1)

2016年(3)

2015年(10)

2014年(12)

2013年(5)

2012年(10)

2011年(29)

2010年(3)

2008年(13)

2007年(92)

2006年(104)

我的朋友

分类:

2007-09-20 23:11:14

本文主要讲述了Graph图构建过程中常用的技巧,主要的内容如下:

  ·如何根据CLSID向graph中添加filter
  ·如何查找filter空闲的pin
  ·如何连接两个Filter
  ·如何获得filter或者pin的接口指针
  ·如何查找和某个filter的上下相连的filter
  ·如何删除graph中的所有filter
  ·如何利用Capture Graph Builder构建Graph图表

  如何根据CLSID向graph中添加filter

  下面的代码演示了如何利用CLSID生成一个filter,然后将其加入到graph图中

HRESULT AddFilterByCLSID(
 IGraphBuilder *pGraph, // Pointer to the Filter Graph Manager.
 const GUID& clsid, // CLSID of the filter to create.
 LPCWSTR wszName, // A name for the filter.
 IBaseFilter **ppF) // Receives a pointer to the filter.
{
 if (!pGraph || ! ppF) return E_POINTER;
 *ppF = 0;
 IBaseFilter *pF = 0;
 HRESULT hr = CoCreateInstance(clsid, 0, CLSCTX_INPROC_SERVER,
 IID_IBaseFilter, reinterpret_cast(&pF));
 if (SUCCEEDED(hr))
 {
  hr = pGraph->AddFilter(pF, wszName);
  if (SUCCEEDED(hr))
   *ppF = pF;
  else
   pF->Release();
 }
 return hr;
}

  在你的应用程序中,你可以这样用这个函数

IBaseFilter *pMux;
hr = AddFilterByCLSID(pGraph, CLSID_AviDest, L"AVI Mux", &pMux);

if (SUCCEEDED(hr))
{
 /* ... */
 pMux->Release();
}

  注:有些filter是不能通过with CoCreateInstance方法创建的。例如AVI Compressor Filter和WDM Video Capture filter

  如何查找filter空闲的pin

  看代码吧:

HRESULT GetUnconnectedPin(
 IBaseFilter *pFilter, // Pointer to the filter.
 PIN_DIRECTION PinDir, // Direction of the pin to find.
 IPin **ppPin) // Receives a pointer to the pin.
{
 *ppPin = 0;
 IEnumPins *pEnum = 0;
 IPin *pPin = 0;
 HRESULT hr = pFilter->EnumPins(&pEnum);
 if (FAILED(hr))
 {
  return hr;
 }
 while (pEnum->Next(1, &pPin, NULL) == S_OK)
 {
  PIN_DIRECTION ThisPinDir;
  pPin->QueryDirection(&ThisPinDir);
  if (ThisPinDir == PinDir)
  {
   IPin *pTmp = 0;
   hr = pPin->ConnectedTo(&pTmp);
   if (SUCCEEDED(hr)) // Already connected, not the pin we want.
   {
    pTmp->Release();
   }
   else // Unconnected, 这就是我们想要的pin,空闲的pin
   {
    pEnum->Release();
    *ppPin = pPin;
    return S_OK;
   }
  }
  pPin->Release();
 }
 pEnum->Release();
 // Did not find a matching pin.
 return E_FAIL;
}

  下面的代码演示了如何利用上面的函数来在一个filter查找一个输出的空闲的pin。

IPin *pOut = NULL;
HRESULT hr = GetUnconnectedPin(pFilter, PINDIR_OUTPUT, &pOut);
if (SUCCEEDED(hr))
{
 /* ... */
 pOut->Release();
}

  如何连接两个Filter

  下面的函数演示了如何将一个filter的输出pin和另一个filter的第一个空闲的输入pin进行连接。

HRESULT ConnectFilters(
 IGraphBuilder *pGraph, // Filter Graph Manager.
 IPin *pOut, // Output pin on the upstream filter.
 IBaseFilter *pDest) // Downstream filter.
{
 if ((pGraph == NULL) || (pOut == NULL) || (pDest == NULL))
 {
  return E_POINTER;
 }
 #ifdef debug
  PIN_DIRECTION PinDir;
  pOut->QueryDirection(&PinDir);
  _ASSERTE(PinDir == PINDIR_OUTPUT);
 #endif
 //找一个空闲的输入pin
 IPin *pIn = 0;
 HRESULT hr = GetUnconnectedPin(pDest, PINDIR_INPUT, &pIn);
 if (FAILED(hr))
 {
  return hr;
 }
 // Try to connect them.
 hr = pGraph->Connect(pOut, pIn);
 pIn->Release();
 return hr;
}

  下面是ConnectFilters的一个重载函数,但是第二个参数是一个指向filter的指针,而不是指向pin的指针,这个函数将两个filter连接起来。

HRESULT ConnectFilters(
 IGraphBuilder *pGraph,
 IBaseFilter *pSrc,
 IBaseFilter *pDest)
{
 if ((pGraph == NULL) || (pSrc == NULL) || (pDest == NULL))
 {
  return E_POINTER;
 }
 // 首先在第一个filter上查询一个输出的pin接口
 IPin *pOut = 0;
 HRESULT hr = GetUnconnectedPin(pSrc, PINDIR_OUTPUT, &pOut);
 if (FAILED(hr))
 {
  return hr;
 }
 //然后将它和第二个filter的输入接口衔接。
 hr = ConnectFilters(pGraph, pOut, pDest);
 pOut->Release();
 return hr;
}

  下面的函数演示了利用这个函数来连接AVIMux 过滤器和File Writer过滤器,这个例子也使用了AddFilterByCLSID函数。

IBaseFilter *pMux, *pWrite;
hr = AddFilterByCLSID(pGraph, CLSID_AviDest, L"AVI Mux", &pMux);
if (SUCCEEDED(hr))
{
 hr = AddFilterByCLSID(pGraph, CLSID_FileWriter, L"File Writer", &pWrite);
 if (SUCCEEDED(hr))
 {
  hr = ConnectFilters(pGraph, pMux, pWrite);
  /* Use IFileSinkFilter to set the file name (not shown). */
  pWrite->Release();
 }
 pMux->Release();
}
阅读(1088) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~