Hi Deepstream Team
I understand that the code for Gstnvmultistreamtiler plugin has not yet been provided.
So. I made new custom tiler plugin using OpenCV but this is so slow and heavy
Can you give us a hint about the tile method you used [ex. resize, composite]?
below is code of customtiler process
[4batch surface → 1batch surface]
static GstFlowReturn
process_tiler(GstCustomTiler *customtiler, NvBufSurface *insurface, NvDsBatchMeta *inbatch, NvBufSurface *outsurface, NvDsFrameMeta *outframemeta){
//g_print("process tile\n");
cv::Mat outMat;
outMat = cv::Mat (outsurface->surfaceList[0].planeParams.height[0],outsurface->surfaceList[0].planeParams.width[0],
CV_8UC4, outsurface->surfaceList[0].mappedAddr.addr[0],
outsurface->surfaceList[0].planeParams.pitch[0]);
// g_print("output mat w = %d h = %d p = %d\n", outsurface->surfaceList[0].planeParams.width[0],
// outsurface->surfaceList[0].planeParams.height[0],
// outsurface->surfaceList[0].planeParams.pitch[0]);
if(customtiler->auto_scale){
//int col = insurface->batchSize / 2;
//int row = insurface->batchSize / 2;
int col = 2;
int row = 2;
int tilewidth = customtiler->processing_width / col;
int tileheight = customtiler->processing_height / row;
//g_print("input batch = %d col = %d row = %d tw = %d th = %d\n",insurface->batchSize, col, row, tilewidth, tileheight);
int batch = 0;
cv::Rect dest[4];
cv::Mat inmat[4];
#if 0
dest[0] = cv::Rect(0, 0, 1014, 720);
dest[1] = cv::Rect(1014, 0, 256, 240);
dest[2] = cv::Rect(1014, 240, 256, 240);
dest[3] = cv::Rect(1014, 480, 256, 240);
#else
dest[0] = cv::Rect(0, 0, 640, 360);
dest[1] = cv::Rect(640, 0, 640, 360);
dest[2] = cv::Rect(0, 360, 640, 360);
dest[3] = cv::Rect(640, 360, 640, 360);
#endif
ResizeMatGroup *group[4] = {0,};
for(int r = 0 ; r < row; ++r){
for(int c = 0 ; c < col; ++c){
NvDsFrameMeta *frame_meta = nvds_get_nth_frame_meta(inbatch->frame_meta_list, batch);
group[batch] = g_new(ResizeMatGroup, 1);
//g_print("input mat batch%d w = %d h = %d p %d size %u addr %p\n",batch, insurface->surfaceList[batch].planeParams.width[0],
// insurface->surfaceList[batch].planeParams.height[0],
// insurface->surfaceList[batch].planeParams.pitch[0],
// insurface->surfaceList[batch].dataSize,
// insurface->surfaceList[batch].mappedAddr.addr[0]);
if(insurface->surfaceList[batch].mappedAddr.addr[0] == nullptr){
g_print("customtiler - detect nullpointer in tile process, ignore this frame batch%d\n", batch);
++batch;
continue;
}
inmat[batch] = cv::Mat (insurface->surfaceList[batch].planeParams.height[0],insurface->surfaceList[batch].planeParams.width[0],
CV_8UC4, insurface->surfaceList[batch].mappedAddr.addr[0],
insurface->surfaceList[batch].planeParams.pitch[0]);
group[batch]->isEmpty = FALSE;
group[batch]->src = &inmat[batch];
group[batch]->dst = &outMat;
group[batch]->rect = dest[frame_meta->source_id];
char title[255];
sprintf(title, "resize thread %d", batch);
customtiler->processMatThread[batch] = g_thread_new(title, process_resize_mat, group[batch]);
//cv::Size s = inmat[batch].size();
//g_print("mat width = %d height = %d\n", s.width, s.height);
//g_print("resize\n");
//g_print("batch%d pindex = %d sourceid = %d\n", batch, frame_meta->pad_index, frame_meta->source_id);
process_bbox(frame_meta, insurface->surfaceList[batch].planeParams.width[0], insurface->surfaceList[batch].planeParams.height[0],
outframemeta, dest[frame_meta->source_id]);
++batch;
}
}
for(int i = 0 ; i < 4 ; ++i){
if(!group[i]->isEmpty){
g_thread_join(customtiler->processMatThread[i]);
//g_print("thrd%d=O ", i);
}
else
{
//g_print("thrd%d=X ", i);
}
g_free(group[i]);
}
//g_print("\n");
}
else{
}
return GST_FLOW_OK;
}
static gpointer process_resize_mat(gpointer ptr){
ResizeMatGroup *group = (_ResizeMatGroup*)ptr;
cv::Mat resizedmat;
cv::resize(*(group->src), resizedmat, cv::Size(group->rect.width, group->rect.height));
resizedmat.copyTo((*(group->dst))(group->rect));
return NULL;
}