2011-02-11 106 views
2

我已經編寫了一個小型轉換過濾器(從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; 
} 
+1

無法看到任何有趣的東西,你有沒有嘗試在CreateInstance中放置一個斷點,然後將GraphEdit設置爲VS中的調試exe文件?然後看看你的突破點是否受到打擊。另外,在GraphEdit中,查看過濾器:如果展開過濾器詳細信息,「文件名」路徑是否正確? – Ralf 2011-02-12 12:28:00

+0

在GraphEdit中,「文件名」是正確的並指向我的DLL。優點,引腳和媒體信息也是正確的。我會盡快嘗試直接調試GE,感謝您的建議。 – BlueCookie 2011-02-14 08:51:36

+0

現在一切都很好!直接調試DLL幫助我解決了這個問題。我將發佈一篇文章並編輯原文... – BlueCookie 2011-02-14 10:07:09

回答

1

有一兩件事要檢查將是該GUID是一樣的無處不在:AMOVIESETUP_FILTER,CFactoryTemplate,並傳遞給CTransInPlaceFilter構造。

此外,最好將CCustomFilter :: CreateInstance的pUnk和pHr參數傳遞給您的CCustomFilter構造函數,並從那裏傳遞給CTransInPlaceFilter構造函數,以便將任何錯誤傳播給調用者。在你的情況下,任何這樣的錯誤都會被你的構造函數吞噬。例如:

CUnknown* WINAPI FramerateDisplayFilter::CreateInstance(LPUNKNOWN pUnk, 
                 HRESULT *pHr) 
{ 
    FramerateDisplayFilter *pFilter = new FramerateDisplayFilter(pUnk, pHr); 
    if (pFilter== NULL) 
    { 
    *pHr = E_OUTOFMEMORY; 
    } 
    return pFilter; 
} 


FramerateDisplayFilter::FramerateDisplayFilter(LPUNKNOWN pUnk, HRESULT *pHr) 
: CTransInPlaceFilter(NAME("CSIR RTVC Framerate Estimator Filter"), pUnk, 
         CLSID_RTVCFramerateEstimatorFilter, pHr, false), 
    m_uiEstimatedFramerate(0), 
    m_bSeenFirstFrame(false), 
    m_previousTimestamp(0) 
{;} 
3

問題解決了。它實際上是兩兩件事:

  1. 直接調試DLL(財產以後我沒有想到的...),更具體CoCreateInstance函數,幫助我發現與字符串宏的問題。 TransInPlaceFilter的構造函數被調用了一個錯誤的參數,導致了崩潰。

  2. 有人讓我注意到我沒有導出每個必需的功能(如在MSDN上描述here)。我的。def文件缺少DllMain,DllGetClassObject和DllCanUnloadNow。那2個最後的函數只需要出現在def中,因爲它們已經在baseclasses庫中定義了。

`

LIBRARY "custom_filter" 
EXPORTS 
    DllMain     PRIVATE /* missing */ 
    DllGetClassObject  PRIVATE /* missing */ 
    DllCanUnloadNow   PRIVATE /* missing */ 
    DllRegisterServer  PRIVATE 
    DllUnregisterServer  PRIVATE 

非常感謝您的幫助!

相關問題