分类: WINDOWS
2007-02-03 10:15:36
我需将一个特定的Video Encode Filter连入Filter Graph 中。想用系统枚举器逐个枚举,但不知道 如何判断枚举到的Filter是我所需要的(如H.264)?
请给出代码!!
杨光 [等级:◆◆(初级)] (信誉值: 100) 回复于: 2004-12-10 12:58:45 Top
Video Encode Filter在哪个目录中,你可以通过目录类型CLSID,遍历!再根据Filter[]->FriendlyName
判断哪个是你想要的Filter
超 [等级:◆◆◆◆(中级)] (信誉值: 100) 回复于: 2004-12-10 13:09:11 Top
The following example shows how to enumerate the video compressors installed on the user's system.
For brevity, the example performs minimal error checking.
// Create the System Device Enumerator.
HRESULT hr;
ICreateDevEnum *pSysDevEnum = NULL;
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum, (void **)&pSysDevEnum);
if (FAILED(hr))
return hr;
// Obtain a class enumerator for the video compressor category.
IEnumMoniker *pEnumCat = NULL;
hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoCompressorCategory, &pEnumCat, 0);
if (hr == S_OK)
{
// Enumerate the monikers.
IMoniker *pMoniker = NULL;
ULONG cFetched;
while(pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK)
{
IPropertyBag *pPropBag;
hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag,
(void **)&pPropBag);
if (SUCCEEDED(hr))
{
// To retrieve the filter's friendly name, do the following:
VARIANT varName;
VariantInit(&varName);
hr = pPropBag->Read(L"FriendlyName", &varName, 0);
if (SUCCEEDED(hr))
{
// Display the name in your UI somehow.
}
VariantClear(&varName);
// To create an instance of the filter, do the following:
IBaseFilter *pFilter;
hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, /////////////////创建枚举到的Filter
(void**)&pFilter);
// Now add the filter to the graph.
//Remember to release pFilter later.
pPropBag->Release();
}
pMoniker->Release();
}
pEnumCat->Release();
}
奸臣 [等级:◆◆(初级)] (信誉值: 100) 回复于: 2004-12-10 13:12:36 Top
多谢,我试试看。
奸臣 [等级:◆◆(初级)] (信誉值: 100) 回复于: 2004-12-10 17:36:13 Top
那个FriendlyName到底指得是什么?我以为是该Filter 的名字就像"Avi Mux",于是我将取到的FriendlyName输出,发现每个FriendlyName只一个字符。哪位兄弟可以给我解释一下。
如果没有如果 [等级:◆◆◆◆◆(中级)] (信誉值: 104) 回复于: 2004-12-10 20:25:50 Top
HRESULT CPreviewDlg::FindXvidCodec(IBaseFilter **ppXvidCodec)
{
HRESULT hr;
IBaseFilter *pCodec = NULL;
//CComPtr
ULONG cFetched;
VARIANT varName = {0};
IMoniker *pMoniker;
// Create the system device enumerator
CComPtr
hr = CoCreateInstance (CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
IID_ICreateDevEnum, (void**)&pDevEnum);
if (FAILED(hr))
return hr;
// Create an enumerator for the video capture devices
CComPtr
hr = pDevEnum->CreateClassEnumerator (CLSID_VideoCompressorCategory, &pClassEnum, 0);
if (FAILED(hr))
return hr;
// If there are no enumerators for the requested type, then
// CreateClassEnumerator will succeed, but pClassEnum will be NULL.
if (pClassEnum == NULL)
{
return E_FAIL;
}
// Use the first video capture device on the device list.
// Note that if the Next() call succeeds but there are no monikers,
// it will return S_FALSE (which is not a failure). Therefore, we
// check that the return code is S_OK instead of using SUCCEEDED() macro.
while(S_OK == (pClassEnum->Next(1, &pMoniker, &cFetched)))
{
CComPtr
// Associate moniker with a file
hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag);
// Read filter name from property bag
varName.vt = VT_BSTR;
hr = pPropBag->Read(L"FriendlyName", &varName, 0);
if (FAILED(hr))
continue;
// Get filter name (converting BSTR name to a CString)
CString str(varName.bstrVal);
SysFreeString(varName.bstrVal);
if (str.Compare("XviD MPEG-4 Codec") == 0)
{
// Bind Moniker to a filter object
hr = pMoniker->BindToObject(0,0,IID_IBaseFilter, (void**)&pCodec);
if (FAILED(hr))
return hr;
// Cleanup interfaces
pMoniker->Release();
break;
}
pMoniker->Release();
}
// Copy the found filter pointer to the output parameter.
// Do NOT Release() the reference, since it will still be used
// by the calling function.
*ppXvidCodec = pCodec;
return hr;
}
如果没有如果 [等级:◆◆◆◆◆(中级)] (信誉值: 104) 回复于: 2004-12-10 20:26:28 Top
我是今天才刚刚研究到的
哈哈
很高兴能对你有用
回头是岸 [等级:◆◆(初级)] (信誉值: 100) 回复于: 2004-12-11 11:55:16 Top
把这种通用的操作写成函数,以后用就方便了,
如果找 Video Compressor 下名称为"H.263" 的话
IBaseFilter * pVCodec = NULL;
CString csCodecName = "H.263";
hr = GetFilterByCLSIDandName(CLSID_VideoCompressorCategory, &csCodecName, &pVCodec)
// 枚举某个域下的某个名称的 filter
HRESULT GetFilterByCLSIDandName(const CLSID& CLSID_TheCategory, CString* pcsFilterName, IBaseFilter** ppIBFtheFilter)
{
USES_CONVERSION;
HRESULT hr;
ICreateDevEnum* pEnum = NULL;
hr = CoCreateInstance( CLSID_SystemDeviceEnum,
NULL,
CLSCTX_ALL,
IID_ICreateDevEnum,
(void**)&pEnum );
if (FAILED(hr) ) { return false; }
IEnumMoniker* enumMoniker = NULL;
hr = pEnum->CreateClassEnumerator( CLSID_TheCategory, &enumMoniker, 0 );
if (enumMoniker)
{
enumMoniker->Reset();
IMoniker* moniker = NULL;
ULONG fetched = 0;
while (SUCCEEDED(enumMoniker->Next(1, &moniker, &fetched)) && fetched )
{
if (moniker)
{
WCHAR * wzDisplayName = NULL;
char displayName[512] = {0};
char friendlyName[256] = {0};
IPropertyBag * propertyBag = NULL;
_variant_t name;
hr = moniker->GetDisplayName( NULL, NULL, &wzDisplayName );
// moniker->GetClassID();
if (SUCCEEDED(hr) )
{
WideCharToMultiByte ( CP_ACP,
0,
wzDisplayName,
-1,
displayName,
1024,
"",
NULL );
CoTaskMemFree(wzDisplayName);
hr = moniker->BindToStorage( 0,
0,
IID_IPropertyBag,
(void**)&propertyBag );
}
if (SUCCEEDED(hr) )
{
name.vt = VT_BSTR;
hr = propertyBag->Read(L"FriendlyName", &name, NULL );
}
if (SUCCEEDED(hr) )
{
WideCharToMultiByte( CP_ACP,
0,
name.bstrVal,
-1,
friendlyName,
256,
NULL,
NULL );
hr = moniker->BindToObject( 0, 0, IID_IBaseFilter, (void**)ppIBFtheFilter);
}
if (SUCCEEDED(hr) )
{
if (strcmp(pcsFilterName->GetBuffer(), friendlyName) == 0 )
{
if (propertyBag)
{
propertyBag->Release();
propertyBag = NULL;
}
moniker->Release();
enumMoniker->Release();
pEnum->Release();
return hr;
}
else
{
(*ppIBFtheFilter)->Release();
(*ppIBFtheFilter) = NULL;
}
}
if (propertyBag)
{
propertyBag->Release();
propertyBag = NULL;
}
moniker->Release();
}
}
enumMoniker->Release();
}
pEnum->Release();
return hr;
}
奸臣 [等级:◆◆(初级)] (信誉值: 100) 回复于: 2004-12-11 9:44:38 Top
多谢了!
奸臣 [等级:◆◆(初级)] (信誉值: 100) 回复于: 2004-12-12 18:15:19 Top
不知我这么写有什么问题吗?
GetVideoCompressorFilter(IGraphBuilder* pGB, LPCTSTR lpszFilterName, IBaseFilter** ppFilter)
{
HRESULT hr = S_OK;
ppFilter = NULL;
CComPtr
hr = pDevEnum.CoCreateInstance( CLSID_SystemDeviceEnum );
if ( FAILED ( hr ) )
{
AfxMessageBox( "SystemDeviceEnum CreateInstance Failed!" );
return FALSE;
}
CComPtr
hr = pDevEnum->CreateClassEnumerator( CLSID_VideoCompressorCategory, &pEnumMoniker, 0 );
if ( FAILED ( hr ) )
{
AfxMessageBox( "VideoCompressorCategory CreateInstance Failed!" );
return FALSE;
}
CComPtr
ULONGcFetched;
while ( S_OK == pEnumMoniker->Next( 1, &pMoniker, &cFetched ) )
{
CComPtr
pMoniker->BindToStorage( 0, 0, IID_IPropertyBag, (void**)&pPropertyBag );
VARIANT varName;
varName.vt = VT_BSTR;
pPropertyBag->Read( L"FriendlyName", &varName, NULL );
CString strName( varName.bstrVal );
SysFreeString( varName.bstrVal );
if ( 0 == strName.Compare( lpszFilterName ) )
{
pMoniker->BindToObject( 0, 0, IID_IBaseFilter, (void**)&ppFilter );
pMoniker.Release();
return TRUE;
}
pMoniker.Release();
}
pEnumMoniker.Release();
pDevEnum.Release();
回头是岸 [等级:◆◆(初级)] (信誉值: 100) 回复于: 2004-12-13 10:25:59 Top
if ( 0 == strName.Compare( lpszFilterName ) )
{
pMoniker->BindToObject( 0, 0, IID_IBaseFilter, (void**)&ppFilter );
pMoniker.Release();
return TRUE;
}
pEnumMoniker, pDevEnum 没Release
///////////////////////////
pEnumMoniker.Release();
pDevEnum.Release();
加到return TRUE; 之前
肥猫 [等级:◆◆(初级)] (信誉值: 100) 回复于: 2004-12-13 11:22:16 Top
BOOL AddFilterByDisplayName(IGraphBuilder *pGraph, WCHAR *wszDisplayName,LPCWSTR wszName,
IBaseFilter **ppF)
{
HRESULT hr;
IMoniker *pMoniker=NULL;
if(!pGraph)
return FALSE;
IBaseFilter *pF=0;
IBindCtx *pBindCtx;
hr=CreateBindCtx(0,&pBindCtx);
ULONG chEaten=0;
hr= MkParseDisplayName(pBindCtx,wszDisplayName,&chEaten,&pMoniker);
pBindCtx->Release();
if(FAILED(hr))
{
return FALSE;
}
pMoniker->AddRef();
hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pF);
if (pF == NULL)
{
return FALSE;
}
hr = pGraph->AddFilter(pF, wszName);
if (hr != NOERROR)
{
return FALSE;
}
*ppF = pF;
pMoniker->Release();
return TRUE;
}
举例:
WCHAR szMon[] =L"@device:cm:{33D9A760-90C8-11D0-BD43-00A0C911CE86}\\xvid"; //xvid
if(!AddFilterByDisplayName(pFilterGraph,szMon,L"MPEG4 Encoder",&gcap.pMPEG4))
{
MessageBox("Add xvid Encoder Error");
return FALSE;
}