Please provide complete information as applicable to your setup.
• Hardware Platform (Jetson / GPU) GPU
• DeepStream Version 7.1
• JetPack Version (valid for Jetson only)
• TensorRT Version 10.6
• NVIDIA GPU Driver Version (valid for GPU only) 560.30.35
• Issue Type( questions, new requirements, bugs) Questions
Hi!
I am having trouble with cuda memoery to raw frame data.
My encoder does not need to be executed for every bounding box at every moment. Instead, it operates intermittently when certain conditions are met, and its execution takes a considerable amount of time. Therefore, I want it to function asynchronously.
To achieve this, I plan to place a separate nvvideoconvert
element after the nvinfer
in the DeepStream pipeline. Using a frame callback function, I will extract the bounding boxes and raw frame data pointers, store them in a queue, and then process them in a separate thread after popping them from the queue.
Provider
static GstPadProbeReturn frame_probe(GstPad *pad, GstPadProbeInfo *info, gpointer user_data) {
GstBuffer *buf = (GstBuffer *)info->data;
NvDsBatchMeta *batch_meta = gst_buffer_get_nvds_batch_meta(buf);
NvDsMetaList *l_frame = NULL;
NvDsMetaList *l_obj = NULL;
NvDsMetaList *l_user = NULL;
GstMapInfo in_map_info;
if (!gst_buffer_map(buf, &in_map_info, GST_MAP_READ)) { // for gpu memoery
return GST_PAD_PROBE_OK;
}
NvBufSurface *surface = (NvBufSurface *)in_map_info.data;
NvBufSurfaceMap(surface, -1, -1, NVBUF_MAP_READ);
cv::cuda::GpuMat* copiedMat = new cv::cuda::GpuMat();
for (l_frame = batch_meta->frame_meta_list; l_frame != NULL; l_frame = l_frame->next)
{
NvDsFrameMeta *frame_meta = (NvDsFrameMeta *)(l_frame->data);
NvBufSurfaceParams *params = &surface->surfaceList[frame_meta->batch_id];
if (frame_meta->source_id > 0)
continue;
cv::cuda::GpuMat nv12_mat = cv::cuda::GpuMat(
surface->surfaceList[frame_meta->batch_id].height,
surface->surfaceList[frame_meta->batch_id].width, CV_8UC4,
surface->surfaceList[frame_meta->batch_id].mappedAddr.addr[0],
surface->surfaceList[frame_meta->batch_id].pitch);
nv12_mat.copyTo(*copiedMat);
cudaDeviceSynchronize();
g_async_queue_push(queue, copiedMat);
}
NvBufSurfaceUnMap(surface, 0, 0);
gst_buffer_unmap(buf, &in_map_info);
return GST_PAD_PROBE_OK;
}
Consumer
void consumer(GAsyncQueue *queue) {
g_print("Consumer running");
int count = 0;
while (true)
{
cv::cuda::GpuMat* matToProcess =
(cv::cuda::GpuMat*)g_async_queue_timeout_pop(queue, 100 * 1000);
if (matToProcess == nullptr || matToProcess->empty()) {
std::cerr << "Error: Retrieved GpuMat is empty or null." << std::endl;
}else{
cv::Mat aa;
matToProcess->download(aa);
if (aa.empty()) {
std::cerr << "Error: Downloaded Mat is empty." << std::endl;
} else {
std::string filename = "/workspace/tmpjpg/src0.jpg";
cv::imwrite(filename, aa);
}
}
g_usleep(100);
}
}
I was able to pop/push and convert cuda::Mat and store images.
But images were incomplete.
The images were not fully loaded.
It seems like cuda buffer is overwritten even if after deep-copy cuda::Mat.
Is there any good solution…?
I am in desperate need of your assistance. I would greatly appreciate it if you could kindly help me.