Segmentation fault when using nvds_obj_enc_process

Please provide complete information as applicable to your setup.

• Hardware Platform: RTX 4060 Laptop
• DeepStream Version 6.4
WSL2. Docker nvcr.io/nvidia/deepstream:6.4-gc-triton-devel
• NVIDIA GPU Driver Version: CUDA 12.2
• Issue Type: questions

I tried to use deepstream-test5-app to achieve runtime sensor ADD/REMOVE capability and send raw image and relative object information through kafka. So I started by simply using nvds_obj_enc_process in the bbox_generated_probe_after_analytics function to attach the image to usrMetaData, and then modify the nvmsgconv deepstream_schema/dsmeta_payload.cpp to make json data contained in the image of the base64 encoding.
Then I had a Segmentation fault.
So I reviewed some posts for help and tried to copy some functions from the deepstream-transfer-learning-app into deepstream-test5-app, but I still encountered the same error. Which is reported immediately when the program runs into the nvds_obj_enc_process function.


deepstream-test5-edit.zip (385.4 KB)

To run the app I use

./deepstream-test5-app -c ./configs/test5_config_file_nvmultiurisrcbin_src_list_attr_all.txt

after make.

I also try this Deeepstream-test5 error when save image but error happened, too.
Due to my poor programming skills, I can’t solve this problem on my own, please help me.

I also found the error will happened even if I run deepstream-test4-app without modified in original docker (nvcr.io/nvidia/deepstream:6.4-gc-triton-devel). I have no idea to fix it.

@Fiona.Chen @fanzh
Could you do me a favor? Any help appreciated.

We’ve added the jpeg image encoding to base64 and send to Kafka server sample in deepstream-test4 sample. Please read /opt/nvidia/deepstream/deepstream-6.4/sources/apps/sample_apps/deepstream-test4/REDAME

Thank you for helping me. However I met

Job 1, ‘./deepstream-test4-app dstest4_…’ terminated by signal SIGSEGV (Address boundary error)

before nvds_obj_enc_process every time everywhere. Please help me check whether its a problem cause by docker problem nvcr.io/nvidia/deepstream:6.4-gc-triton-devel.

Sometimes it will send first image successfully, then get error.

Did you run that the following way?
1.Modify the dstest4_config.yml file

msgconv:
  #If you want to send images, please set the "payload-type: 1" and "msg2p-newapi: 1"
  payload-type: 1
  msg2p-newapi: 1
  frame-interval: 30

msgbroker:
  proto-lib: /opt/nvidia/deepstream/deepstream/lib/libnvds_kafka_proto.so
  conn-str: <your_setup>
  topic: <your_topic>
  sync: 0
  1. run the command below:
./deepstream-test4-app dstest4_config.yml --no-display


Yes, I run that correct way but the error happened again. I wonder if it because I run the docker in WSL2, I’m trying to figure out.

DeepStream 6.4 does not support WSL. The " nvds_obj_enc_process()" interface needs hardware encoder support from the OS. You may look for some open source software encoder and replace the hardware encoding by yourself if you have to run DeepStream on WSL.

1 Like

@Fiona.Chen Thanks for help! Does that mean I can only run deepstream properly on a native linux server or pc? Is there a way to develop a deepstream app in a virtual machine on windows?

Besides can I use opencv in bbox_generated_probe_after_analytics() to extract image without changing the pipeline?

How can I extract images from surface objects if there is more than 1 stream src - #16 by st123010

I learn it from upper post but I met segmentation fault when converting images.

