Nvivafilter EOS C

Hi, same error message when I tried Jetpack 4.6.3 via SDK Manager.

Hi,
Somehow we are not able to observe the issue in our setup. Since you have seen issues in using nvivafilter plugin, could you check if you can customize nvvidconv plugin to apply CUDA processing to the buffer? The nvvidconv plugin is public and you can download the source code from
https://developer.nvidia.com/downloads/remack-sdksjetpack-463r32releasev73sourcest210publicsourcestbz2

The implementation is based on NvBuffer APIs and with the following function calls:

NvEGLImageFromFd();
cuGraphicsEGLRegisterImage();
cuGraphicsResourceGetMappedEglFrame();

You can access the buffer through CUDA. Please check this and consider it as a possible solution.

Hi @DaneLLL,
I was able to get it working. I can stream RTSP with CUDA process and also start stop recording with the same CUDA process without the app crashing.

However, I am unsure how to handle eglTerminate(). I think that it’s because of this, memory is slowly increasing with each recording. Maybe worth mentioning I am also running headless, and eglQueryDevicesEXT() will detect only a single device.

If I call eglTerminate() at the end of gst_nvvconv_finalize(), streaming and recording still works, but I see repeated messages.

NvEGLImageFromFd: Failed to create EGLImage from dma-buf fd (1040)
cugraphicseglregisterimage failed : 999

Would you help me understand what’s happening?

Relevant bits of code:

static GstFlowReturn
gst_nvvconv_transform (GstBaseTransform * btrans, GstBuffer * inbuf, GstBuffer * outbuf)
{
…
image = NvEGLImageFromFd(eglDisplay, space->interbuf.idmabuf_fd);

CUresult status;
CUeglFrame eglFrame;
CUgraphicsResource pResource = NULL;

cudaFree(0);

status = cuGraphicsEGLRegisterImage(&pResource, image, CU_GRAPHICS_MAP_RESOURCE_FLAGS_NONE);
if (status != CUDA_SUCCESS) {
g_print(“cugraphicseglregisterimage failed : %d \n”, status);
goto done;
}

status = cuGraphicsResourceGetMappedEglFrame( &eglFrame, pResource, 0, 0);
if (status != CUDA_SUCCESS) {
g_print(“cudaGraphicsSubResourceGetMappedArray failed\n”);
}

status = cuCtxSynchronize();
if (status != CUDA_SUCCESS) {
g_print(“cuCtxSynchronize failed \n”);
}

if (eglFrame.frameType == CU_EGL_FRAME_TYPE_PITCH){
…

// start the CUDA process from here
// from nvivafilter custom lib
addLabels((CUdeviceptr) eglFrame.frame.pPitch[0], …
}

cuCtxSynchronize();
…
cuGraphicsUnregisterResource(pResource);

retn = NvBufferTransform (space->intervuf.idmavuf_fd, omem->buf->dmabuf_fd, &space->transform_params);

…
}

static gboolean
gst_nvvconv_start (GstBaseTransform * btrans)
{
EGLint major, minor;
eglDisplay = eglGetDisplay ( EGL_DEFAULT_DISPLAY );
eglInitialize ( eglDisplay, &major, &minor);
…
}

static gboolean
gst_nvvconv_finalize (GObject * object)
{
…
G_OBJECT_CLASS (parent_class)->finalize (object);
eglTerminate(eglDisplay);
}

I think I will try to initialize and terminate the EGL display from the GStreamer application instead of the plugin.

Hi,
Does it work if you call eglTerminate(); before G_OBJECT_CLASS (parent_class)->finalize (object);

Do you have HDMI out in your system?

I get the same result calling eglTerminate(); before G_OBJECT_CLASS(parent_class)->finalize (object);.
Also, initializing and terminating EGL display from the GStreamer application doesn’t seem to work either.

My dev kit has an HDMI out, but I will not be using it. In the previous tests with nvivafilter I had tried with a monitor attached.

I would ignore the NvEGLImageFromFd: Failed to create EGLImage from dma-buf fd (1040) error messages (which turns out to be the fd for the RTSP pipeline) but I suspect there is still a leak somewhere. And adding error handling flow_ret = GST_FLOW_ERROR will replicate the behavior of the nvivafilter examples.

I also tried to call image = NvEGLImageFromFd(eglDisplay, space->interbuf.idmabuf_fd); only once, but then for some reason the recording no longer had the CUDA process filter.

I have reason to believe the memory usage is a result of how I am starting and stopping the recording pipeline because if I replace my custom nvvidconv2 plugin with the original nvvidconv I see the same steady increase in memory usage.

Hi,
Could you try to call eglInitialize() and eglTerminate() globally, and then use the same context in the two nvvidconv plugins?

I will try again this weekend. Thank you.

Calling eglTerminate() globally solves the original issue of two CUDA filter pipelines.

I was confusing myself rewriting workign code thinking there was a memory leak. It seems as though it is not uncommon for GStreamer / GLib to look like it is leaking memory when it is not. If I find any significant problems after proper memory profiling, I will start a new topic. THank you @DaneLLL for your guidance.