How to use NvBufSurfaceCopy to copy surface from CUDA device to CPU accessable memory

Please provide complete information as applicable to your setup.

• Hardware Platform (Jetson / GPU) GPU
• DeepStream Version 5.0 Beta
• JetPack Version (valid for Jetson only)
• TensorRT Version
• NVIDIA GPU Driver Version (valid for GPU only) 10.2
• Issue Type( questions, new requirements, bugs) questions
• How to reproduce the issue ? (This is for bugs. Including which sample app is using, the configuration files content, the command line used and other details for reproducing)

I want to copy the NvBufSurface structure in gst-buffer from CUDA device to CPU, I try to create a new surface in CPU and then apply NvBufSurfaceCopy function. but it says “buffer size mismatch” and failed to copy.

As I dig into this, the ip_surf_cuda structure have batchSize=4 and numFilled=2, only the firest 2 entry have dataSize>2. Is there any reference solution to conduct the copy process?

GstMapInfo inmap = GST_MAP_INFO_INIT;
  if (!gst_buffer_map (buf, &inmap, GST_MAP_READ)) {
    NVGSTDS_ERR_MSG_V ("Input buffer mapinfo failed.");
    return;
  }
  NvBufSurface *ip_surf_cuda = (NvBufSurface *) inmap.data;
  // FIXME: copy content from CUDA to CPU accessible memory. or set memory type to NVBUF_MEM_CUDA_UNIFIED
  NvBufSurface *ip_surf = NULL;
  NvBufSurfaceCreateParams params  = {
    .size = ip_surf_cuda->surfaceList[0].dataSize,
    .memType = NVBUF_MEM_SYSTEM
  };
  NvBufSurfaceCreate (&ip_surf, ip_surf_cuda->numFilled, &params);
  ip_surf->batchSize = ip_surf_cuda->batchSize;
  ip_surf->numFilled = ip_surf_cuda->numFilled;
  ip_surf->memType = NVBUF_MEM_SYSTEM;
  for (int i=0; i < ip_surf_cuda->batchSize; i++) {
    ip_surf->surfaceList[i].dataSize = ip_surf_cuda->surfaceList[i].dataSize;
  }

  // abort();

  if (NvBufSurfaceCopy (ip_surf_cuda, ip_surf) != 0) {
    GST_CAT_DEBUG (NVDS_APP, "Fail to copy surface to cpu, mem type = %d",
        ip_surf->memType);
    goto done;
  } else {
    GST_CAT_DEBUG (NVDS_APP, "Successfully copy surface to cpu, mem type = %d",
        ip_surf->memType);
  }

• Requirement details( This is for new requirement. Including the module name-for which plugin or for which sample application, the function description)

Hi @horacehxw,
Before you call NvBufSurfaceCreate (… , &params), please set the value of all the elements of “NvBufSurfaceCreateParams params” according to the input - NvBufSurface *ip_surf_cuda, e.g. gpuid, width, height, colorFormat, layout, and so on

According to Deepstream5.0 documentation, the size element of NvBufSurfaceCreateParams "Holds the amount of memory to be allocated. Optional; if set, all other
parameters (width, height, etc.) are ignored. "

image

https://docs.nvidia.com/metropolis/deepstream/dev-guide/DeepStream_Development_Guide/baggage/structNvBufSurfaceCreateParams.html#aafabab430f9fb14598afc762f5770d37

Why should I set gpuid, width, height, colorFormat, layout, etc?

@mchi

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

Is it possible to give me a simple repo?

Thanks!

Basically I move everything into CUDA_UNIFIED_MEMORY so that there’s no need to copy from CUDA device to CPU memory.

Besides that, a nvvideoconverter plugin should be added at the end of all source elements, convert them to unified memory.