IMFMediaEngine 总是 运行 在 640x480 使用 DirectComposition

IMFMediaEngine always run in 640x480 using DirectComposition

我正在使用 IMFMediaEngine 播放视频流(Smooth Streaming,HLS),稍后可能会使用 PlayReady

使用 TransferVideoFrame 将视频绘制到纹理上效果非常好。但我知道 PlayReady + DRM + 1080p 视频需要使用 DirectComposition。所以我正在努力使它起作用。

这样做的另一个好处是,视频帧渲染独立于应用程序,因此应用程序中可能出现的卡顿或延迟 UI 不会影响视频播放。

我能够让它工作,但不幸的是,我使用的 IDCompositionVisual 最终总是被限制为 640x480。所以视频必须缩小到它。然后,如果我对其进行变换以按比例放大,我会得到一张丑陋的拉伸图片。

我是这样注册Visual的:

pMediaAttributes->SetUnknown(MF_MEDIA_ENGINE_PLAYBACK_VISUAL, m_pDcompVideoVisual);

如此处所述: https://msdn.microsoft.com/en-us/library/windows/desktop/hh162850(v=vs.85).aspx

尝试在 Visual 上先创建表面并 SetContent 不会改变任何内容。就像视频播放器用自己的表面覆盖它一样,640x480。将它坚持到简单的播放器,找到这个问题的真正解决方案并能够在我收到 MF_MEDIA_ENGINE_EVENT_FORMATCHANGE[=37= 时指定 Visual Surface 的大小真的很好] 事件。

因为这是 IMFMediaEngine 中用于指定 DirectComposition 表面的选项,所以必须有一种方法可以使它起作用。

根据我为 IMFMediaEngine, you should be able to handle DRM protected content using IMFMediaEngineProtectedContent->TransferVideoFrame 看到的文档:

对于受保护的内容,调用此方法而不是 IMFMediaEngine::TransferVideoFrame 方法。

您提供的示例的 VideoPlayer::CaptureFrame 方法中可以包含类似这样的内容:

// Transfer the frame to the texture
auto pIMFMediaEngineUnknown = reinterpret_cast<IUnknown *>(m_pMediaEngine);
IMFMediaEngineProtectedContent *temp = 0;
pIMFMediaEngineUnknown->QueryInterface(IID_PPV_ARGS(&temp));
DWORD flags = 0;
HRESULT ret = temp->TransferVideoFrame(m_pRenderTarget, &videoRect, &targetRect, &borderColor, &flags);
temp->Release();

//HRESULT ret = m_pMediaEngine->TransferVideoFrame(m_pRenderTarget, &videoRect, &targetRect, &borderColor);
assert(ret == S_OK && "Failed to transfer video frame");

试一试 1080p 受保护的内容。