1

(痛苦地)学习如何使用拓扑和会话来呈现捕获的视频。没什么特别的——只需选择一个网络摄像头,列出它的模式,选择一种视频格式,然后点击“开始”。一般来说,这些是我呈现视频捕获的步骤:

  1. 列出具有MFEnumDeviceSources()过滤条件的可用设备MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID并让用户选择一个
  2. GetStreamDescriptorCount()在激活源并创建 Presentation Descriptors 之后列出流CreatePresentationDescriptor()并让用户选择一个流(如果有多个流可用)
  3. 根据IMFMediaType可用的列表显示所有支持的视频格式,GetMediaTypeByIndex()并让用户选择一种

一旦选择了确切的格式,我就会以这种方式构建拓扑:

  1. 调用MFCreateTopology()创建一个新IMFTopology对象
  2. 创建媒体接收器激活MFCreateVideoRendererActivate()
    1. 确保调用当前选择SetCurrentMediaType()的对象IMFMediaTypeHandlerIMFStreamDescriptor
  3. 创建源节点MFCreateTopologyNode(),通过调用设置其表示和流描述符SetUnknown()并将该节点添加到拓扑
    1. 确保将其电流设置IMFMediaType为用户选择的SetCurrentMediaType()
  4. 创建一个输出节点并调用SetObject()它,提供先前创建的媒体接收器激活对象(来自上面的步骤 5)
  5. 将源连接到输出并ConnectOutput()为其提供节点 ID0

单击“预览”按钮时,会IMFMediaSession使用新拓扑设置会话对象(在应用程序启动时创建)

m_session->SetTopology(MFSESSION_SETTOPOLOGY_IMMEDIATE, pTopo);

这就是我看到一些奇怪的地方。我根据用户选择的帧尺寸设置预览视频的大小,IMFMediaType并且源似乎正在以该格式生成视频。然而,渲染器错误地处理了像素纵横比,并且在将图片呈现为垂直或水平拉伸的同时对视频进行了信箱/邮筒处理。

对于我的一生,我无法找到告诉渲染器调整正确像素纵横比的方法(在上面的步骤 5.1 中设置为正确的值)


MS 的 SDK 示例仅显示如何为未压缩格式呈现捕获的视频 - 它不使用IMFMediaSession对象并且适用于YUV2格式但不适用于MJPG. 事实上,它工作得很好,我认为继续使用会话会很容易:)

使用IMFMediaSession似乎是支持压缩视频格式的最简单的方式,尤其是H.264在较新的UVC 1.5标准中以及H.265将来出现的任何新 (?) 格式中。

4

1 回答 1

0

进一步的研究表明,可以通过查询会话来访问渲染器对象以获取服务,然后使用该服务来获取视频显示控制。该IMFVideoDisplayControl对象可让您控制渲染视频的各个方面,包括图像的纵横比。

以下是获取该IMFVideoDisplayControl对象的方法:

  1. 得到IMFGetService

    hr = m_session->QueryInterface<IMFGetService>(&service);

  2. 得到IMFVideoDisplayControl

    hr = service->GetService(MR_VIDEO_RENDER_SERVICE, IID_IMFVideoDisplayControl, (void**)&control);

一旦你有了显示控制对象,你就可以完成其余的工作。在我的情况下(因为我知道预期视频的实际真实几何形状),解决方案是将宽高比模式设置为MFVideoARMode_None

于 2016-03-03T02:55:51.637 回答