Can sharing NvBuffer between different processes?

We need to pass nvbuffer between processes, using sendmsg()…

But encountered the following error:

nvbuf_utils: dmabuf_fd 3 mapped entry NOT found
nvbuf_utils: Can not get HW buffer from FD... Exiting...

Full source code:

#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>

#include <nvbuf_utils.h>

#define LOG(fmt, ...) printf(fmt "\n", ##__VA_ARGS__)

int main(char argc, char *argv[])
{
    int sock[2];
    if (socketpair(AF_UNIX, SOCK_STREAM, 0, sock))
    {
        LOG("[E] create sockpair failed!");
        return -1;
    }
    int pid = fork();
    char buf[100];
    struct iovec iov;
    if (pid != 0)
    {
        //create nvBuffer
        int fd;
        NvBufferCreateParams bufParams = {0};
        bufParams.width = 1280;
        bufParams.height = 720;
        bufParams.layout = NvBufferLayout_Pitch;
        bufParams.colorFormat = NvBufferColorFormat_NV12;
        bufParams.payloadType = NvBufferPayload_SurfArray;
        bufParams.nvbuf_tag = NvBufferTag_CAMERA;
        if (NvBufferCreateEx(&fd, &bufParams))
        {
            LOG("[E] create buffer for camera failed! err=%d", errno);
            return -1;
        }

        struct msghdr msg;
        msg.msg_iov = &iov;
        msg.msg_iovlen = 1;
        msg.msg_control = buf;
        msg.msg_controllen = sizeof(buf);
        struct cmsghdr *cmsg;
        cmsg = CMSG_FIRSTHDR(&msg);
        cmsg->cmsg_level = SOL_SOCKET;
        cmsg->cmsg_type = SCM_RIGHTS;
        cmsg->cmsg_len = CMSG_LEN(sizeof(int));
        memcpy(CMSG_DATA(cmsg), &fd, sizeof(int));
        msg.msg_controllen = cmsg->cmsg_len;
        if (sendmsg(sock[0], &msg, 0) <= 0)
        {
            LOG("[E] send fd to client failed, fd=%d! err=%d", fd, errno);
        }
        else
        {
            LOG("[I] sending fd=%d ok", fd);
        }
    }
    else
    {
        struct msghdr msg;
        msg.msg_iov = &iov;
        msg.msg_iovlen = 1;
        msg.msg_name = NULL;
        msg.msg_namelen = 0;
        msg.msg_control = buf;
        msg.msg_controllen = CMSG_LEN(sizeof(buf));
        if (recvmsg(sock[1], &msg, 0) <= 0)
        {
            LOG("[E] client recvmsg failed!");
            return -1;
        }
        struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
        if (cmsg->cmsg_type != SCM_RIGHTS)
        {
            LOG("[E] client recvmsg type wrong, type = %d", cmsg->cmsg_type);
            return -2;
        }
        int fd = *(int *)(CMSG_DATA(cmsg));
        LOG("[I] recv fd=%d ok", fd);

        NvBufferParams bufParam;
        //get nvBuffer param    
        if (NvBufferGetParams(fd, &bufParam))
        {
            LOG("[E] get buf param failed! err = %d", errno);
        }
        else
        {
            LOG("[I] buf info plane=%d, width=%d, height=%d, size=%d",
                bufParam.num_planes, bufParam.width[0], bufParam.height[0], bufParam.psize[0]);
        }
    }
}

Hi,
This is not supported. For sharing buffers between processes, you may use eglstream producer/consumer.

Is there detail documents or samples?

Thanks.

Do you mean the CUDA api : cuEGLStreamConsumerAcquireFrame, cuEGLStreamConsumerReleaseFrame.

Thanks.

@DaneLLL

I can’t found douments about eglstream on tx2 linux driver API.

It seems like eglsteam is part of NVMedia API.

Please check it …

Thanks.

Hi,
Please refer to
Problems getting EGL Stream transferred to another process on same machine - #7 by DaneLLL