2013-08-09 2 views
0

Я использую DirectShow в своем приложении Qt.Работа с CLSID_FilterGraph в разных потоках

Чтобы создать экземпляр 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; 
} 

Позже я удалить свой объект graph_ptr в UI потоке. AFAIK, поток QApplication UI работает в модели потоков STA, но удаление работает без сбоев или утечек памяти. Правильно ли это?

Иногда мне нужно приостановить или возобновить мой объект graph_ptr в потоке пользовательского интерфейса.

// UI Thread 
_graph_ptr->pause(); 

Вот "пауза" implementatino в объекте graph_ptr:

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

Интерфейс IMediaControl был задан вопрос в QThreadPool в момент инициализации объекта graph_ptr.

Оказывается, я работаю с объектом из потока пользовательского интерфейса (STA), в то время как этот объект был создан в потоке QThreadPool (MTA). Все работает без сбоев, но я предполагаю, что не могу использовать объект по потокам с разными файловыми моделями?

Заранее спасибо.

ответ

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

Это не выглядит хорошо. CoUninitialize должен вызываться, когда все COM-операции завершены. Чтобы добавить к этому, вы должны проверить возвращаемые коды состояния. В потоке STA это приведет к ошибке на CoInitializeEx и не имеет аналогов CoUninitialize.

Скорее всего это приводит к нарушениям доступа. Может быть, вы просто не доберетесь до них. DirectShow использует упрощенный COM, и вы можете передавать исходные указатели между квартирами, однако вы должны делать самые важные вещи правильно: инициализация/неинициализация, подсчет ссылок. Чтобы не беспокоиться, вы захотите создать, запустить, остановить и освободить график в потоке STA.

+0

Roman, спасибо, что объяснил. У меня есть еще один вопрос: «:: CoUninitialize()» уничтожает MTA в моем приложении или нет (поскольку я ссылался на объект, который был создан в MTA »? – Dalamber

+0

' CoUninitialize' говорит буквально: «в этой теме я сделанный с помощью COM ". В противном случае может возникнуть проблема с COM. MTA может охватывать несколько потоков, поэтому этот вызов не обязательно полностью« уничтожает »MTA. –