我编写了一个小型变换过滤器(派生自 TransInPlaceFilter 基类),并设法使其在 Directshow 图中正常工作,完全用 C++ 编码。我基本上遵循了MSDN上描述的 5 个第一步,以及第 6 步的最后一部分(为了在应用程序中直接使用过滤器)。
由于很多原因(包括能够在 GraphEdit 中使用过滤器),我需要将该过滤器导出到 DLL 中并进行注册。
我一直在尝试遵循这些步骤:设置“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;
}