windows - 在 Media Foundation 中使用 COINIT_APARTMENTTHREADED 或 COINIT_MULTITHREADED?

标签 windows multithreading com video-streaming ms-media-foundation

在我对媒体基金会的研究中,我遇到了一些来自两个非常有信誉的来源的看似矛盾的建议。

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

In Media Foundation, asynchronous processing and callbacks are handled by work queues. Work queues always have multithreaded apartment (MTA) threads, so an application will have a simpler implementation if it runs on an MTA thread as well. Therefore, it is recommended to call CoInitializeEx with the COINIT_MULTITHREADED flag.

然后摘自《开发 Microsoft 媒体基础应用程序 - 作者:Anton Polinger》一书第 24 页:

Note MF is a free-threaded system, which means that COM interface methods can be invoked from arbitrary threads. Therefore, when calling CoInitializeEx(), you must initialize COM with the apartment-threaded object concurrency by passing in the COINIT_ APARTMENTTHREADED parameter. Your objects might also need to use synchronization primitives, such as locks, to control access to internal variables by concurrently running threads.

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

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

最佳答案

Media Foundation 不会使用编码(marshal)处理(也就是说,它们使用直接通信)并且它的对象使用“两者”单元模型,在运行时使用免费的线程编码(marshal)处理。

户型自由选择,MTA和STA都可以解决。然而,由 Media Foundation 启动的工作线程将始终被初始化为 MTA(特别是因为 MF 的设计不建议线程对齐,例如在工作队列上并且执行 STA 没有任何意义;由应用程序初始化的控制线程可以是 STA ).

也就是说,初始化控制线程为STA是没有错的。它对媒体基础 API 调用没有影响。文档建议 MTA 初始化的唯一原因是将所有线程都初始化为 MTA,这样就不会错误地混淆单元,这将特别容易,因为 API 正在忽略标准 COM 单元规则的线程之间主动传递 COM 指针。如果您了解您不会受到此行为的影响,则 STA 初始化将很适合您。因为您已经找到许多媒体基础示例,并且应用程序正在执行 STA 初始化。

关于windows - 在 Media Foundation 中使用 COINIT_APARTMENTTHREADED 或 COINIT_MULTITHREADED?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45334838/

相关文章:

windows - 在我的应用程序退出前将终止的线程上调用 CoUninitialize 是否重要?

python - 尝试通过 com/pywin32 从 Python 运行 Excel-Solver 时出错

windows - 我需要 Hook 什么进程 API 来跟踪服务?

c++ - 我可以从对话框的 DoModal 函数返回自定义值吗?

java.lang.RuntimeException : Can't create handler inside thread that has not called Looper. 准备()

python - SQL 数据库中查询的多线程

C# 在 COM 重应用中的使用

windows - teracopy 如何替换默认的 Windows 副本

java - 从 Windows 命令提示符了解 JRE 是 32 位还是 64 位

java - 应用程序在使用 AsyncTask 时挂起并挂起所有线程