使用 VMR9 在 NPAPI 中进行视频呈现

Using VMR9 for video rendering in NPAPI

本文关键字:视频 VMR9 NPAPI 使用      更新时间:2023-10-16

我正在使用DirectShow在NPAPI插件中进行视频渲染。我编写了一个将 YUY2 样本推送到上游的源过滤器,我试图在无窗口模式下使用 VMR9 将视频渲染到插件的 HWND 中。无论如何,框架实际上正在交付,但插件窗口中没有显示任何输出。我确定帧交付,因为如果我在窗口模式下使用 VMR9,我实际上可以看到视频。

这段代码用于图形构建和呈现。

// init VMR9 filter
IBaseFilter *pVmr = NULL;
HRESULT hr = CoCreateInstance(CLSID_VideoMixingRenderer9, 0,
    CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pVmr);
hr = _base->AddFilter(pVmr, L"VMR9");
pVmr->Release();
// set VMR9 windowless
IVMRFilterConfig9* pConfig;
hr = pVmr->QueryInterface(IID_IVMRFilterConfig9, (void**)&pConfig);
if (SUCCEEDED(hr))
{
    pConfig->SetRenderingMode(VMRMode_Windowless);
    pConfig->SetNumberOfStreams(1);
    pConfig->Release();
}
// set VMR9 clipping window
IVMRWindowlessControl9* pWc = NULL;
hr = pVmr->QueryInterface(IID_IVMRWindowlessControl9, (void**)&pWc);
if (SUCCEEDED(hr))
{
    hr = pWc->SetVideoClippingWindow((_outputWindow));
    RECT r;
    GetWindowRect(_outputWindow, &r);
    pWc->SetVideoPosition(NULL, &r);
    pWc->Release();
}
// init source filter
IBaseFilter *pSource = new NetReceiverFilter();
hr = _base->AddFilter(pSource, L"Net Receiver");
_capture->RenderStream(0, 0, pSource, 0, pVmr);

long evCode;
_control->Run();
_event->WaitForCompletion(10000, &evCode);

哪里:

  • _outputWindow是插件的HWND
  • _base是 IGraphBuilder *
  • _build是ICaptureGraphBuilder2 *
  • _control是 IMediaControl *
  • _event是 IMediaEvent *

IVMRWindowlessControl9::SetVideoPosition获取客户端(相对)坐标,而GetWindowRect获取屏幕(绝对)坐标,您需要解决这个问题,例如使用GetclientRect,或使用额外的ScreenToClient调用。