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

2008-04-09 04:10:46来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

作者:智慧的鱼

  摘要:本文主要讲述了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))

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:VC中利用WinAPI实现自绘按钮类

下一篇:三种常见中文内码的转换方法