DirectX Surface 缓冲区
DirectX 表面缓冲区对象是管理 Direct3D 表面的媒体缓冲区。 若要创建此对象的实例,请调用 MFCreateDXSurfaceBuffer 并传入指向 DirectX 图面的指针。 DirectX 表面缓冲区公开以下接口:
可通过多种方式从缓冲区对象访问表面内存:
- 建议:在缓冲区上调用 IMFGetService::GetService 。 使用 服务标识符MR_BUFFER_SERVICE。 方法返回指向基础 Direct3D 图面的指针。
- 调用 IMF2DBuffer::Lock2D。 此方法直接在图面上调用 IDirect3DSurface9::LockRect 。 IMF2DBuffer::Unlock2D 方法在表面上调用 UnlockRect。
- 调用 IMFMediaBuffer::Lock。 通常不建议这样做,因为它会强制对象从 Direct3D 图面复制内存,然后再次复制。 Lock2D 方法更高效。
如果基础表面不可锁定, Lock和 Lock2D 都可能失败。 DirectX 表面缓冲区实现这两种方法主要用于不设计用于 Direct3D 图面的组件。
当未将解码器配置为 DirectX 视频加速 (DXVA) 时,增强的视频呈现器 (EVR) 会创建 DirectX 表面缓冲区。 有关详细信息,请参阅 IMFVideoSampleAllocator。
获取 Direct3D Surface
若要从视频示例获取 Direct3D 图面,请执行以下操作:
- 调用索引值为零的 IMFSample::GetBufferByIndex 。
- 调用 MFGetService 并指定 MR_BUFFER_SERVICE 服务标识符。
以下代码演示了这些步骤:
HRESULT GetD3DSurfaceFromSample(IMFSample *pSample, IDirect3DSurface9 **ppSurface)
{
*ppSurface = NULL;
IMFMediaBuffer *pBuffer = NULL;
HRESULT hr = pSample->GetBufferByIndex(0, &pBuffer);
if (SUCCEEDED(hr))
{
hr = MFGetService(pBuffer, MR_BUFFER_SERVICE, IID_PPV_ARGS(ppSurface));
pBuffer->Release();
}
return hr;
}
相关主题