Cuda memory access error with EGLFrame

I am following the 04_video_dec_trt examples for converting data from mipi camera (libargus) to float array for inference. I am getting the cuda illegal address access error while executing the convertEglFrameIntToFloat
function from NvCudaProc.cpp file.

Buffer creation:

void createNvBufferForTransform(const Size2D<uint32_t> size, int nBuffers,
                                ImagingContext *ctxt)
  {
      NvBufSurf::NvCommonAllocateParams aParams = {0};
      aParams.colorFormat = NvBufSurfaceColorFormat::NVBUF_COLOR_FORMAT_RGBA;
      aParams.height = size.height();
      aParams.width = size.width();
      aParams.layout = NvBufSurfaceLayout::NVBUF_LAYOUT_PITCH;
      aParams.memtag = NvBufSurfaceTag::NvBufSurfaceTag_VIDEO_CONVERT;
      aParams.memType = NvBufSurfaceMemType::NVBUF_MEM_SURFACE_ARRAY;

    ctxt->dstDmaFd = new int[nBuffers];
    ctxt->eglFramePtr = new CUeglFrame[nBuffers];
    ctxt->pResource = new CUgraphicsResource[nBuffers];
    ctxt->eglImagePtr = new EGLImageKHR[nBuffers];

    CUresult status;
    for (size_t i = 0; i < nBuffers; i++){
        NvBufSurf::NvAllocate(&aParams, 1, ctxt->dstDmaFd + i);
        NvBufSurface *bufSurf;
        int ret = NvBufSurfaceFromFd(*(ctxt->dstDmaFd + i), (void**)&bufSurf);
        if (ret < 0){
            std::cout << "Surf from fd failed" << std::endl;
            continue;
        }
        if (bufSurf->surfaceList[0].mappedAddr.eglImage == NULL)
        {
            if (NvBufSurfaceMapEglImage(bufSurf, 0) != 0)
            {
                std::cout << "Mapping EGL frame failed" << std::endl;
                continue;
            }
        }
        ctxt->eglImagePtr[i] = (EGLImageKHR*)bufSurf->surfaceList[0].mappedAddr.eglImage;
        if (ctxt->eglImagePtr[i] == NULL)
        {
            std::cout << "Mapping EGL frame failed again" << std::endl;
            continue;
        }
        ctxt->pResource[i] = NULL;
        cudaFree(0);
        status = cuGraphicsEGLRegisterImage(&(ctxt->pResource[i]), ctxt->eglImagePtr[i],
            CU_GRAPHICS_MAP_RESOURCE_FLAGS_NONE);
        if (status != CUDA_SUCCESS)
        {
            printf("cuGraphicsEGLRegisterImage failed: %d, cuda process stop\n",
                            status);
            return;
        }
        CUresult cuRes = cuCtxSynchronize();
        if(cuRes != CUDA_SUCCESS){
            cout << "Cuda sync failed" << endl;
            break;
        }

        status = cuGraphicsResourceGetMappedEglFrame(&ctxt->eglFramePtr[i], ctxt->pResource[i], 0, 0);
        if (status != CUDA_SUCCESS)
        {
            printf("cuGraphicsSubResourceGetMappedArray failed\n");
        }
        ctxt->dmaEglMap.insert(pair<int, CUeglFrame*>(*(ctxt->dstDmaFd + i), &ctxt->eglFramePtr[i]));
    }
    ctxt->pStreamConversion = new cudaStream_t;
    cudaStreamCreate(ctxt->pStreamConversion);
}

Capture Loop:

  for(i = 0; i < 100; i++){
      frame = UniqueObj<Frame>(iFrameConsumer->acquireFrame(40000000, &status));
      if (status != STATUS_OK)
      {
          continue;
      }
      try
      {
          iFrame = interface_cast<IFrame>(frame);
          iNativeBuffer = interface_cast<NV::IImageNativeBuffer>(iFrame->getImage());
          status = iNativeBuffer->copyToNvBuffer(fd);
          if (status != STATUS_OK){
              cout << "Copy to NVbuffer failed" << endl;
              continue;
          }
          frame.reset();
          int dmaFd = context.dstDmaFd[i % maxBuffers];
          nvRet = NvBufSurf::NvTransform(&tParams, fd, dmaFd);
          if (nvRet != 0){
              cout << "RGBA conversion failed" << endl;
              continue;
          }
          CUeglFrame *eglFrame = context.dmaEglMap.find(dmaFd)->second;
          int offs[] = {0, 0, 0};
          convertEglFrameIntToFloat(eglFrame, eglFrame->width, eglFrame->height,
                                    COLOR_FORMAT_RGB, mBuf, offs, offs, context.pStreamConversion);
          cudaError_t res = cudaStreamSynchronize(*context.pStreamConversion);
          if (res != cudaError_t::cudaSuccess){
              std::cout << "Error conversion";
              break;
          }
      }
      catch(...)
      {
          std::cout << "Image manipulation error\n";
      }
    }

I am getting error at cudaError_t res = cudaStreamSynchronize(*context.pStreamConversion);

Am I missing something in the configuration?

Hi,
Your use-case looks similar to this sample:

/usr/src/jetson_multimedia_api/samples/frontend

Please take a look at the sample and give it a try.

Hi @DaneLLL ,

I am doing the same as what’s explained in the frontend example except I am mapping the CUeglFrame during buffer creation itself instead of every iteration as mentioned in the example. Not sure that would make any difference. I think the main problem is that buffer (NvBufSurface) is accessible by CUDA.

Hi,
Are you able to run frontend sample successfully? Would like to know if you hit same issue while running the reference sample.

It runs without any issues.

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