DShow默认的预览窗口(IVideoWindow)对绘制的控制太弱了,想自己在上面叠加文字线条什么的几乎不可能。使用VMR-7或者VMR-9显示的控制要方便很多。
#include <d3d9.h>
#include <Vmr9.h>
// Create the VMR-9:
hr = CoCreateInstance(CLSID_VideoMixingRenderer9, 0,
CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&m_pVmr9);
if (FAILED(hr))
{
return FALSE;
}
// Add the VMR-9 to the filter graph:
hr = m_pGraphBuilder->AddFilter(m_pVmr9, L"VMR9");
if (FAILED(hr))
return FALSE;
// Set video window style and position
hr = SetupVideoWindow();
if (FAILED(hr))
return FALSE;
// Render the preview pin on the video capture filter
// Use this instead of m_pGraph->RenderFile
hr = m_pCapture->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,
m_pSrcFilter, NULL, m_pVmr9);
if (FAILED(hr))
{
SAFE_RELEASE(m_pSrcFilter);
return FALSE;
}
HRESULT CDShowDevStream::SetupVideoWindow()
{
HRESULT hr;
HWND hwnd;
IVMRWindowlessControl* pWc = NULL;
// Set the rendering mode and number of streams.
IVMRFilterConfig *pConfig;
hr = m_pVmr9->QueryInterface(IID_IVMRFilterConfig9, (void**)&pConfig);
if (SUCCEEDED(hr))
{
pConfig->SetRenderingMode(VMRMode_Windowless);
pConfig->Release();
}
hwnd = (HWND)param_.window.info.win.hwnd;
// Set the video window to be a child of the main window
hr = m_pVmr9->QueryInterface(IID_IVMRWindowlessControl9, (void**)&m_pVmrWc);
if (SUCCEEDED(hr))
{
m_pVmrWc->SetVideoClippingWindow(hwnd);
}
else
return hr;
// Find the native video size.
long lWidth, lHeight;
HRESULT hr = m_pVmrWc->GetNativeVideoSize(&lWidth, &lHeight, NULL, NULL);
if (SUCCEEDED(hr))
{
RECT rcSrc, rcDest;
// Set the source rectangle.
SetRect(&rcSrc, 0, 0, lWidth, lHeight);
// Get the window client area.
GetClientRect(hwnd, &rcDest);
// Set the destination rectangle.
SetRect(&rcDest, 0, 0, rcDest.right, rcDest.bottom);
// Set the video position.
hr = m_pVmrWc->SetVideoPosition(&rcSrc, &rcDest);
}
return hr;
}
MSDN上面的主要参考资料
https://msdn.microsoft.com/en-us/library/ms779725(v=VS.85).ASPx
https://msdn.microsoft.com/en-us/library/ms787876.aspx
网友评论