Reputation: 1
Copying a ID3D11Texture2D to a byte array is causing out of memory error c++
The copy is happening every frame and it runs for around 5 seconds until I get the memory error, which is happening on either
HRESULT hr = device->CreateTexture2D(&description, NULL, &texTemp);
Result in GetImageData returning NULL
OR
when a new byte array is created at
BYTE* dest = new BYTE[(*nWidth)*(*nHeight) * 4];
Giving,
Unhandled exception at 0x76414DBD in NDIlib_Send_Video.x86.exe: Microsoft C++ exception: std::bad_alloc at memory location 0x0107F5D8
I'm not sure which memory I should be releasing, probably the byte arrays.., I've tried this using delete[] aByteArray, but this causes a crash.
Here's my function for doing the copy,
BYTE* GetImageData(ID3D11Device* device, ID3D11DeviceContext* context, ID3D11Texture2D* texture, /*OUT*/ int* nWidth, /*OUT*/ int* nHeight) {
if (texture) {
D3D11_TEXTURE2D_DESC description;
texture->GetDesc(&description);
description.BindFlags = 0;
description.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
description.Usage = D3D11_USAGE_STAGING;
ID3D11Texture2D* texTemp = NULL;
HRESULT hr = device->CreateTexture2D(&description, NULL, &texTemp);
if (FAILED(hr))
{
if (hr == E_OUTOFMEMORY) {
printf("GetImageData - CreateTexture2D - OUT OF MEMORY \n");
}
if (texTemp)
{
texTemp->Release();
texTemp = NULL;
}
return NULL;
}
context->CopyResource(texTemp, texture);
D3D11_MAPPED_SUBRESOURCE mapped;
unsigned int subresource = 0;
hr = context->Map(texTemp, 0, D3D11_MAP_READ, 0, &mapped);
if (FAILED(hr))
{
printf("GetImageData - Map - FAILED \n");
texTemp->Release();
texTemp = NULL;
return NULL;
}
*nWidth = description.Width;
*nHeight = description.Height;
const int pitch = mapped.RowPitch;
BYTE* source = (BYTE*)(mapped.pData);
BYTE* dest = new BYTE[(*nWidth)*(*nHeight) * 4];
BYTE* destTemp = dest;
for (int i = 0; i < *nHeight; ++i)
{
memcpy(destTemp, source, *nWidth * 4);
source += pitch;
destTemp += *nWidth * 4;
}
context->Unmap(texTemp, 0);
return dest;
}
else {
printf("GetImageData - texture null - FAILED \n");
return NULL;
}
}
And here's how I'm using GetImageData from my main function
BYTE* p_frame = (BYTE*)GetImageData(g_d3dDevice, g_d3dDeviceContext, g_pDeskTexture, &w, &h);
if (p_frame == NULL) printf("GetImageData - Returned NULL \n");
else {
printf("GetImageData - OK \n");
}
Upvotes: 0
Views: 1255
Reputation: 26
Where do you delete dest*
or in the case after being returned p_frame*
? You are allocating data using new and returning this pointer, if you don't delete this you will eventually run out of memory, especially if you're calling this every frame.
You should also consider some form of memory management and define ownership of what's being allocated, passing back raw pointers is a prime suspect for memory leaks.
Upvotes: 1