static void
bbox_generated_probe_after_analytics (AppCtx * appCtx, GstBuffer * buf,
    NvDsBatchMeta * batch_meta, guint index)
{
......
    GstMapInfo inmap = GST_MAP_INFO_INIT;
    if (!gst_buffer_map (buf, &inmap, GST_MAP_READ)) {
      GST_ERROR ("input buffer mapinfo failed");
      return;
    }
    NvBufSurface *ip_surf = (NvBufSurface *) inmap.data;

    const gchar *calc_enc_str = g_getenv ("CALCULATE_ENCODE_TIME");
    gboolean calc_enc = !g_strcmp0 (calc_enc_str, "yes");
    int countTest = 0;

    NvBufSurface *uni_surf = nullptr;
    if (ip_surf->memType == NVBUF_MEM_CUDA_DEVICE) {
      NvBufSurfaceCreateParams create_params;
      memset(&create_params, 0, sizeof(NvBufSurfaceCreateParams));
      create_params.gpuId = ip_surf->gpuId;
      create_params.width = ip_surf->surfaceList[0].width;
      create_params.height = ip_surf->surfaceList[0].height;
      create_params.layout = NVBUF_LAYOUT_PITCH;
      create_params.size = 0;
      create_params.colorFormat = ip_surf->surfaceList[0].colorFormat;
      create_params.memType = NVBUF_MEM_CUDA_UNIFIED;  // 或者 NVBUF_MEM_HOST
      NvBufSurfTransformRect src_rect, dst_rect;  

      int batch_size= ip_surf->batchSize;

      src_rect.top   = 0;
      src_rect.left  = 0;
      src_rect.width = (guint) ip_surf->surfaceList[0].width;
      src_rect.height= (guint) ip_surf->surfaceList[0].height;
      dst_rect.top   = 0;
      dst_rect.left  = 0;
      dst_rect.width = (guint) ip_surf->surfaceList[0].width;
      dst_rect.height= (guint) ip_surf->surfaceList[0].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;

      cudaError_t cuda_err;
      cuda_err = cudaSetDevice (ip_surf->gpuId);
      cudaStream_t cuda_stream;
      cuda_err=cudaStreamCreate (&cuda_stream);

      NvBufSurfTransformConfigParams transform_config_params;
      NvBufSurfTransform_Error err;

      transform_config_params.compute_mode = NvBufSurfTransformCompute_Default;
      transform_config_params.gpu_id = ip_surf->gpuId;
      transform_config_params.cuda_stream = cuda_stream;
      err = NvBufSurfTransformSetSessionParams (&transform_config_params);

      if (NvBufSurfaceCreate(&uni_surf, ip_surf->batchSize, &create_params) != 0) {
          g_print("Failed to create NvBufSurface for unified memory\n");
          gst_buffer_unmap(buf, &inmap);
          return;
      }


      NvBufSurfaceMemSet (uni_surf, -1, -1, 0);
      err = NvBufSurfTransform (ip_surf, uni_surf, &nvbufsurface_params);
      if (err != NvBufSurfTransformError_Success) {
        g_print ("NvBufSurfTransform failed with error %d while converting buffer\n", err);
        return;
      }
    NvBufSurfaceMap(uni_surf, -1, -1, NVBUF_MAP_READ);
    NvBufSurfaceSyncForCpu(ip_surf, -1, -1);


    printf("uni_surf->gpuId = %d\n", uni_surf->gpuId);
    printf("uni_surf->batchSize = %d\n", uni_surf->batchSize);
    printf("uni_surf->memType = %d\n", uni_surf->memType);
    printf("uni_surf->surfaceList = %p\n", uni_surf->surfaceList);
    printf("uni_surf->surfaceList size = %d\n", sizeof(uni_surf->surfaceList)/sizeof(uni_surf->surfaceList[0]));
    printf("uni_surf->numFilled = %d\n", uni_surf->numFilled);
    int num_p = uni_surf->surfaceList[0].planeParams.num_planes;

      for (NvDsMetaList * l_frame = batch_meta->frame_meta_list; l_frame != NULL;
        l_frame = l_frame->next) {
        NvDsFrameMeta *frame_meta = (NvDsFrameMeta *) l_frame->data;
        int sur_id = frame_meta->batch_id;

        printf("uni_surf->surfaceList[%d] = %p\n", sur_id, uni_surf->surfaceList[sur_id]);
        printf("uni_surf->surfaceList[%d].colorFormat = %d\n", sur_id, uni_surf->surfaceList[sur_id].colorFormat);
        for (int j = 0; j < num_p; ++j) {
          printf("uni_surf->surfaceList[%d].mappedAddr.addr[%d] = %p\n", sur_id, j, uni_surf->surfaceList[sur_id].mappedAddr.addr[j]);
          printf("uni_surf->surfaceList[%d].planeParams.pitch[%d] = %d\n", sur_id, j, uni_surf->surfaceList[sur_id].planeParams.pitch[j]);
          printf("uni_surf->surfaceList[%d].planeParams.width[%d] = %d\n", sur_id, j, uni_surf->surfaceList[sur_id].planeParams.width[j]);
          printf("uni_surf->surfaceList[%d].planeParams.height[%d] = %d\n", sur_id, j, uni_surf->surfaceList[sur_id].planeParams.height[j]);
          printf("uni_surf->surfaceList[%d].planeParams.offset[%d] = %d\n", sur_id, j, uni_surf->surfaceList[sur_id].planeParams.offset[j]);
          printf("uni_surf->surfaceList[%d].planeParams.psize[%d] = %d\n", sur_id, j, uni_surf->surfaceList[sur_id].planeParams.psize[j]);
          printf("uni_surf->surfaceList[%d].planeParams.bytesPerPix[%d] = %d\n", sur_id, j, uni_surf->surfaceList[sur_id].planeParams.bytesPerPix[j]);
        }


        void* y_plane = uni_surf->surfaceList[0].mappedAddr.addr[0];
        void* uv_plane = uni_surf->surfaceList[0].mappedAddr.addr[1];
        int height = uni_surf->surfaceList[0].planeParams.height[0];
        int width = uni_surf->surfaceList[0].planeParams.width[0];
        int step = uni_surf->surfaceList[0].planeParams.pitch[0];
        printf("height = %d, width = %d, step = %d\n", height, width, step);

        cv::Mat y_mat(height, width, CV_8UC1, y_plane, step);
        cv::Mat uv_mat(height / 2, width / 2, CV_8UC2, uv_plane, step);
        cv::Mat nv12_mat(height + height / 2, width, CV_8UC1);
        // Segmentation fault immediately.
        y_mat.copyTo(nv12_mat(cv::Rect(0, 0, width, height)));
        uv_mat.copyTo(nv12_mat(cv::Rect(0, height, width, height / 2)));

        cv::Mat rgb_mat;
        cv::cvtColor(nv12_mat, rgb_mat, cv::COLOR_YUV2RGB_NV12);

        std::vector<uchar> jpeg_buffer;
        cv::imencode(".jpg", rgb_mat, jpeg_buffer);

        printf("dot base64\n");
        gchar* base64_jpeg = g_base64_encode(jpeg_buffer.data(), jpeg_buffer.size());

        printf("Base64 JPEG:\n%s\n", base64_jpeg);
......

Do we have some similar examples?

There is no such workaround currently, because the virtual machine does not support GPU virtualization.

DeepStream only support native Linux for the moment"

Refer to the example below

static GstPadProbeReturn infer_sink_pad_buffer_probe(GstPad *pad,
                                                     GstPadProbeInfo *info,
                                                     gpointer u_data) {
  GstBuffer *buf = (GstBuffer *)info->data;
  NvDsBatchMeta *batch_meta = gst_buffer_get_nvds_batch_meta(buf);
  NvDsMetaList *l_frame = NULL;
  char file_name[128];

  // Get original raw data
  GstMapInfo in_map_info;
  if (!gst_buffer_map(buf, &in_map_info, GST_MAP_READ)) {
    g_print("Error: Failed to map gst buffer\n");
    return GST_PAD_PROBE_OK;
  }
  NvBufSurface *surface = (NvBufSurface *)in_map_info.data;
  // TODO for cuda device memory we need to use cudamemcpy
  NvBufSurfaceMap(surface, -1, -1, NVBUF_MAP_READ);
#ifdef PLATFORM_TEGRA
  /* Cache the mapped data for CPU access */
  if (surface->memType == NVBUF_MEM_SURFACE_ARRAY) {
    NvBufSurfaceSyncForCpu(surface, 0, 0);
  }
#endif

  for (l_frame = batch_meta->frame_meta_list; l_frame != NULL;
       l_frame = l_frame->next) {
    NvDsFrameMeta *frame_meta = (NvDsFrameMeta *)(l_frame->data);

    guint height = surface->surfaceList[frame_meta->batch_id].height;
    guint width = surface->surfaceList[frame_meta->batch_id].width;
    // Create Mat from NvMM memory, refer opencv API for how to create a Mat

    // only rotate the first 10 frames
    NvBufSurface *inter_buf = nullptr;
    NvBufSurfaceCreateParams create_params;
    create_params.gpuId = surface->gpuId;
    create_params.width = width;
    create_params.height = height;
    create_params.size = 0;
    create_params.colorFormat = NVBUF_COLOR_FORMAT_BGRA;
    create_params.layout = NVBUF_LAYOUT_PITCH;
#ifdef __aarch64__
    create_params.memType = NVBUF_MEM_DEFAULT;
#else
    create_params.memType = NVBUF_MEM_CUDA_UNIFIED;
#endif
    // Create another scratch RGBA NvBufSurface
    if (NvBufSurfaceCreate(&inter_buf, 1, &create_params) != 0) {
      GST_ERROR("Error: Could not allocate internal buffer ");
      return GST_PAD_PROBE_OK;
    }

    NvBufSurfTransformConfigParams transform_config_params;
    NvBufSurfTransformParams transform_params;
    NvBufSurfTransformRect src_rect;
    NvBufSurfTransformRect dst_rect;
    cudaStream_t cuda_stream;
    CHECK_CUDA_STATUS(cudaStreamCreate(&cuda_stream),
                      "Could not create cuda stream");
    transform_config_params.compute_mode = NvBufSurfTransformCompute_Default;
    transform_config_params.gpu_id = surface->gpuId;
    transform_config_params.cuda_stream = cuda_stream;
    /* Set the transform session parameters for the conversions executed in this
     * thread. */
    NvBufSurfTransform_Error err =
        NvBufSurfTransformSetSessionParams(&transform_config_params);
    if (err != NvBufSurfTransformError_Success) {
      cout << "NvBufSurfTransformSetSessionParams failed with error " << err
           << endl;
      return GST_PAD_PROBE_OK;
    }
    /* Set the transform ROIs for source and destination, only do the color
     * format conversion*/
    src_rect = {0, 0, width, height};
    dst_rect = {0, 0, width, height};

    /* Set the transform parameters */
    transform_params.src_rect = &src_rect;
    transform_params.dst_rect = &dst_rect;
    transform_params.transform_flag = NVBUFSURF_TRANSFORM_FILTER;
    transform_params.transform_flip = NvBufSurfTransform_None;
    transform_params.transform_filter = NvBufSurfTransformInter_Algo3;

    /* Transformation format conversion */
    err = NvBufSurfTransform(surface, inter_buf, &transform_params);
    if (err != NvBufSurfTransformError_Success) {
      cout << "NvBufSurfTransform failed with error %d while converting buffer"
           << err << endl;
      return GST_PAD_PROBE_OK;
    }

    // map for cpu
    if (NvBufSurfaceMap(inter_buf, 0, -1, NVBUF_MAP_READ_WRITE) != 0) {
      cout << "map error" << endl;
      break;
    }

#ifdef PLATFORM_TEGRA
    if (surface->memType == NVBUF_MEM_SURFACE_ARRAY) {
      NvBufSurfaceSyncForCpu(inter_buf, 0, 0);
    }
#endif
    // make mat from inter-surface buffer
    Mat rawmat(height, width, CV_8UC4,
               inter_buf->surfaceList[0].mappedAddr.addr[0],
               inter_buf->surfaceList[0].planeParams.pitch[0]);
    char *data = (char *)malloc(width * height * 4);
    // make temp rotate mat from malloc buffer
    Mat rotate_mat(width, height, CV_8UC4, data, height);
    // Aplly your algo which works with opencv Mat, here we only rotate the Mat
    // for demo
    rotate(rawmat, rotate_mat, ROTATE_180);
    free(data);
    if (frame_number % 300 == 0) {
      snprintf(file_name, sizeof(file_name), "frame-%d.png", frame_number);
      cv::imwrite(file_name, rotate_mat);
    }
#ifdef PLATFORM_TEGRA
    if (inter_buf->memType == NVBUF_MEM_SURFACE_ARRAY) {
      NvBufSurfaceSyncForDevice(inter_buf, 0, 0);
    }
#endif
    // unmap
    NvBufSurfaceUnMap(inter_buf, 0, -1);
    NvBufSurfaceDestroy(inter_buf);
  }

#ifdef PLATFORM_TEGRA
  if (surface->memType == NVBUF_MEM_SURFACE_ARRAY) {
    NvBufSurfaceSyncForDevice(surface, 0, 0);
  }
#endif
  NvBufSurfaceUnMap(surface, -1, -1);
  gst_buffer_unmap(buf, &in_map_info);
  return GST_PAD_PROBE_OK;
}
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.