本篇文档主要讲述了graph图构建过程中常用的技巧
主要的内容如下:
- 1如何根据clsid向graph中添加filter
- 2如何查找filter空闲的pin
- 3如何连接两个filter
- 4如何获得filter或者pin的接口指针
- 5如何查找和某个filter的上下相连的filter
- 6如何删除graph中的所有filter
- 7如何利用capture graph builder构建graph图表
1如何根据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<void**>(&pf));
if (succeeded(hr))
{
hr = pgraph->addfilter(pf, wszname);
if (succeeded(hr))
*ppf = pf;
else
pf->release();
}
return hr;
}
ibasefilter *pmux;注:有些filter是不能通过with cocreateinstance方法创建的。例如avi compressor filter和wdm video capture filter
hr = addfilterbyclsid(pgraph, clsid_avidest, l"avi mux", &pmux);
if (succeeded(hr))
{
/* ... */
pmux->release();
}
2如何查找filter空闲的pin
看代码把
hresult getunconnectedpin(下面的代码演示了如何利用上面的函数来在一个filter查找一个输出的空闲的pin。
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;
}
ipin *pout = null;
hresult hr = getunconnectedpin(pfilter, pindir_output, &pout);
if (succeeded(hr))
{
/* ... */
pout->release();
}
3如何连接两个filter
下面的函数演示了如何将一个filter的输出pin和另一个filter的第一个空闲的输入pin进行连接。
hresult connectfilters(下面是connectfilters的一个重载函数,但是第二个参数是一个指向filter的指针,而不是指向pin的指针,这个函数将两个filter连接起来。
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;
}
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;
}