获得filter的CLSID并加入到graph中

获得filter的CLSID并加入到graph中

 

一、获得filter的CLSID

获得filter的CLSID有三种方法:

1、通过注册表中记录的值获得。

HKEY_CURRENT_USER/Software/Microsoft/ActiveMovie/devenum下面有几个分 类,各个filter都在里面。

比如DivX MPEG-4 Fast-Motion这个filter就在{33D9A760-90C8-11D0-BD43-00A0C911CE86}下面的div4里面。可以看 到他的CLSID是D76E2820-1563-11CF-AC98-00AA004C0FA9。

2、通过代码枚举。

HRESULThr;
CComBSTR FilterName(name);
ICreateDevEnum *pSysDevEnum = NULL;
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,CLSCTX_INPROC_SERVER,IID_ICreateDevEnum, (void **)&pSysDevEnum);
IEnumMoniker *pEnumCat = NULL;
hr = pSysDevEnum->CreateClassEnumerator(CLSID_LegacyAmFilterCategory,&pEnumCat, 0);

if (hr == S_OK)
{
// Enumerate the monikers.
IMoniker *pMoniker;
ULONG cFetched;
while(pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK)
{
IPropertyBag *pPropBag;
pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag);
VARIANT varName;
VariantInit(&varName);
hr = pPropBag->Read(L"FriendlyName", &varName, 0);
if ( (SUCCEEDED(hr) && wcscmp(FilterName, varName.bstrVal) == 0))
{
pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, (void**)&pFilter);
hr=pGraph->AddFilter(pFilter, LPCWSTR (name));
break;
}
VariantClear(&varName);
pPropBag->Release();
pMoniker->Release();
}
pEnumCat->Release();
}
pSysDevEnum->Release();

name是一个字符串,用于存放要枚举的filter的FriendlyName。需要注意的是CreateClassEnumerator的时候的CLSID_LegacyAmFilterCategory这个参数是指filter的类型,这里是 枚举解码的filter。如果是编码的filter就应该是CLSID_VideoCompressorCategory。

CLSID_LegacyAmFilterCategory对应Directshow Filter,而CLSID_VideoCompressorCategory对应VideoCompressor目录。

3、directshow SDK头文件

通常情况下,filter的CLSID是不用我们去查找或枚举的,在directshowSDK的include目录下,有一个名为“uuids.h”的头文件,常用的或者说directshow自带的filter已经列在里面了。

 

二、将filter加入到graph中

在得到了filter后,我们要使用他们,还需要将filter加入到graph中,下面的代码演示了如何利用CLSID生成一个filter,然后将其加入到graph图中。

HRESULT AddFilterByCLSID(
IGraphBuilder *pGraph, // Pointer to the FilterGraph Manager.

const GUID& clsid, // CLSID of the filter tocreate.
LPCWSTR wszName, // A name for the filter.
IBaseFilter **ppF) // Receives a pointer to thefilter.
{
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 VideoCapture filter。

其实这些方法在《directshow开发指南》一书中已经有详细的说明,将filter加入到graph的方法共有两种,静态加载和动态加载,具体内容也可在《directshow开发指南》中找到。

 


你可能感兴趣的:(VC++,directshow,filter,graph,null,server,include,avi)