NvMediaImageLock caused segmentation fault

Hi,

I’m working on a PX2 project.
We need to connect the camera video and other applications.
Right now our approach is to use EGLStream to bridge the video streaming.
We do this based on the sample code of img_cap_eglprod (image producer) and eglstream (image consumer).
In the eglstream, we try to retrieve the image buffer by using below codes after NvMediaEglStreamConsumerAcquireImage.

if (image) {
        LOG_ERR("%s %d\n", __func__, __LINE__);
        NvMediaImageSurfaceMap surfaceMap;
        NvMediaStatus status;
        if ((status = NvMediaImageLock(image, NVMEDIA_IMAGE_ACCESS_WRITE, &surfaceMap)) !=
            NVMEDIA_STATUS_OK) {
            LOG_ERR("%s: NvMediaImageLock failed %d\n", __func__, status);
            goto fail;
        }
        LOG_ERR("%s %d %d %d\n", __func__, __LINE__, surfaceMap.height, surfaceMap.width);
        NvU32 srcPitch = 3840*4;
        if(NVMEDIA_STATUS_OK != (status = NvMediaImageGetBits(image, NULL, (void **)&inputBuffer, &srcPitch))) {
            LOG_ERR("Nvmedia image get bits fail %d\n", status);
            goto fail;
        }
        NvMediaImageUnlock(image);
        NvMediaEglStreamConsumerReleaseImage(display->consumer, image);
    }

However, every time we call NvMediaImageLock, we get a segmentation fault. Looking into the core dump, we found the issue was caused by NvMediaImageLock function. Is there any suggestion or direction we can check?
Thanks in advance.

PS. the producer and consumer are two different processes, the producer generates the image buffer, and we try to lock in the consumer process. don’t know if this matters.

Best,
Krammer

Dear chenghul,
May I know what is the objective of your project? Also, Is it possible to share a sample code to reproduce the issue on our side?

Hi Siva,

Thank you for your reply.

Our objective is to connect camera streaming with two different applications and use those camera frames to do the perception jobs. Specifically, we need to find a way to share the same camera streaming with two different applications (processes) and these applications might copy the entire frame buffer and do some operations based on the image.

Right now we are using img_cap_eglprod as the source application to capture camera streaming, and we use eglstream to mimic the two consumer applications. Everything goes well and we can get the NvMediaImage from EglStream. However, when we wanted to retrieve the real image buffer (so that our applications could do their works), we got a segmentation fault when calling NvMediaImageLock. Does our current approach make sense to you?

Regarding the sample code, do you have an email or any server which I could upload onto?

Thanks,
Krammer

Dear Chenghul,
If possible can you paste sample code here.

Hi Siva,

Thank you for your reply.
I’m afraid that I can share my code here.

Right now we already found the root cause of this issue. We didn’t initiate a NvMedia device before using the EGLStream. This was what caused the segmentation fault.

We still have a doubt about our approach. Right now from our measurement, the time it takes to do the NvMediaImageGetBits is around 80ms for a 1920x1208 resolution. This is considered too long for us. From the scenario I described before, do you have any suggestions or is there any other options we have?

Thanks,
Krammer

Hi Siva,

One update. After I changed the surface attributes of NVM_SURF_ATTR_CPU_ACCESS from NVM_SURF_ATTR_CPU_ASSESS_UNCACHED to NVM_SURF_CPU_ASSESS_CACHED, the time we spent in NvMediaImageGetBits reduced from 80ms to 16ms. Is there any side effect to make this kind of modification?

I can’t find many descriptions for this attribute, but I guess if we don’t use any hardware mechanism to modify our buffer, this is safe, right?

Best,
Krammer

Dear Krammer,
Noe that application must create 2 eglstreams, 2 consumers, 2 producers. Both the producers have to post the same image.
For more details you can refer to “Using NvMedia EGLStream to Send an Image to Multiple Consumers” section in the PDK documentation
https://docs.nvidia.com/drive/nvvib_docs/index.html#page/NVIDIA%20DRIVE%20Linux%20SDK%20Development%20Guide%2FGraphics%20Programming%20Guide%2Fgraphics_guide_eglstreams.html%23wwpID0E0LF0HA

For CPU ACCESS attributes, you can refer to the NvMedia Surface Allocation Guide
https://developer.download.nvidia.com/driveworks/installers/driveinstall/secure/5.0.5.0bL/NvMedia_Surface_Allocation_Guide_DRIVE_5.0.pdf?1eJK5YDz0vDIU49h3oSzgjfQCQm8xrgM-LprNF6R4xRkJD454mAb46pGFvwdDhd-j8rpdHG9y0jEFsrWUKuleqzGxNiCP3eSQ0hfUCGZFh8A31iw9X9wGOHnNnES-oC-k5qNKztC0iRnW1r9kycdXa7OJ3qpR6mxUoGISDQVhIksj0xZy2DZM_272Vs3q1-pu5K_wip2JmSkdzB43fdLFWI

If a NvMediaImage has to be accessed from CPU, then setting the surface attribute to NVM_SURF_CPU_ASSESS_CACHED during allocation time, will result in better performance for CPU accesses.

Hi Siva,

Understood. Thank you for your help.

Krammer