FBO to NvBuffer

Hello, I’m trying to render something in a OpenGL FBO and output the result to a DMABuf.

Here is the code I’m using to check for the image content:

        void * virtual_addr = nullptr;
        NvBufferMemMap(_dmabuf_fd, 0, NvBufferMem_Read, &virtual_addr);
        NvBufferMemSyncForCpu (_dmabuf_fd, 0, &virtual_addr);
        cv::Mat outputImageNvBuffer( _height, _width, CV_8UC4, virtual_addr );
        cv::imwrite( "output_nvbuffer.jpg", outputImageNvBuffer );
        NvBufferMemUnMap (_dmabuf_fd, 0, &virtual_addr);

        unsigned char * outBuffer;
        size_t bufSize = _width * _height * 4;
        outBuffer = (unsigned char*)malloc(bufSize);
        glBindTexture(GL_TEXTURE_2D, _texId);
        glGetTexImage(GL_TEXTURE_2D,
                      0,
                      GL_RGBA,
                      GL_UNSIGNED_BYTE,
                      outBuffer);
        cv::Mat outputImageTexImage( _height, _width, CV_8UC4, outBuffer );
        cv::imwrite( "output_teximage.jpg", outputImageTexImage );

I’m using OpenCV for simple image I/O.
The image I get from glGetTexImage is correct, while the image I get from NvBufferMemMap is not (see attached files).

Also, here is the code I use to “map” the texture to my dmabuf :

NvBufferCreate(&_dmabuf_fd, _width, _height, NvBufferLayout_BlockLinear, NvBufferColorFormat_ABGR32);
_eglImage = NvEGLImageFromFd (_display, _dmabuf_fd);
_initialized = true;
glBindTexture (GL_TEXTURE_2D, _texId);
glEGLImageTargetTexture2DOES (GL_TEXTURE_2D, _eglImage);
glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _texId, 0);

What am I doing wrong ?


1 Like

Hi,
Please create NvBuffer in NvBufferLayout_Pitch for a try. The function cv::imwrite() should only support data layout in pitch linear.

May refer to this sample:
Trying to process with OpenGL an EGLImage created from a dmabuf_fd - #9 by DaneLLL
One minor bug in the sample:
Trying to process with OpenGL an EGLImage created from a dmabuf_fd - #12 by DaneLLL

Thanks.

I did run the provided example.


glReadPixels gives the expected result, while the nvbuffer mapping does not (see attached files).
FYI, I used an input texture of resolution (64x64), and the output resolution if (1024x1024)

Btw, using NvBufferLayout_Pitch results in an empty output, but I believe it was expected, since GL/EGL is using the Block layout, internally ?

Hi,
Please create another NvBuffer in pitchlinear. Once you get NvBuffer in blocklinear, you can call NvBufferTranform() to convert to pitch-linear buffer and encode the buffer to JPEG.

Thanks… It works now !!
My bad, I was already using pitch-linear to convert to cv::Mat in another part of the code.

1 Like

🙂
that’s awesome
@DaneLLL