疑难解答指南

[与此页面关联的功能 DirectShow 是一项旧功能。 它已被 MediaPlayerIMFMediaEngine媒体基金会中的音频/视频捕获取代。 这些功能已针对Windows 10和Windows 11进行了优化。 Microsoft 强烈建议新代码尽可能使用 MediaPlayerIMFMediaEngineMedia Foundation 中的音频/视频捕获 ,而不是 DirectShow。 如果可能,Microsoft 建议重写使用旧 API 的现有代码以使用新 API。]

以下提示将帮助你避免 DirectShow 应用程序中出现死锁或崩溃。

全局对象

全局 C++ 对象不应在其构造函数方法中创建 DirectShow 对象,也不应在其析构函数方法中释放它们。 这样做可能会导致应用程序无限期阻止,原因如下:

线程在 DLL 的入口点函数内时无法退出。 内核 32 在入口点函数期间持有全局进程锁,锁阻止线程退出。 由于某些 DirectShow 对象拥有线程,因此,如果从 DLL 入口点函数内部释放,它们可能会阻塞。 如果应用程序具有全局 C++ 对象,则 C 运行时 DLL 在卸载 DLL 时调用该对象的析构函数。 如果析构函数释放 DirectShow 对象,则它可能会因此而阻塞。

出于类似原因,DLL 不应在其入口点例程中创建或释放 DirectShow 对象。

释放接口

在应用程序退出消息循环之前,应在应用程序仍在处理消息时释放所有 DirectShow 接口指针。 否则,你可能会看到各种断言,因为某些 DirectShow 对象在其清理例程期间发送消息。

(作为推论,如果使用 ATL CWindowImpl 类,请不要等到 OnFinalMessage 释放接口。而是在处理WM_CLOSE message.)

引用计数

当调试版本的 Quartz.dll 卸载时,它会检查是否有任何 DirectShow 对象具有未释放的引用计数。 如果是这样,它将引发断言:

g_cFGObjects == 0 

如果此断言失败,则表示应用程序已泄漏引用计数。 查看代码并确保释放所有接口指针。

在 DirectShow 中进行调试