1

I have a decoder which produces NV12 yuv frames. What I would like to do is to copy that frame to ID3D11Texture2D texture with single memcpy. Because D3D11_MAPPED_SUBRESOURCE has a different RowPitch than my NV12 frame has I have to copy whole yuv row by row which is pretty expensive. Is there a better way to do this?

I've tried to find any information on this topic but so far without any luck.

// Copy from CPU access texture to bitmap buffer
D3D11_MAPPED_SUBRESOURCE resource;
UINT subresource = D3D11CalcSubresource(0, 0, 0);
OutMgr.m_DeviceContext->Map(OutMgr.m_texture, subresource, D3D11_MAP_WRITE_DISCARD, 0, &resource);

BYTE* dptr = reinterpret_cast<BYTE*>(resource.pData);

for (int i = 0; i < nv12Frame->height; i++)
{
    memcpy(dptr + resource.RowPitch * i, nv12Frame->Y + nv12Frame->pitch * i, nv12Frame->pitch);
}

for (int i = 0; i < nv12Frame->height / 2; i++)
{
    memcpy(dptr + resource.RowPitch *(nv12Frame->height + i), nv12Frame->UV + nv12Frame->pitch * i, nv12Frame->pitch);
}

OutMgr.m_DeviceContext->Unmap(OutMgr.m_texture, subresource);
Teamol
  • 733
  • 1
  • 14
  • 42
  • IMHO with the layout of your nv12Frame this is the fastest way to copy it properly. memcpy should be SSE2 optimized (if SSE2 is available), so it should be really fast on modern CPUs and compilers. https://stackoverflow.com/questions/2963898/faster-alternative-to-memcpy Another approach might involve compute or even pixel shaders somehow (with a render target texture), but you will need to upload the nv12Frame to the shader somehow anyway. – VuVirt Sep 25 '19 at 20:00

0 Answers0