清除Media Foundation中的预览窗口

时间:2018-10-30 13:42:22

标签: camera preview ms-media-foundation

从相机进行预览后,是否可以清除预览窗口?我正在使用MFCaptureEngine,调用m_pPreview-> SetRenderHandle(m_hwnd)渲染视频。但是当我停止视频时,我无法在窗口上绘制。相机还有最后一帧。我需要用黑色笔刷填充窗口并绘制一些文本,但相机的图像无法覆盖。

2 个答案:

答案 0 :(得分:1)

目前尚不清楚您的答案是什么MFCaptureManager,但是根据代码SetRenderHandle(m_hwnd),我看到您使用了IMFCapturePreviewSink::SetRenderHandle。因此,可以说我前段时间也遇到过类似的问题,这与WinXP中存在的旧窗口系统与Vista中当前窗口系统之间的差异有关。代码通过调用IMFCapturePreviewSink::SetRenderHandle来设置渲染器的窗口上下文-对于IMFCapturePreviewSink,它是DirectX11-并且DirectX11已完全访问该窗口,并且已切换到当前窗口系统。结果,由Win95-XP时代的旧Windows API完成的任何调用fill the window by black brush and draw some text都无济于事-因为窗口处理程序上下文被DirectX11锁定。

有三种方法可以解决此问题:

  1. 通过基于DirectX11的新Microsoft DirectComposition GUI API编写新的UI,并将其设置为IMFCapturePreviewSink::SetRenderSurface
  2. 通过MFCreateVideoRenderer创建EVR媒体接收器-它创建与Win95-XP一代的旧Windows API兼容的DirectX9视频渲染器,并在IMFCapturePreviewSink::SetCustomSink中设置此IMFMediaSink
  3. 在DirectX9的基础上创建视频渲染器的代码-例如MFCaptureD3D/device.cpp,然后从回调IMFCapturePreviewSink::SetSampleCallback中提取原始IMFSample。

致谢。

答案 1 :(得分:0)

我是这样实现的:

// Sink
CComPtr<IMFCaptureSink> pSink;
m_pEngine->GetSink(MF_CAPTURE_ENGINE_SINK_TYPE_PREVIEW, &pSink);

CComPtr<IMFMediaSink> pCustomSink;
::MFCreateVideoRenderer(IID_IMFMediaSink, (void**)&pCustomSink);

CComPtr<IMFCapturePreviewSink> pPreviewSink;
pSink.QueryInterface(&pPreviewSink);
pPreviewSink->SetCustomSink(pCustomSink);

// preview
pSink.QueryInterface(&m_pPreview); // or pPreviewSink.QueryInterface(&m_pPreview)
m_pPreview->SetRenderHandle(m_hwndPreview);

但是行为仍然相同(停止预览后无法重绘屏幕)。