Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

CopyTo loding data

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;

}

click to hide/show revision 2
None

CopyTo loding data

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

}