在不同的线程中使用CLSID_FilterGraph

时间:2013-08-09 07:11:47

标签: qt com directshow

我在我的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)线程中创建的。 一切都没有崩溃,但我想我不能在具有不同线程模型的线程中使用对象?

提前致谢。

1 个答案:

答案 0 :(得分:1)

 ::CoInitializeEx(nullptr, COINIT_MULTITHREADED);
 auto * dst = graph_ptr(new MovieGraph(path));
 ::CoUninitialize();

这看起来不太好。所有COM活动完成后,必须调用CoUninitialize。要添加到此,您必须检查返回的状态代码。在STA线程上,这将导致CoInitializeEx上的错误和之后无法匹配的CoUninitialize

更有可能的是,这最终会导致访问冲突。也许你只是没有达到他们。 DirectShow使用简化的COM,你可以在公寓之间传递原始指针,但是你必须正确地做最重要的事情:初始化/未初始化,引用计数。为了避免麻烦,您可能希望在STA线程上创建,运行,停止和释放图形。