Hi all,
I am experiencing a memory leak when trying to recycle a DMA Buf used for Pitch-linear to Block-linear transformation and vice-versa. I had another implementation without recycling and it works perfectly with no leakages.
To illustrate better, here is the code without recycling:
typedef struct _EglImageHandler {
EGLImageKHR egl_image;
PFNGLEGLIMAGETARGETTEXTURE2DOESPROC egl_target_proc;
int dmabl;
} EglImageHandler;
bool preparation(uint8_t * buffer, EglImageHandler * handler) {
int dmapl, dmatarget;
ExtractFdFromNvBuffer((void *)buffer, (int *)&dmapl);
/* Some checks to avoid allocating dmabl if unneeded */
// Suppose output_create_params is loaded Ok
NvBufferCreateEx(&handler->dmabl, &output_create_params);
/*
Some detection logic to see if the buffer is block linear
the block linear buffer will be loaded in dmatarget (if it was transformed, dmatarget = handler->dmabl,
dmatarget = dmapl otherwise
*/
handler->egl_image = NvEGLImageFromFd(NULL, dmatarget);
handler->egl_target_proc =
(PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)eglGetProcAddress(
"glEGLImageTargetTexture2DOES");
handler->egl_target_proc(GL_TEXTURE_2D,
(GLeglImageOES)handler->egl_image);
/* The functions are checked in case of failure and return false in this case. I kept this simple */
return true;
}
bool conclusion(EglImageHandler * handler) {
NvDestroyEGLImage(NULL, handler->egl_image);
/* Logic to ransform back if the buffer was transformed to block-linear before */
NvBufferDestroy(handler->dmabl);
handler->dmabl = 0;
}
This was working. Now, my recycling version:
typedef struct _EglImageHandler {
EGLImageKHR egl_image;
PFNGLEGLIMAGETARGETTEXTURE2DOESPROC egl_target_proc;
int dmabl;
} EglImageHandler;
bool preparation(uint8_t * buffer, EglImageHandler * handler) {
int dmapl, dmatarget;
ExtractFdFromNvBuffer((void *)buffer, (int *)&dmapl);
/* Some checks to avoid allocating dmabl if unneeded */
if (handler->dmabl == 0) {
// Suppose output_create_params is loaded Ok
NvBufferCreateEx(&handler->dmabl, &output_create_params);
}
/*
Some detection logic to see if the buffer is block linear
the block linear buffer will be loaded in dmatarget (if it was transformed, dmatarget = handler->dmabl,
dmatarget = dmapl otherwise
*/
handler->egl_image = NvEGLImageFromFd(NULL, dmatarget);
handler->egl_target_proc =
(PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)eglGetProcAddress(
"glEGLImageTargetTexture2DOES");
handler->egl_target_proc(GL_TEXTURE_2D,
(GLeglImageOES)handler->egl_image);
/* The functions are checked in case of failure and return false in this case. I kept this simple */
return true;
}
bool conclusion(EglImageHandler * handler) {
NvDestroyEGLImage(NULL, handler->egl_image);
/* Logic to ransform back if the buffer was transformed to block-linear before */
}
// the handler->dmabl is deallocated at the end of the program
In this second code, I can see that there is an increasing in the memory consumption (when it is running) without a reason. I made sure of being allocating the buffer just once and deallocating it at the end of the execution.
Apparently, not executing NvBufferDestroy(handler->dmabl)
is making a difference when having a leakage or not, even when I am not allocating dmabl
constantly. Perhaps, the thing is in how EGLImageKHR
works and what NvDestroyEGLImage
and NvEGLImageFromFd
does actually. It seems I am forced to deallocate the dma buffer that I used, but I want to avoid allocating/deallocating it many times, since these functions go into GStreamer.
Any explanation for this behaviour?
Thanks in advance for your kind help