Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1087332
  • 博文数量: 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:08:50

如何查找和某个filter的上下相连的filter

  给你一个filter,你可以沿着graph图找到和它相联结的filter。首先枚举filter的pin,检查每一个pin是否有其他的pin的和它连接,如果有就检查连接pin属于哪个filter,你可以通过输入pin检查上游的filter,通过输出pin来检查下游的filter。

  下面的函数返回上游或者下游的和本filter连接的filter,只要有一个match,就返回。

// Get the first upstream or downstream filter
HRESULT GetNextFilter(
 IBaseFilter *pFilter, // 开始的filter
 PIN_DIRECTION Dir, // 搜索的方向 (upstream 还是 downstream)
 IBaseFilter **ppNext) // Receives a pointer to the next filter.
{
 if (!pFilter || !ppNext) return E_POINTER;
 IEnumPins *pEnum = 0;
 IPin *pPin = 0;
 HRESULT hr = pFilter->EnumPins(&pEnum);
 if (FAILED(hr)) return hr;
 while (S_OK == pEnum->Next(1, &pPin, 0))
 {
  // See if this pin matches the specified direction.
  PIN_DIRECTION ThisPinDir;
  hr = pPin->QueryDirection(&ThisPinDir);
  if (FAILED(hr))
  {
   // Something strange happened.
   hr = E_UNEXPECTED;
   pPin->Release();
   break;
  }
  if (ThisPinDir == Dir)
  {
   // Check if the pin is connected to another pin.
   IPin *pPinNext = 0;
   hr = pPin->ConnectedTo(&pPinNext);
   if (SUCCEEDED(hr))
   {
    // Get the filter that owns that pin.
    PIN_INFO PinInfo;
    hr = pPinNext->QueryPinInfo(&PinInfo);
    pPinNext->Release();
    pPin->Release();
    pEnum->Release();
    if (FAILED(hr) || (PinInfo.pFilter == NULL))
    {
     // Something strange happened.
     return E_UNEXPECTED;
    }
    // This is the filter we're looking for.
    *ppNext = PinInfo.pFilter; // Client must release.
    return S_OK;
   }
  }
  pPin->Release();
 }
 pEnum->Release();
 // Did not find a matching filter.
 return E_FAIL;
}

  下面演示如何使用这个函数:

IBaseFilter *pF; // Pointer to some filter.
IBaseFilter *pUpstream = NULL;
if (SUCCEEDED(GetNextFilter(pF, PINDIR_INPUT, &pUpstream)))
{
 // Use pUpstream ...
 pUpstream->Release();
}

  但是,一个filter可能在某个方向同时连接着两个或者更多个filter,例如一个分割filter,就有好几个filter与之相联。 因此,你可能想将所有的filter通过一个集合都搜集到。下面的例子代码就演示了如何通过CGenericList结构来实现这个方法。

#include // Link to the DirectShow base class library
// Define a typedef for a list of filters.
typedef CGenericList CFilterList;
// Forward declaration. Adds a filter to the list unless it's a duplicate.
void AddFilterUnique(CFilterList &FilterList, IBaseFilter *pNew);
// Find all the immediate upstream or downstream peers of a filter.
HRESULT GetPeerFilters(
IBaseFilter *pFilter, // Pointer to the starting filter
PIN_DIRECTION Dir, // Direction to search (upstream or downstream)
CFilterList &FilterList) // Collect the results in this list.
{
 if (!pFilter) return E_POINTER;
  IEnumPins *pEnum = 0;
  IPin *pPin = 0;
  HRESULT hr = pFilter->EnumPins(&pEnum);
  if (FAILED(hr)) return hr;
  while (S_OK == pEnum->Next(1, &pPin, 0))
  {
   // See if this pin matches the specified direction.
   PIN_DIRECTION ThisPinDir;
   hr = pPin->QueryDirection(&ThisPinDir);
   if (FAILED(hr))
   {
    // Something strange happened.
    hr = E_UNEXPECTED;
    pPin->Release();
    break;
   }
   if (ThisPinDir == Dir)
   {
    // Check if the pin is connected to another pin.
    IPin *pPinNext = 0;
    hr = pPin->ConnectedTo(&pPinNext);
    if (SUCCEEDED(hr))
    {
     // Get the filter that owns that pin.
     PIN_INFO PinInfo;
     hr = pPinNext->QueryPinInfo(&PinInfo);
     pPinNext->Release();
     if (FAILED(hr) || (PinInfo.pFilter == NULL))
     {
      // Something strange happened.
      pPin->Release();
      pEnum->Release();
      return E_UNEXPECTED;
     }
     // 将符合的filter添加到list中
     AddFilterUnique(FilterList, PinInfo.pFilter);
     PinInfo.pFilter->Release();
    }
   }
   pPin->Release();
  }
  pEnum->Release();
  return S_OK;
 }
 void AddFilterUnique(CFilterList &FilterList, IBaseFilter *pNew)
 {
  if (pNew == NULL) return;
  POSITION pos = FilterList.GetHeadPosition();
  while (pos)
  {
   IBaseFilter *pF = FilterList.GetNext(pos);
   if (IsEqualObject(pF, pNew))
   {
    return;
   }
  }
  pNew->AddRef(); // The caller must release everything in the list.
  FilterList.AddTail(pNew);
}

  如何应用上面的函数呢?看看下面就知道了:

IBaseFilter *pF; // Pointer to some filter.
CFilterList FList(NAME("MyList")); // List to hold the downstream peers.
hr = GetPeerFilters(pF, PINDIR_OUTPUT, FList);
if (SUCCEEDED(hr)) //解析filter 的集合。
{
 POSITION pos = FList.GetHeadPosition();
 while (pos)
 {
  IBaseFilter *pDownstream = FList.GetNext(pos);
  pDownstream->Release();
 }
}
阅读(1028) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~