我在我的Qt应用程序中使用DirectShow。
要创建Filter Graph的实例,我使用的是QtConcurrent :: run(即使用全局应用程序线程池中的一个可用线程)。
以下是在QThreadPool中运行的简化代码示例:
graph_ptr createMovieGraph(const QString & file)
{
::CoInitializeEx(nullptr, COINIT_MULTITHREADED);
auto * dst = graph_ptr(new MovieGraph(path));
::CoUninitialize();
return dst;
}
稍后,我在UI线程中删除了我的graph_ptr对象。 AFAIK,QApplication UI线程在STA线程模型中工作,但删除工作没有任何崩溃或内存泄漏。这是对的吗?
有时我需要在UI线程中暂停或恢复我的graph_ptr对象。
// UI Thread
_graph_ptr->pause();
这是graph_ptr对象中的“pause”implementatino:
_mediaControlInterface->Pause();
// ...
// CComPtr<IMediaControl> _mediaControlInterface;
在graph_ptr对象初始化时,在QThreadPool中查询了IMediaControl接口。
事实证明,我使用UI线程(STA)中的对象,而此对象是在QThreadPool(MTA)线程中创建的。 一切都没有崩溃,但我想我不能在具有不同线程模型的线程中使用对象?
提前致谢。
答案 0 :(得分:1)
::CoInitializeEx(nullptr, COINIT_MULTITHREADED);
auto * dst = graph_ptr(new MovieGraph(path));
::CoUninitialize();
这看起来不太好。所有COM活动完成后,必须调用CoUninitialize
。要添加到此,您必须检查返回的状态代码。在STA线程上,这将导致CoInitializeEx
上的错误和之后无法匹配的CoUninitialize
。
更有可能的是,这最终会导致访问冲突。也许你只是没有达到他们。 DirectShow使用简化的COM,你可以在公寓之间传递原始指针,但是你必须正确地做最重要的事情:初始化/未初始化,引用计数。为了避免麻烦,您可能希望在STA线程上创建,运行,停止和释放图形。