Segmentation fault (core dumped) when convert color with openCV on jetson nano

• Hardware Platform (Jetson / GPU) Jetson
• DeepStream Version 5.0.1
• JetPack Version (valid for Jetson only) 4 .4
• TensorRT Version 7.1.3.0
• CUDA 10.2
Hi all, i am trying to change video frame with:

pad_buffer_probe

However, i am facing log “Segmentation fault (core dumped)” when convert color from bgr to grba. the bellow is my function.

static GstPadProbeReturn
prep_pad_buffer_probe (GstPad * pad, GstPadProbeInfo * info, gpointer u_data)
{
  GstBuffer *buf = (GstBuffer *) info->data;
  GstMapInfo in_map_info;
  memset (&in_map_info, 0, sizeof (in_map_info));

  if (gst_buffer_map (buf, &in_map_info, GST_MAP_READWRITE))
  { 
    
    NvBufSurface *surface = (NvBufSurface *) in_map_info.data;
    NvDsBatchMeta *batch_meta = gst_buffer_get_nvds_batch_meta (GST_BUFFER (info->data));

    NvDsMetaList *l_frame = NULL;
    NvDsFrameMeta *frame_meta = NULL;
    NvDsMetaList * l_obj = NULL;
    NvDsObjectMeta *obj_meta = NULL;
    int left, top, width, height;

    for (l_frame = batch_meta->frame_meta_list; l_frame != NULL;
        l_frame = l_frame->next)
    {
      frame_meta = (NvDsFrameMeta *)(l_frame->data);
      NvBufSurface *surface_idx;
      surface_idx = surface;
      surface_idx->surfaceList = &(surface->surfaceList[frame_meta->batch_id]);
      surface_idx->numFilled = surface->batchSize = 1;

      NvBufSurfTransformRect src_rect, dst_rect;
      int batch_size = surface->batchSize;
      src_rect.top   = 0;
      src_rect.left  = 0;
      src_rect.width = (guint) surface->surfaceList[frame_meta->batch_id].width;
      src_rect.height= (guint) surface->surfaceList[frame_meta->batch_id].height;

      dst_rect.top   = 0;
      dst_rect.left  = 0;
      dst_rect.width = (guint) surface->surfaceList[frame_meta->batch_id].width;
      dst_rect.height= (guint) surface->surfaceList[frame_meta->batch_id].height;

      NvBufSurfTransformParams nvbufsurface_params;
      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;

      NvBufSurfaceCreateParams nvbufsurface_create_params;
      nvbufsurface_create_params.gpuId  = surface->gpuId;
      nvbufsurface_create_params.width  = (guint) surface->surfaceList[frame_meta->batch_id].width;
      nvbufsurface_create_params.height = (guint) surface->surfaceList[frame_meta->batch_id].height;
      nvbufsurface_create_params.size   = 0;
      nvbufsurface_create_params.colorFormat = NVBUF_COLOR_FORMAT_RGBA;
      nvbufsurface_create_params.layout = NVBUF_LAYOUT_PITCH;

      #ifdef PLATFORM_TEGRA
        nvbufsurface_create_params.memType = NVBUF_MEM_DEFAULT;
      #else
        nvbufsurface_create_params.memType = NVBUF_MEM_CUDA_UNIFIED;
      #endif
    
      if (NvBufSurfaceCreate(&surface, batch_size, &nvbufsurface_create_params) != 0){
        g_print ("NvBufSurfaceCreate failed\n");
        return GST_PAD_PROBE_DROP;
      }
    
      NvBufSurfaceMemSet(surface, 0, 0, 0);

      if (NvBufSurfTransform (surface_idx, surface, &nvbufsurface_params) != NvBufSurfTransformError_Success) {
        g_print ("NvBufSurfTransform failed with error while converting buffer\n");
        return GST_PAD_PROBE_DROP;
      }

      
      NvBufSurfaceMap(surface, 0, 0, NVBUF_MAP_READ);
      NvBufSurfaceSyncForCpu(surface, 0, 0);

    
      cv::Mat in_mat = cv::Mat((guint) surface->surfaceList[frame_meta->batch_id].height, 
                                (guint) 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);


      cv::Mat bgr_frame;
      
      cv::cvtColor(in_mat, bgr_frame, (int)cv::COLOR_RGBA2BGR);

      cv::rectangle(bgr_frame, cv::Point(100, 100), cv::Point(200, 200), cv::Scalar(255,0,255), 2);
   
   
      cv::cvtColor(bgr_frame, in_mat, (int)cv::COLOR_BGR2RGBA);
      
      /* We need to transform back to original buffer */
      // https://forums.developer.nvidia.com/t/dsexample/81896/7
      if (NvBufSurfTransform (surface, surface_idx, &nvbufsurface_params) != NvBufSurfTransformError_Success){
        g_print ("NvBufSurfTransform failed with error while converting buffer\n");
        return GST_PAD_PROBE_DROP;
      }

      NvBufSurfaceSyncForDevice(surface, frame_meta->batch_id, 0);
      NvBufSurfaceUnMap(surface, frame_meta->batch_id , 0);
      NvBufSurfaceDestroy(surface);

    }
    
  }

  gst_buffer_unmap (buf, &in_map_info);


  return GST_PAD_PROBE_OK;
}

it raise the error at this line " cv::cvtColor(bgr_frame, in_mat, (int)cv::COLOR_BGR2RGBA); "
can you help me to solve my problem? thanks

Hi,
You should call

NvBufSurfaceSyncForDevice(surface, frame_meta->batch_id, 0);

before calling

      if (NvBufSurfTransform (surface, surface_idx, &nvbufsurface_params) != NvBufSurfTransformError_Success){
        g_print ("NvBufSurfTransform failed with error while converting buffer\n");
        return GST_PAD_PROBE_DROP;
      }

Please give this a try.

Hi,
It still raise the same error. It crashed at

cv::cvtColor(in_mat, bgr_frame, (int)cv::COLOR_RGBA2BGR);

Before calling

NvBufSurfaceSyncForDevice(surface, frame_meta->batch_id, 0);

Hi,
There is a verified patch:

It is to save frames to JPEGs. Could you try it? Would like to see if this patch works.

Hi.
It not seems what i want. I want to draw a circle, rectangle or anything on video frame.

Hi,
Suggest you run it as a reference since it is verified.

This setting looks wrong in the code:

NvBufSurfaceMap(surface, 0, 0, NVBUF_MAP_READ);

It should be readwrite access.

yeppp. The problem is that.
thanks so much.