How to properly Release BitmapBuffer from SoftwareBitmap (UWP)?

2

I struggle to properly release the BitmapBuffer locked with SoftwareBitmap.LockBuffer() method in C++/CX code on UWP.

The base code looks as below (it's a OpenCV bridge sample from Microsoft available here.

bool OpenCVHelper::GetPointerToPixelData(SoftwareBitmap^ bitmap, unsigned char** pPixelData, unsigned int* capacity)
{
   BitmapBuffer^ bmpBuffer = bitmap->LockBuffer(BitmapBufferAccessMode::ReadWrite);
   IMemoryBufferReference^ reference = bmpBuffer->CreateReference();

   ComPtr<IMemoryBufferByteAccess> pBufferByteAccess;
   if ((reinterpret_cast<IInspectable*>(reference)->QueryInterface(IID_PPV_ARGS(&pBufferByteAccess))) != S_OK)
   {
    return false;
   }

   if (pBufferByteAccess->GetBuffer(pPixelData, capacity) != S_OK)
   {
    return false;
   }
   return true;
}

This buffer (pPixelData) is then used to initialize cv:Mat object (shallow copy). And is never released.

Consecutive call to LockBuffer() on the same SoftwareBitmap object raises exception:

Platform::AccessDeniedException ^ at memory location 0x00000002CEEFDCC0. HRESULT:0x80070005 Access is denied. WinRT information: Bitmap shared lock taken

How to properly release this buffer? Especially in C++/CX?

I tried to keep the reference to release it when no more needed. In C++/CX Dispose() or Close() methods are inaccessible and compiler advises to call destructor instead:

BitmapBuffer^ bmpBuffer = nullptr;
// ... get the buffer, use it
//((IDisposable^)bmpBuffer)->Dispose();
bmpBuffer->~BitmapBuffer();

But it doesn't work (does nothing). Destructor is being invoked but another call to LockBuffer() raises the same error as before.

windows
uwp
windows-10-universal
c++-cx
windows-10-iot-core
asked on Stack Overflow Mar 13, 2018 by Pawel

1 Answer

1

How to properly Release BitmapBuffer from SoftwareBitmap (UWP)?

After BitmapBuffer and IMemoryBufferReference completing their work, these objects could be closed by invoking delete expression. More details please check Destructors. For example:

SoftwareBitmap^ bitmap = ref new SoftwareBitmap(
    BitmapPixelFormat::Bgra8,
    100,
    200,
    BitmapAlphaMode::Premultiplied);
BitmapBuffer^ bmpBuffer = bitmap->LockBuffer(BitmapBufferAccessMode::ReadWrite); 
IMemoryBufferReference^ reference = bmpBuffer->CreateReference();
delete reference;
delete bmpBuffer; 
BitmapBuffer^ bmpBuffer2 = bitmap->LockBuffer(BitmapBufferAccessMode::ReadWrite);

As above code snippet showed, after delete the BitmapBuffer object, you could lock the buffer again successfully.

answered on Stack Overflow Mar 21, 2018 by Sunteen Wu

User contributions licensed under CC BY-SA 3.0