我已經編寫了一個小型轉換過濾器(從TransInPlaceFilter基類派生而來),並設法使其在Directshow圖形中正常工作,完全使用C++編碼。我基本上遵循MSDN中描述的5個第一步和第6步的最後部分(爲了在應用程序中直接使用過濾器)。使用自定義DirectShow過濾器(DLL,已註冊)
由於很多原因(包括能夠在GraphEdit中使用過濾器),我需要將該過濾器導出到DLL中並註冊它。
我一直努力遵循these steps:建立 「的CreateInstance」 方法,將CFactoryTemplate類,過濾器/引腳說明(AMOVIESETUP_FILTER,AMOVIESETUP_PIN,AMOVIESETUP_MEDIA),註冊/註銷功能,最後的DllMain /入口點。
該代碼成功編譯並提供了一個DLL,它似乎使用Regsvr32註冊時沒有任何問題。
但後來我不能使用的過濾器:
- 它出現在GraphEdit中的列表中,但是當我嘗試插入失敗:0x800401f9(「錯誤的DLL」)。
- 當我嘗試用C來創建它++(使用
pCustomFilter.CoCreateInstance(CLSID_Custom)
,確定正確的GUID後),我收到0x80040154錯誤(REGDB_E_CLASSNOTREG)
我很困惑在這裏。我錯過了DLL /註冊碼中的某些內容嗎?我發佈了大部分我正在使用的代碼,如果它有任何用處的話。
任何幫助將不勝感激。
static const WCHAR g_wszName[] = L"Custom Filter";
AMOVIESETUP_MEDIATYPE sudMediaTypes[] = {
{ &MEDIATYPE_Video, &MEDIASUBTYPE_NULL },
{ &MEDIATYPE_Audio, &MEDIASUBTYPE_NULL },
};
AMOVIESETUP_PIN sudPins[2] = {
{
L"Input", // Name
FALSE, // Is this pin rendered?
FALSE, // Is it an output pin?
FALSE, // Can the filter create zero instances?
FALSE, // Does the filter create multiple instances?
&GUID_NULL, // Obsolete.
NULL, // Obsolete.
2, // Number of media types.
sudMediaTypes // Pointer to media types.
},
{
L"Output", // Name
FALSE, // Is this pin rendered?
TRUE, // Is it an output pin?
FALSE, // Can the filter create zero instances?
FALSE, // Does the filter create multiple instances?
&GUID_NULL, // Obsolete.
NULL, // Obsolete.
2, // Number of media types.
sudMediaTypes // Pointer to media types.
}
};
AMOVIESETUP_FILTER sudFilterReg = {
&CLSID_Custom, // Filter CLSID.
g_wszName, // Filter name.
MERIT_DO_NOT_USE, // Merit.
2, // Number of pin types.
sudPins // Pointer to pin information.
};
CFactoryTemplate g_Templates[] =
{
{
g_wszName,
&CLSID_Custom,
CCustomFilter::CreateInstance,
NULL,
&sudFilterReg
}
};
int g_cTemplates = sizeof(g_Templates)/sizeof(g_Templates[0]);
STDAPI DllRegisterServer()
{
return AMovieDllRegisterServer2(TRUE);
}
STDAPI DllUnregisterServer()
{
return AMovieDllRegisterServer2(FALSE);
}
extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
BOOL WINAPI DllMain(HANDLE hDllHandle, DWORD dwReason, LPVOID lpReserved)
{
return DllEntryPoint(reinterpret_cast<HINSTANCE>(hDllHandle), dwReason, lpReserved);
}
// ---
// Meanwhile, in my filter class...
// ---
CUnknown * WINAPI CCustomFilter::CreateInstance(LPUNKNOWN pUnk, HRESULT *pHr)
{
CCustomFilter *pFilter = new CCustomFilter();
if (pFilter== NULL)
{
*pHr = E_OUTOFMEMORY;
}
return pFilter;
}
無法看到任何有趣的東西,你有沒有嘗試在CreateInstance中放置一個斷點,然後將GraphEdit設置爲VS中的調試exe文件?然後看看你的突破點是否受到打擊。另外,在GraphEdit中,查看過濾器:如果展開過濾器詳細信息,「文件名」路徑是否正確? – Ralf 2011-02-12 12:28:00
在GraphEdit中,「文件名」是正確的並指向我的DLL。優點,引腳和媒體信息也是正確的。我會盡快嘗試直接調試GE,感謝您的建議。 – BlueCookie 2011-02-14 08:51:36
現在一切都很好!直接調試DLL幫助我解決了這個問題。我將發佈一篇文章並編輯原文... – BlueCookie 2011-02-14 10:07:09