0

I'm using DirectShow in my Qt application.

To create the instance of Filter Graph, I am using QtConcurrent::run (i.e. using one of the available threads in global app thread pool).

Here's a simplified code sample that runs in QThreadPool:

graph_ptr createMovieGraph(const QString & file)
{
     ::CoInitializeEx(nullptr, COINIT_MULTITHREADED);
     auto * dst = graph_ptr(new MovieGraph(path));
     ::CoUninitialize();

     return dst;
}

Later, I delete my graph_ptr object in UI thread. AFAIK, QApplication UI thread works in STA threading model but deletion works without any crashes or memory leaks. Is it correct?

Sometimes I need to pause or resume my graph_ptr object in UI thread.

// UI Thread
_graph_ptr->pause();

Here's the "pause" implementatino in graph_ptr object:

_mediaControlInterface->Pause();
// ...
// CComPtr<IMediaControl>   _mediaControlInterface;

The IMediaControl interface was queried in QThreadPool at the graph_ptr object initialization time.

It turns out that I work with the object from UI thread (STA), while this object was created in QThreadPool (MTA) thread. Everything works without crashes, but I guess I cannot use object across threads with different threading models?

Thanks in advance.

4

1 回答 1

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

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

这很可能最终导致访问违规。也许你只是没有接触到他们。DirectShow 使用简化的 COM,您可以在公寓之间传递原始指针,但是您必须正确完成最重要的事情:初始化/取消初始化、引用计数。为了避免麻烦,您需要在 STA 线程上创建、运行、停止和释放图表。

于 2013-08-09T08:33:40.457 回答