DeepStream on Jetson: copy NvBufSurface data from CUeglFrame to conventional device memory

Hi,

I am using JetPack 4.4 on Jetson Nano with DeepStream 5.

I am trying to copy a frame from NvBufSurface to conventional device memory.

As described in DeepStream ds-example plugin, one can access buffer data in CUDA using CUeglFrame:

    CUeglFrame egl_frame;
    CUgraphicsResource p_resource = NULL;
    cuGraphicsEGLRegisterImage(&p_resource,
                                   ip_surf.surfaceList[0].mappedAddr.eglImage,
                                   CU_GRAPHICS_MAP_RESOURCE_FLAGS_NONE);
    cuGraphicsResourceGetMappedEglFrame(&egl_frame, p_resource, 0, 0);

Having a frame in YUV NV12 format in buffer, I successfully get cudaArray pointers to planes (egl_frame.frame.pPitch[0] for the luma (Y) plane and egl_frame.frame.pPitch[1] for UV plane). Using texture-related function (tex2D<uint8_t>(tex_obj, x, y) in copy kernel) I can copy luma component completely, but when I try to copy UV plane I could n’t get fully colored image. It seems like only one component either U or V is copied. Could someone please give a hint on a way to do this?

Ok, I was dumb.

There is function to copy cudaArray: cudaMemcpy2DFromArray.
So given allocated device memory cudaMallocPitch((void**)d_frame, &d_pitch, width, height + height/2), one can simple call copy function twice for both YUV NV12 planes:

    cudaMemcpy2DFromArray(d_image, d_pitch,
                          (cudaArray *) egl_frame.frame.pPitch[0], 0, 0,
                          width, height,
                          cudaMemcpyDeviceToDevice);

    uint8_t *uv_image_plane = d_image + d_pitch * height;
    cudaMemcpy2DFromArray(uv_image_plane, d_pitch,
                          (cudaArray *) egl_frame.frame.pPitch[1], 0, 0,
                          width, height / 2,
                          cudaMemcpyDeviceToDevice);