在Media Foundation中使用COINIT_APARTMENTTHREADED或COINIT_MULTITHREADED?

问题描述:

在我对媒体基金会的研究中,我遇到了一些来自两个非常有名的消息来源的看似矛盾的建议。在Media Foundation中使用COINIT_APARTMENTTHREADED或COINIT_MULTITHREADED?

从MSDN: 媒体基金会和COM: https://msdn.microsoft.com/en-us/library/windows/desktop/ee892371(v=vs.85).aspx

在媒体基金会,异步处理和回调是由工作队列处理。工作队列总是有多线程单元(MTA)线程,所以如果应用程序也在MTA线程上运行,它的实现将更简单。因此,建议使用COINIT_MULTITHREADED标志调用CoInitializeEx。

然后从书“开发Microsoft媒体基础应用 - 安东Polinger”第24页:

注MF是一个免费的线程系统,这意味着,COM接口方法可以 从调用任意线程。因此,在调用CoInitializeEx()时,必须通过传递COINIT_ APARTMENTTHREADED参数来初始化带有单元线程对象并发性的 COM。您的对象可能还需要使用同步原语(如锁)来通过同时运行 线程来控制对内部变量的访问。

此外,我在GitHub中看到了很多使用COINIT_APARTMENTTHREADED的Media Foundation示例代码。

我正在开发一个RTSP客户端,它使用Media Foundation将多个IP摄像机视频源传输到Windows显示器。我将在我的应用程序中使用多个线程,所以我相信在这个问题上得到明确的答案将是非常重要的。有人可以解释矛盾并就正确的方式提出建议吗?

+0

MSDN提供了事实,除非另有证明;这是官方文件。任何线程都可以使用“*线程系统”(与MSDN一致),所以我不明白为什么本书说你必须“初始化”STA。 –

Media Foundation不会使用封送处理(即它们使用直接通信),其对象使用“Both”公寓模型,并在运行时使用*线程封送处理。

你可以*选择公寓模型,MTA和STA都将制定出来。然而,由Media Foundation启动的工作线程始终会被初始化为MTA(具体原因是因为MF的设计并未建议线程对齐,例如在工作队列上,并且在STA中没有意义;由应用程序初始化的控制线程可以是STA )。

也就是说,将控制线程初始化为STA没有任何问题。它对Media Foundation API调用没有影响。该文档建议MTA初始化为所有线程初始化为MTA的唯一原因是没有机会错误地混淆公寓,这将会特别容易,因为API正在主线之间传递COM指针,忽略标准COM公寓规则。如果你明白你不会受到这种行为的影响,那么STA初始化对你来说会很好。正如您找到许多媒体基金会的样本,并且应用程序正在进行STA初始化。

+0

谢谢罗马R. –