Я написал небольшой фильтр преобразования (полученный из базового класса TransInPlaceFilter) и сумел заставить его работать должным образом в графе Directshow, целиком написанном на C ++.Я в основном выполнил 5 первых шагов, описанных в MSDN , и последнюю часть 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;
}