Segmentation Fault in NvBufSurfTransform

• Hardware Platform: GPU
• DeepStream Version: 5.0.0
• TensorRT Version: 7.0.0.11
• NVIDIA GPU Driver Version (valid for GPU only): 460.32.03

I’m facing a weired issue: I installed a probe on a pad to play around with some transformation before feeding a crop into an SGIE. Following this thread I want to access the frames buffer by using a GstMapInfo object. Please check my below complete code:

static GstPadProbeReturn sgie2_sink_pad_buffer_probe(GstPad *, GstPadProbeInfo *info,
                                                     gpointer user_data)
{
  GstBuffer *buf = (GstBuffer *)info->data;
  NvDsBatchMeta *batch_meta = gst_buffer_get_nvds_batch_meta(buf);

  // std::shared_ptr<GstMapInfo> in_map_info(new GstMapInfo(),
  //                                         [buf](GstMapInfo *o) { gst_buffer_unmap(buf, o); });

  GstMapInfo in_map_info;
  //auto guard = sg::make_scope_guard([buf, &in_map_info]() { g_print("Hi scope guard\n");gst_buffer_unmap(buf, &in_map_info); });
  if (!gst_buffer_map(buf, &in_map_info, GST_MAP_READ))
  {
    g_printerr("Failed to map gst buffer\n");
    return GST_PAD_PROBE_OK;
  }
  NvBufSurface *surface = (NvBufSurface *)(in_map_info.data);
  for (NvDsMetaList *l_frame = batch_meta->frame_meta_list; l_frame != NULL;
       l_frame = l_frame->next)
  {
    NvDsFrameMeta *frame_meta = (NvDsFrameMeta *)(l_frame->data);

    for (NvDsMetaList *l_obj = frame_meta->obj_meta_list; l_obj != NULL; l_obj = l_obj->next)
    {
      NvDsObjectMeta *obj_meta = (NvDsObjectMeta *)(l_obj->data);

      if (true)
      {
        NvBufSurface *nvbuf;
        NvBufSurfaceCreateParams create_params;

        create_params.gpuId = 0;
        create_params.width = 112;
        create_params.height = 112;
        create_params.size = 0;
        create_params.colorFormat = surface->surfaceList[frame_meta->batch_id].colorFormat;
        create_params.layout = surface->surfaceList[frame_meta->batch_id].layout;
        create_params.memType = NVBUF_MEM_CUDA_UNIFIED;
        NvBufSurfaceCreate(&nvbuf, 1, &create_params);

        NvBufSurfaceMemSet(nvbuf, 0, 0, 0);

        NvBufSurfTransformConfigParams transform_config_params;
        transform_config_params.compute_mode = NvBufSurfTransformCompute_Default;
        transform_config_params.gpu_id = 0;

        NvBufSurfTransform_Error err = NvBufSurfTransformSetSessionParams(&transform_config_params);
        if (err != NvBufSurfTransformError_Success)
        {
          g_printerr("NvBufSurfTransformSetSessionParams failed with error %d", err);
          return GST_PAD_PROBE_OK;
        }

        NvBufSurfTransformRect src_rect = {
            (guint)obj_meta->rect_params.top, (guint)obj_meta->rect_params.left,
            (guint)obj_meta->rect_params.width, (guint)obj_meta->rect_params.height};
        NvBufSurfTransformRect dst_rect = {0, 0, 112, 112};

        NvBufSurfTransformParams transform_params;
        transform_params.src_rect = &src_rect;
        transform_params.dst_rect = &dst_rect;
        transform_params.transform_flag = NVBUFSURF_TRANSFORM_FILTER |
                                          NVBUFSURF_TRANSFORM_CROP_SRC |
                                          NVBUFSURF_TRANSFORM_CROP_DST;
        transform_params.transform_filter = NvBufSurfTransformInter_Default;

        NvBufSurfaceMemSet(nvbuf, 0, 0, 0);

        err = NvBufSurfTransform(surface, nvbuf, &transform_params);
        if (err != NvBufSurfTransformError_Success)
        {
          g_printerr("NvBufSurfTransform failed with error %d while converting buffer\n", err);
          return GST_PAD_PROBE_OK;
        }
        if (NvBufSurfaceMap(nvbuf, 0, 0, NVBUF_MAP_READ) != 0)
        {
          g_printerr("NvBufSurfaceMap(nvbuf, 0, 0, NVBUF_MAP_READ) != 0\n");
          return GST_PAD_PROBE_OK;
        }
        NvBufSurfaceSyncForCpu(nvbuf, 0, 0);

        cv::Mat mat(nvbuf->surfaceList[0].height, nvbuf->surfaceList[0].width, CV_8UC3,
                    nvbuf->surfaceList[0].mappedAddr.addr[0], nvbuf->surfaceList[0].pitch);
        char *filename = "image.jpg";
        cv::imwrite(filename, mat);
        g_print("wrote image file %s\n", filename);
      }
    }
  }
  return GST_PAD_PROBE_OK;
}

Gstreamer suggests to do a gst_buffer_unmap() after finishing to clean up resources. However, as you see in the code there are multiple spots in the code where things could go wrong and resources should be release before returning from the function so I tried to wrap the in_map_info into a smart pointer and supply a custom deleter function. You can see that commented out there. This approach needs two minor changes where the actual object is being used. This gave me a segmentation fault inNvBufSurfTransformwhich I don’t really understand. Following I tried using a scope guard implementation to avoid the pointers. Same issue appeared, again the seg fault is interrupting my app. However, when not using any of those means it works perfectly. From my understanding both methods should work or am I missing something very basic?

There is no update from you for a period, assuming this is not an issue any more.
Hence we are closing this topic. If need further support, please open a new one.
Thanks

Where did you insert these code? Can you post the whole code of your application?