科技行者

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

知识库

知识库 安全导航

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

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

  • 扫一扫
    分享文章到微信

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

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

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

关键字:

  • 评论
  • 分享微博
  • 分享邮件
如何查找和某个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 <streams.h> // Link to the DirectShow base class library
// Define a typedef for a list of filters.
typedef CGenericList<IBaseFilter> 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();
 }
}
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

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

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