疑難解答秘訣
[與此頁面相關聯的功能,DirectShow是舊版功能。 它已被 MediaPlayer、IMFMediaEngine,和媒體基金會中的 音訊/視訊擷取取代。 這些功能已針對 Windows 10 和 Windows 11 進行優化。 Microsoft強烈建議新程式代碼盡可能在媒體 基礎中使用 MediaPlayer、IMFMediaEngine 和 音訊/視訊擷取,而不是 DirectShow。 Microsoft建議使用舊版 API 的現有程式代碼,盡可能改寫成使用新的 API。]
下列秘訣可協助您避免 DirectShow 應用程式中的死結或當機。
全域物件
全域C++物件不應在其建構函式方法中建立 DirectShow 物件,或將其釋放在其解構函式方法中。 這樣做可能會導致應用程式無限期封鎖,原因如下:
線程無法在 DLL 進入點函式內結束。 Kernel32 在進入點函式期間會保留全域處理程序鎖定,而鎖定可防止執行緒結束。 由於某些 DirectShow 物件擁有執行緒,因此如果從 DLL 入口點函式內釋放,它們可能會被阻塞。 如果應用程式具有全域 C++ 物件,C 執行階段 DLL 會在卸載 DLL 時呼叫物件的解構函式。 如果解構函式釋放 DirectShow 物件,它可能會因此封鎖。
基於類似的原因,DLL 不應該在其進入點例程中建立或釋放 DirectShow 物件。
發行介面
在應用程式仍在處理訊息之前,您應該釋放所有 DirectShow 介面指標,再結束訊息迴圈。 否則,您可能會看到各種斷言,因為某些 DirectShow 物件會在清理程序期間傳送訊息。
因此,如果您使用 ATL CWindowImpl 類別,請勿等到 OnFinalMessage 釋放介面。相反,當您處理 WM_CLOSE 訊息時,請立即釋放它們。
參考計數
當偵錯版本的 Quartz.dll 卸除時,它會檢查任何 DirectShow 物件是否有未釋放的參考計數。 如果是,它會引發斷言:
g_cFGObjects == 0
當這個判斷提示失敗時,這表示您的應用程式已洩漏參考計數。 檢閱您的程序代碼,並確定您釋放所有介面指標。
相關主題
-
DirectShow 中的 偵錯