Hi
I use DS 4.0 on jetson nano dev kit
i made a plugin for draw menu based on dsexample plugin
some changing ,
original(dsexample) - transform_ip ()
new plugin(menudraw) - prepareoutputbuffer → transform()
- my plugin loads some image and convert to Mat
- store them in a Mat array (cv::Mat) (init)
- menudraw_start
- run prepare_output_buffer when source(two camera sources, batchsize = 2, after infer) is input
- make a new buffer(batchsize = 1) for outbuf
- Set the drawParam using property of the menudraw(page-num, cusor-pos, command)
- draw the buffer using DrawParam
- In camera setting menu, the input source is composited on the screen (plan to make)
my plugin looks good
but it has 3mb memory leak every sec
If bypass, memory leakage does not occur.
i think, there seems to be a problem during buffer making and using Mat.
i upload my all code of my plugin source
please help me…
Maybe there is a problem with these functions
gst_menudraw_prepare_output_buffer
gst_menudraw_prepare_output_buffer(GstBaseTransform * btrans, GstBuffer * inbuf, GstBuffer ** outbuf)
{
GstMenuDraw *menudraw = GST_MENUDRAW (btrans);
GstFlowReturn flow_ret = GST_FLOW_ERROR;
GstMapInfo out_map_info;
DrawParam DrawParam;
NvBufSurface *outsurface = NULL;
NvBufSurfaceCreateParams create_params;
NvDsBatchMeta *batch_meta = NULL;
NvDsFrameMeta *frame_meta = NULL;
NvDsMeta *meta = NULL;
g_print ("Prepare start\n");
//*outbuf = inbuf;
//return GST_FLOW_OK;
if (menudraw->inter_buf)
NvBufSurfaceDestroy (menudraw->inter_buf);
menudraw->inter_buf = NULL;
/* An intermediate buffer for NV12/RGBA to BGR conversion will be
* required. Can be skipped if custom algorithm can work directly on NV12/RGBA. */
create_params.gpuId = menudraw->gpu_id;
create_params.width = menudraw->processing_width;
create_params.height = menudraw->processing_height;
create_params.size = 0;
create_params.colorFormat = NVBUF_COLOR_FORMAT_RGBA;
create_params.layout = NVBUF_LAYOUT_PITCH;
#ifdef __aarch64__
create_params.memType = NVBUF_MEM_DEFAULT;
g_print("set surface memtype nvbuf_mem_dafault\n");
#else
create_params.memType = NVBUF_MEM_CUDA_UNIFIED;
#endif
//Make GST Buffer
if (NvBufSurfaceCreate (&(menudraw->inter_buf), 1,
&create_params) != 0) {
GST_ERROR ("Error: Could not allocate internal buffer for menudraw");
goto error;
}
menudraw->inter_buf->numFilled = 1;
/* An intermediate buffer for NV12/RGBA to BGR conversion will be
* required. Can be skipped if custom algorithm can work directly on NV12/RGBA. */
/*create_params.gpuId = menudraw->gpu_id;
create_params.width = menudraw->processing_width;
create_params.height = menudraw->processing_height;
create_params.size = 0;
create_params.colorFormat = NVBUF_COLOR_FORMAT_RGBA;
create_params.layout = NVBUF_LAYOUT_PITCH;
#ifdef __aarch64__
create_params.memType = NVBUF_MEM_DEFAULT;
g_print("set surface memtype nvbuf_mem_dafault\n");
#else
create_params.memType = NVBUF_MEM_CUDA_UNIFIED;
#endif
//Make GST Buffer
if (NvBufSurfaceCreate (&newoutsurface, 1,
&create_params) != 0) {
GST_ERROR ("Error: Could not allocate internal buffer for menudraw");
goto error;
}
newoutsurface->numFilled = 1;*/
*outbuf = NULL;
*outbuf = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_ZERO_PREFIXED, menudraw->inter_buf, sizeof(NvBufSurface), 0, sizeof(NvBufSurface), NULL, NULL);
batch_meta = nvds_create_batch_meta(1);
meta = gst_buffer_add_nvds_meta (*outbuf , batch_meta, NULL, copy_user_meta, release_user_meta);
meta->meta_type = NVDS_BATCH_GST_META;
batch_meta->base_meta.batch_meta = batch_meta;
batch_meta->base_meta.copy_func = copy_user_meta;
batch_meta->base_meta.release_func = release_user_meta;
batch_meta->max_frames_in_batch = 1;
frame_meta = nvds_acquire_frame_meta_from_pool(batch_meta);
//g_print("m4\n");
nvds_add_frame_meta_to_batch(batch_meta, frame_meta);
//g_print("m5\n");
// Some important parameters to fill
frame_meta->pad_index = 0;
frame_meta->source_id = 0;
frame_meta->buf_pts = 0;
frame_meta->ntp_timestamp = 0;
frame_meta->frame_num = 0;
frame_meta->batch_id = 0;
frame_meta->source_frame_width = 1024;
frame_meta->source_frame_height = 600;
frame_meta->num_surfaces_per_frame = 1 ;
CHECK_CUDA_STATUS (cudaSetDevice (menudraw->gpu_id),
"Unable to set cuda device");
memset (&out_map_info, 0, sizeof (out_map_info));
if (!gst_buffer_map (*outbuf, &out_map_info, GST_MAP_READWRITE)) {
g_print ("Error: Failed to out map gst buffer\n");
goto error;
}
outsurface = (NvBufSurface *) out_map_info.data;
GST_DEBUG_OBJECT (menudraw,"Processing Frame Surface %p\n",outsurface);
if (CHECK_NVDS_MEMORY_AND_GPUID (menudraw, outsurface))
{
g_print ("Error: Check NVDS Memory And Gpu id\n");
goto error;
}
//NvBufSurfaceMemSet(outsurface, 0, 0, 0);
if (NvBufSurfaceMap (outsurface, 0, 0, NVBUF_MAP_READ_WRITE) != 0){
g_print("Draw surface map Error\n");
return GST_FLOW_ERROR;
}
NvBufSurfaceSyncForCpu (outsurface, 0,0);
DrawParam = Process_Draw_Update_Func[menudraw->page_num](menudraw, inbuf);
Process_Draw_Menu(outsurface, &DrawParam );
NvBufSurfaceSyncForDevice (outsurface, 0,0);
if (NvBufSurfaceUnMap (outsurface, 0,0)){
g_print("Draw surface unmap Error\n");
goto error;
}
g_print ("Prepare OK\n");
flow_ret = GST_FLOW_OK;
error:
gst_buffer_unmap (*outbuf, &out_map_info);
return flow_ret;
}
Process_Draw_Update_Func,
Function pointer
Process_Draw_Menu
Process_Draw_Menu(NvBufSurface *surface, DrawParam *drawparam)
{
cv::Mat screen;
cv::Mat roi;
cv::Mat mask;
GstFlowReturn flow_ret = GST_FLOW_ERROR;
//g_print("Draw Start image count = %d\n",drawparam->image_num);
//Todo Draw Process;
screen =
cv::Mat (surface->surfaceList[0].planeParams.height[0],surface->surfaceList[0].planeParams.width[0],
CV_8UC4, surface->surfaceList[0].mappedAddr.addr[0],
surface->surfaceList[0].planeParams.pitch[0]);
g_print("mat make ok\n");
screen.setTo(cv::Scalar(90,90,90,255));
g_print("mat set background ok\n");
std::vector<cv::Mat*>::iterator itr_mat;
std::vector<cv::Rect>::iterator itr_Rect;
for(int i = 0 ; i< drawparam->image_num; i++)
{
itr_mat = drawparam->imageparams.vec_image.begin() + i;
itr_Rect = drawparam->imageparams.vec_rect.begin() + i;
//g_print("mat size %u, %u\n ",itr_mat->cols, itr_mat->rows);
//g_print("roi rect %u, %u, %u, %u\n ",itr_Rect->x, itr_Rect->y, itr_Rect->width, itr_Rect->height);
roi = screen(*itr_Rect);
cv::cvtColor(**itr_mat,mask,cv::COLOR_BGRA2GRAY);
cv::threshold(mask, mask, 1, 255, cv::THRESH_BINARY );
//cv::cvtColor (*itr_mat, roi, cv::COLOR_RGBA2BGRA);
(*itr_mat)->copyTo(roi,mask);
}
std::vector<std::string>::iterator itr_text;
std::vector<cv::Point>::iterator itr_point;
std::vector<cv::Scalar>::iterator itr_color;
//g_print("Draw Start text count = %d\n",drawparam->text_num);
for(int i = 0 ; i< drawparam->text_num; i++)
{
itr_text = drawparam->textparams.vec_text.begin() + i;
itr_point = drawparam->textparams.vec_point.begin() + i;
itr_color = drawparam->textparams.vec_color.begin() + i;
//g_print("string %s\n",(*itr_text).c_str());
cv::putText(screen, (*itr_text).c_str(), *itr_point, cv::FONT_ITALIC , 1, *itr_color, 2);
}
flow_ret = GST_FLOW_OK;
g_print("Draw Complete\n");
error:
drawparam->imageparams.vec_image.clear();
drawparam->imageparams.vec_rect.clear();
drawparam->textparams.vec_text.clear();
drawparam->textparams.vec_point.clear();
drawparam->textparams.vec_color.clear();
return flow_ret;
}