Hello, my program uses DeepStream5.0 to process live video on JetsonNX devices. I need to do object detection on the video and save the full image with the detection box. When I saved the image, I found that the color format is NVBUF_COLOR_FORMAT_NV12_709_ER. So I need to convert colorFormat to RGBA first, and then save it as JPG via OpenCV. But a segmentation fault occurred when I converted the color format using NvBufSurfTransform. This segmentation fault may have occurred during the NvBufSurfTransform or for some other reason, I’m not sure. Please help me. Thank you very much.
Here is the code snippet:
NvDsMetaList *l_frame = NULL; NvDsMetaList *l_obj = NULL; //NvDsMetaList *l_usr_meta = NULL; NvDsObjectMeta *obj_meta = NULL; // Get original raw data GstMapInfo in_map_info = GST_MAP_INFO_INIT; if (!gst_buffer_map(buf, &in_map_info, GST_MAP_READ)) { g_print ("Error: Failed to map gst buffer\n"); return; } NvBufSurface *surface = (NvBufSurface *)in_map_info.data; //gst_buffer_unmap (buf, &in_map_info); uint32_t frame_data_size = 0; unsigned char* src_data = NULL; std::vector<cv::Rect> objsRect; static std::map<uint32_t, std::vector<cv::Rect>> lastObjsRect; NvDsBatchMeta *batch_meta = gst_buffer_get_nvds_batch_meta(buf); for (l_frame = batch_meta->frame_meta_list; l_frame != NULL; l_frame = l_frame->next) { NvDsFrameMeta *frame_meta = (NvDsFrameMeta *)(l_frame->data); guint object_num = 0, person_num = 0, train_num = 0; if (frame_data_size < surface->surfaceList[frame_meta->batch_id].dataSize) { if (src_data != NULL) { std::cout << "test debug src_data size changed!" << std::endl; free(src_data); src_data = NULL; } src_data = (unsigned char*)malloc(surface->surfaceList[frame_meta->batch_id].dataSize); if (src_data == NULL) { g_print("Error: failed to malloc src_data \n"); return; } frame_data_size = surface->surfaceList[frame_meta->batch_id].dataSize; } memset(src_data, 0, frame_data_size); printf("frame_data_size = %d \n", frame_data_size); // add object bbox in objsRect ... gint frame_width = (gint)surface->surfaceList[frame_meta->batch_id].width; gint frame_height = (gint)surface->surfaceList[frame_meta->batch_id].height; gint frame_step = surface->surfaceList[frame_meta->batch_id].pitch; gint color_format = surface->surfaceList[frame_meta->batch_id].colorFormat; uint source_id = frame_meta->source_id; uint32_t batch_size = surface->batchSize; uint batch_id = frame_meta->batch_id; printf("\nbatch_id = %d, batch_size = %d \n", batch_id, batch_size); if (color_format != NVBUF_COLOR_FORMAT_NV12 && color_format != NVBUF_COLOR_FORMAT_RGBA) { static int loop = 0; // transform NVBUF_COLOR_FORMAT_NV12_709_ER or NVBUF_COLOR_FORMAT_NV12_709 colorFormat NvBufSurfTransformRect src_rect, dst_rect; NvBufSurfTransformParams nvbufsurface_params; NvBufSurface *dst_surface = NULL; NvBufSurfaceCreateParams nvbufsurface_create_params; cudaError_t cuda_err; cudaStream_t cuda_stream; gint create_result; NvBufSurfTransformConfigParams transform_config_params; NvBufSurfTransform_Error err; cv::Mat bgr_frame, in_mat; src_rect.top = 0; src_rect.left = 0; src_rect.width = (guint) surface->surfaceList[batch_id].width; src_rect.height = (guint) surface->surfaceList[batch_id].height; dst_rect.top = 0; dst_rect.left = 0; dst_rect.width = (guint) surface->surfaceList[batch_id].width; dst_rect.height = (guint) surface->surfaceList[batch_id].height; nvbufsurface_params.src_rect = &src_rect; nvbufsurface_params.dst_rect = &dst_rect; nvbufsurface_params.transform_flag = NVBUFSURF_TRANSFORM_CROP_SRC | NVBUFSURF_TRANSFORM_CROP_DST; nvbufsurface_params.transform_filter = NvBufSurfTransformInter_Default; nvbufsurface_create_params.gpuId = surface->gpuId; nvbufsurface_create_params.width = (guint) surface->surfaceList[batch_id].width; nvbufsurface_create_params.height = (guint) surface->surfaceList[batch_id].height; nvbufsurface_create_params.size = 0; nvbufsurface_create_params.isContiguous = true; nvbufsurface_create_params.colorFormat = NVBUF_COLOR_FORMAT_RGBA; nvbufsurface_create_params.layout = NVBUF_LAYOUT_PITCH; // THE memType PARAM IS SET TO CUDA UNIFIED IN dGPU DEVICES COMMENT IT out // AND USE THE IMMEDIATE NEXT LINE TO SET THE memType PARAM FOR JETSON DEVICES #ifdef PLATFORM_TEGRA nvbufsurface_create_params.memType = NVBUF_MEM_DEFAULT; #else nvbufsurface_create_params.memType = NVBUF_MEM_CUDA_UNIFIED; #endif cuda_err = cudaSetDevice (surface->gpuId); cuda_err = cudaStreamCreate(&cuda_stream); create_result = NvBufSurfaceCreate(&dst_surface, batch_size, &nvbufsurface_create_params); if (create_result) { GST_ERROR_OBJECT (nullptr, "NvBufSurfaceCreate failed.\n"); } transform_config_params.compute_mode = NvBufSurfTransformCompute_Default; transform_config_params.gpu_id = surface->gpuId; transform_config_params.cuda_stream = cuda_stream; err = NvBufSurfTransformSetSessionParams (&transform_config_params); NvBufSurfaceMemSet (dst_surface, batch_id, -1, 0); printf("src_color_format: %d, dst_color_format: %d, gpu_id: %d, datasize: %d, %dx%d, pitch: %d, num_planes: %d, loop: %d \n", surface->surfaceList[batch_id].colorFormat, dst_surface->surfaceList[batch_id].colorFormat, surface->gpuId, surface->surfaceList->dataSize, surface->surfaceList->width, surface->surfaceList->height, surface->surfaceList->pitch, surface->surfaceList->planeParams.num_planes, loop++); err = NvBufSurfTransform (surface, dst_surface, &nvbufsurface_params); if (err != NvBufSurfTransformError_Success) { g_print ("NvBufSurfTransform failed with error %d while converting buffer\n", err); } else { printf("NvBufSurfTransform ok.\n"); } #ifdef PLATFORM_TEGRA NvBufSurfaceMap(dst_surface/*surface*/, batch_id, -1, NVBUF_MAP_READ); NvBufSurfacePlaneParams *pParams = &dst_surface->surfaceList[batch_id].planeParams; unsigned int offset = 0; for (unsigned int num_planes=0; num_planes < pParams->num_planes; num_planes++) { if (num_planes>0) offset += pParams->height[num_planes-1]*(pParams->bytesPerPix[num_planes-1]*pParams->width[num_planes-1]); for (unsigned int h = 0; h < pParams->height[num_planes]; h++) { memcpy((void *)(src_data+offset+h*pParams->bytesPerPix[num_planes]*pParams->width[num_planes]), (void *)((char *)dst_surface->surfaceList[batch_id].mappedAddr.addr[num_planes]+h*pParams->pitch[num_planes]), pParams->bytesPerPix[num_planes]*pParams->width[num_planes]); } } printf("debug0: ----------- \n"); NvBufSurfaceSyncForDevice(dst_surface, batch_id, -1); NvBufSurfaceUnMap(dst_surface, batch_id, -1); #endif color_format = dst_surface->surfaceList[batch_id].colorFormat; if (color_fmt == NVBUF_COLOR_FORMAT_NV12) printf("test_color_format: NVBUF_COLOR_FORMAT_NV12 \n"); else if (color_fmt == NVBUF_COLOR_FORMAT_NV12_ER) printf("test_color_format: NVBUF_COLOR_FORMAT_NV12_ER \n"); else if (color_fmt == NVBUF_COLOR_FORMAT_NV12_709) printf("test_color_format: NVBUF_COLOR_FORMAT_NV12_709 \n"); else if (color_fmt == NVBUF_COLOR_FORMAT_NV12_709_ER) printf("test_color_format: NVBUF_COLOR_FORMAT_NV12_709_ER \n"); else if (color_fmt == NVBUF_COLOR_FORMAT_RGBA) printf("test_color_format: NVBUF_COLOR_FORMAT_RGBA \n"); else printf("test_color_format: other: %d \n", color_fmt); printf("debug1: ----------- \n"); NvBufSurfaceDestroy(dst_surface); cudaStreamDestroy (cuda_stream); printf("debug2: ----------- \n"); } else { #ifdef PLATFORM_TEGRA NvBufSurfaceMap(surface, batch_id, -1, NVBUF_MAP_READ); NvBufSurfacePlaneParams *pParams = &surface->surfaceList[batch_id].planeParams; unsigned int offset = 0; for (unsigned int num_planes=0; num_planes < pParams->num_planes; num_planes++) { if (num_planes>0) offset += pParams->height[num_planes-1]*(pParams->bytesPerPix[num_planes-1]*pParams->width[num_planes-1]); for (unsigned int h = 0; h < pParams->height[num_planes]; h++) { memcpy((void *)(src_data+offset+h*pParams->bytesPerPix[num_planes]*pParams->width[num_planes]), (void *)((char *)surface->surfaceList[batch_id].mappedAddr.addr[num_planes]+h*pParams->pitch[num_planes]), pParams->bytesPerPix[num_planes]*pParams->width[num_planes]); } } NvBufSurfaceSyncForDevice(surface, batch_id, -1); NvBufSurfaceUnMap(surface, batch_id, -1); printf("debug2-2: ----------- \n"); #endif } cv::Mat frame; cv::Mat out_mat = cv::Mat(cv::Size(frame_width, frame_height), CV_8UC3); switch (color_format) { case NVBUF_COLOR_FORMAT_NV12: frame = cv::Mat(frame_height * 3 / 2, frame_width, CV_8UC1, src_data, frame_step); cv::cvtColor(frame, out_mat, CV_YUV2BGR_NV12); break; case NVBUF_COLOR_FORMAT_RGBA: frame = cv::Mat(frame_height, frame_width, CV_8UC4, src_data, frame_step); cv::cvtColor(frame, out_mat, CV_RGBA2BGR); break; default: std::cout << "warning: color_format = " << color_format << std::endl; break; } printf("debug3: ----------- \n"); for (uint i = 0; i < objsRect.size(); ++i) { cv::rectangle(out_mat, objsRect[i], cv::Scalar(0,255,0), 1); } printf("debug4: ----------- \n"); char filePath[FILE_NAME_SIZE] = {0}; snprintf((char*)filePath, FILE_NAME_SIZE, "./srci_%d_%d.jpg", source_id, batch_id); cv::Mat tmp_mat = out_mat.clone(); cv::imwrite(filePath, tmp_mat); printf("debug5: ----------- \n"); } if (src_data != NULL) { free(src_data); src_data = NULL; } gst_buffer_unmap (buf, &in_map_info);
• Hardware Platform:Jetson NX
• DeepStream: 5.0
• JetPack Version: 4.4
Here is the configuration file information:
[application]
enable-perf-measurement=1
perf-measurement-interval-sec=5
#gie-kitti-output-dir=streamscl
[tiled-display]
enable=1
rows=3
columns=2
width=1280
height=720
gpu-id=0
nvbuf-memory-type=0
[source0]
enable=1
## Type: 1=CameraV4L2 2=URI 3=MultiURI
type=3
uri=rtsp://admin:******@xx.xx.xx.xx/h264/ch1/main/av_stream
num-sources=4
camera-id=0
gpu-id=0
cudadec-memtype=0
[sink0]
enable=1
## Type: 1=FakeSink 2=EglSink 3=File 4=RTSPStreaming
type=2
sync=0
source-id=0
gpu-id=0
nvbuf-memory-type=0
[sink1]
enable=1
## Type: 1=FakeSink 2=EglSink 3=File 4=RTSPStreaming
type=4
rtsp-port=8554
udp-port=5400
sync=0
source-id=0
gpu-id=0
nvbuf-memory-type=0
## 1=h264 2=h265
codec=1
[osd]
enable=1
gpu-id=0
border-width=1
text-size=12
text-color=1;1;1;1;
text-bg-color=0.3;0.3;0.3;1
font=Serif
show-clock=0
clock-x-offset=800
clock-y-offset=820
clock-text-size=12
clock-color=1;0;0;0
nvbuf-memory-type=0
[streammux]
gpu-id=0
live-source=0
batch-size=8
batched-push-timeout=40000
width=1920
height=1080
enable-padding=0
nvbuf-memory-type=0
[primary-gie]
enable=1
gpu-id=0
model-engine-file=yolov5s-zj.engine
labelfile-path=labels.txt
batch-size=8
#Required by the app for OSD, not a plugin property
bbox-border-color0=1;0;0;1
bbox-border-color1=0;1;1;1
bbox-border-color2=0;0;1;1
bbox-border-color3=0;1;0;1
interval=0
gie-unique-id=1
nvbuf-memory-type=0
config-file=config_infer_primary_yoloV5.txt
[tracker]
enable=1
gpu-id=0
tracker-width=960
tracker-height=540
ll-lib-file=/opt/nvidia/deepstream/deepstream-5.0/lib/libnvds_mot_klt.so
display-tracking-id=1
[nvds-analytics]
enable=1
config-file=config_nvdsanalytics.txt
[tests]
file-loop=0
The following is the exception information: