DirectX Surface Buffer

The DirectX surface buffer object is a media buffer that manages a Direct3D surface. To create an instance of this object, call MFCreateDXSurfaceBuffer and pass in a pointer to the DirectX surface. The DirectX surface buffer exposes the following interfaces:

There are several ways to access the surface memory from the buffer object:

  • Recommended: Call IMFGetService::GetService on the buffer. Use the service identifier MR_BUFFER_SERVICE. The method returns a pointer to the underlying Direct3D surface.
  • Call IMF2DBuffer::Lock2D. This method calls IDirect3DSurface9::LockRect directly on the surface. The IMF2DBuffer::Unlock2D method calls UnlockRect on the surface.
  • Call IMFMediaBuffer::Lock. Generally this is not recommended, because it forces the object to copy memory from the Direct3D surface and then back again. The Lock2D method is more efficient.

Both Lock and Lock2D can fail if the underlying surface is not lockable. The DirectX surface buffer implements these two methods primarily for components that are not designed to work with Direct3D surfaces.

The enhanced video renderer (EVR) creates DirectX surface buffers when the decoder is not configured for DirectX Video Acceleration (DXVA). For more information, see IMFVideoSampleAllocator.

Obtaining the Direct3D Surface

To get a Direct3D surface from a video sample, do the following:

  1. Call IMFSample::GetBufferByIndex with an index value of zero.
  2. Call MFGetService and specify the MR_BUFFER_SERVICE service identifier.

The following code shows these steps:

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;
}

Media Buffers

Video Samples