Segmentation fautl when trying to access NVMM memory

I’m porting some code that used to work on TX2 (Jetpack 3.3).
I am now compiling and running it on Xavier (Jetpack 4.2 rev1).

We attached a USB camera and run the following pipeline:

gst-launch-1.0 v4l2src device=/dev/video0 \
 ! 'video/x-raw,width=1280,height=720,framerate=(fraction)5/1' \
 ! nvvidconv ! 'video/x-raw(memory:NVMM), format=(string)I420' \
 ! nvvidconv output-buffers=16 ! 'video/x-raw(memory:NVMM), format=(string)I420' \
 ! my-plugin \ # This is the one!
 ! nvjpegenc \
 ! multifilesink location="snapshot-%05d.jpg" max-files=10

So my-plugin accepts I420 buffers in (memory:NVMM).

In all plugins that try to access the pixel information, I usually do the following steps:

GstMapInfo in_map_info;
if (gst_buffer_map(buf, &in_map_info, (GstMapFlags)GST_MAP_READWRITE) == FALSE) {
    std::cout << "Failed to map gstbuffer data for read_write" << std::endl;
    std::exit(1);
}

int in_dmabuf_fd = -1;
if (ExtractFdFromNvBuffer(in_map_info.data, &in_dmabuf_fd) != 0) {
    std::cout << "Failed to map hardware buffer on gstbuffer data" << std::endl;
    std::exit(1);
}

NvBufferParams param;
if (NvBufferGetParams(in_dmabuf_fd, &param) != 0) {
    std::cout << "Failed to get buffer params\n";
    std::exit(1);
}

/*
*  Do fun stuff with the pixels
*/

if (NvReleaseFd(in_dmabuf_fd) != 0) {
    std::cout << "Failed to release Fd=" << in_dmabuf_fd << '\n';
    std::exit(1);
}

gst_buffer_unmap(buf, &in_map_info);

This piece of code inside the chain chain function of my custom plugin causes a segmentation fault. Turns out the culprit is the call to NvReleaseFd. It actually crashed when calling this function. The checking of the return value does not even happen anymore.

Commenting it out appears to be fine but can someone from NVIDIA comment on this behavior?
Note that the “NvReleaseFd” is also used in gstdsexample.cpp

To me it makes sense that ExtractFdFromNvBuffer would acquire a non-owning reference to some buffer so Release should not be called on it, but is this reflected somewhere in the documentation and why does it not crash on the pipelines we have been running for months on the older TX2 with the older Jetpack version?

Hi,
After upgrading to r32 releases, please not to call NvReleaseFd(). It is handled in nvvidconv plugin.

Another relevant post:
[url]use gstreamer or tegra_multimedia_api to decode video would be more efficient and increase throughpu... - Jetson TX2 - NVIDIA Developer Forums

Hi DaneLLL,

Thanks for clarifying.

Does it make sense on your end to maybe just remove this particular function from your public API? Is there any use case where we would still need to call it?

For buffers that we created ourselves using

int NvBufferCreate (int *dmabuf_fd, int width, int height, NvBufferLayout layout, NvBufferColorFormat colorFormat);
int NvBufferCreateEx (int *dmabuf_fd, NvBufferCreateParams *input_params);

functions, we have the

int NvBufferDestroy (int dmabuf_fd);

function.

Eventhough you have changed the comment for NvReleaseFd, is is still very close to ExtractFdFromNvBuffer and in my opinion suggesting that it should be called. If you had removed this function from the API, our user-code would not compile anymore and we would not be chasing segfaults.

Maybe something to consider for next patch or is there still a use that I’m overlooking?

Kind regards,
Beerend

Hi,
We have open source package gst-omx which requires the API, although we are also deprecating omx plugins. We will check to review all public APIs. Thanks for your suggestion.

What does this mean concretely? We currently are using the omxh264enc plugin for efficient video streaming in our gstreamer pipeline. Will this disappear and if so, what would be the suggested alternative?

Hi,
We’re unifying interfaces between desktop GPUs and Jetson platforms, and have implemented V4L2 plugins such as nvv4l2h264enc, nvv4l2h265enc, nvv4l2decoder. If there’s new features, they will be implemented in V4L2 plugins. Omx plugins are being maintained but no more new features.