I've stepped through the code, through each OpenCV 3.4.0 function, and I just can't understand why data is being lost or destroyed on my faster systems.
When I use CMat::copyTo to send data to a CMat that has already had its frame buffer allocated (I checked, 8MB allocated), and the scope of the receiving CMat is always in range, why should there be a memory problem?
Using clone solves the problem but allocates memory again for the receiving CMat.
CopyTo just memcpy's to the target CMat's data, so it should work. I stepped through the destructors in my copy procedure, and the target CMat receiving the data is not freed.
If I call ShowImg() on the returned data after the copy call, then the memory problem goes away.
Appreciate any advice on this.
My test code to copy a D3D9 surface to a OpenCV CMat:-
void main() { while (input() != _ESC) { if (!m_pInputLeft) { m_pInputLeftRight = new cv::Mat(pSBM->pTexture->getSize().Height, pSBM->pTexture->getSize().Width, CV_8UC4); // I stepped thro and memory gets allocated, some 8 MBS for an FHD sized frame }
// *** Copy video frame (DShow RGBA) that was input to OpenCV BGR to LR Mat
if (CopyTextureToMat(pSBM->pTexture, m_pInputLeftRight), 1)
{
DisplayFrame(m_pInputLeftRight); // Frame data does not get displayed if copy mode is copyTo (clone works!)
}
} }
bool CopyTextureToMat(CD3D9Texture *pD9Tex , cv::Mat *pDest, SBM_P *pParams) { IDirect3DSurface9 *pSurf; if (!pD9Tex || !pDest) return false; HRESULT r = pD9Tex->Texture->GetSurfaceLevel(0, &pSurf); // Get DX9 surface from Viva3D texture if (r != S_OK) return false; r = pSurf->LockRect(&memDesc, NULL, D3DLOCK_READONLY | D3DLOCK_NO_DIRTY_UPDATE); // D3DLOCK_READONLY if (FAILED(r)) { if (r == D3DERR_WASSTILLDRAWING) { bool b = true; // Debug point only } else if (r == D3DERR_INVALIDCALL) { bool b = true; } return false; }
pMatOut = new cv::Mat(iHeight, iWidth, CV_8UC4, memDesc.pBits, memDesc.Pitch); // Create Mat using same memory as DX9 surface
static bool bCopyMode = 0;
if (bCopyMode)
pMatOut->copyTo(*pDest); // On higher speed systems the memory is being destroyed (no exception occurs on use though)
else
{
*pDest = pMatOut->clone(); // This duplicates the data and works on the higher speed systems
}
r = pSurf->UnlockRect();
delete pMatOut;
if (FAILED(r))
return false;
return true;
}