我应该为 RTSP 客户端创建一个新线程还是只在媒体基础中使用自定义 IMFMediaSource

Should I create a new thread for RTSP client or just use custom IMFMediaSource in Media Foundation

我正在编写一个 RTSP 客户端并使用 Media Foundation 将多个 IP 摄像机视频源流式传输到 Windows 显示器。我知道内置的 MF RTSP 不能很好地处理 IP 摄像机,所以我必须编写自定义媒体源:

编写自定义媒体源: https://msdn.microsoft.com/en-us/library/windows/desktop/ms700134(v=vs.85).aspx

此外,以下 post 提供了一些有用的提示,但没有太多实施细节:

使用 Media Foundation 通过 RTSP 捕获 H264/AAC 流: https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/8f67d241-7e72-4509-b5f8-e2ba3d1a33ad/capture-h264aac-stream-via-rtsp-using-media-foundation?forum=mediafoundationdevelopment

如果我在我的自定义媒体源对象中编写我的 RTSP 代码,它是否能够在它自己的线程中充分 运行 并使用阻塞 "recv" 网络调用来接收相机流数据?或者 COM 对象不是真正可以处理此类任务的单独线程吗?阻塞 "recv" 调用和阻塞 COM 的工作队列之间是否存在潜在冲突?

或者我是否应该使用 "CreateThread" 创建一个新线程来处理所有 RTSP 细节并将相机流数据转发到媒体源对象?

任何能为我指明正确方向的建议都很棒!

实施您的媒体源并在实施内部:

  1. 当您的媒体源为 "started" 时创建线程:https://msdn.microsoft.com/en-us/library/windows/desktop/ms700134(v=vs.85).aspx#starting
  2. 从第 1 点开始,在您的线程中使用阻塞 recv(或者您可以实现更复杂的东西,如 IOCP 线程)。
  3. 对recv获得的每个RTSP帧进行排队
  4. 请求新样本时传送相应的帧(队列顶部):https://msdn.microsoft.com/en-us/library/windows/desktop/ms700134(v=vs.85).aspx#source_data

如果需要,您也可以引入 GAP,或者如果没有获得足够的数据,则重复最后一个样本。

Media Foundation 的设计建议您异步执行处理。有工作队列、事件生成器、start/stop 和其他操作预计将启动并且不阻塞地使用 notification/event 异步完成。

按照这种设计,您不需要很多线程。 Media Foundation 建议改用它的工作队列,它会根据需要实现线程池。

但这并不意味着你不能使用线程。当您为媒体基础源实现 interfaces/methods 强制性时,您将不得不实现异步模式,但如果您更喜欢在单独的工作线程上进行实际工作(在许多情况下会导致更简单的代码),那也没关系。