How do I read the pixel data from an NVBuffer?

I am trying to modify the NVidia h265 video decode example. I am decoding the frames and I want to move them to the CPU and put them in OpenCV MAT containers for further processing, but I can’t seem to read the data properly.

If I take the NVBuffer file descriptor and pass it on to a jpeg encoder I get the correct image, so I know the buffer is good, but when I try to read the data manually with

NvBufferGetParams()
NvBufferMemMap()
NvBufferMemSyncForCpu()
NvBufferMemUnMap()

I get an image that looks as if it contains stride errors, but I can’t find any…
Below are examples. These are one and the same frame:

What am I doing wrong here? Is the raw buffer tiled or strided in some way that I am not taking into account when reading it back?
Thanks

Hi,
Probably you don’t convert the buffer to pitch linear layout. Please refer to this patch:
NVBuffer (FD) to opencv Mat - #6 by DaneLLL

Thanks DaneLLL, I forgot to mention that I am not running a Live Camera stream with the Argus API, for Argus I was able to handle the conversion and indeed a transform to ABGR fixed the issue there, but now I have a raw H265 stream that I recorded previously and I am trying to modify the samples/00_video_decode example. Basically I am trying to replace the EGLImage renderer and instead store the frames in OpenCV Mats, but so far without success.

I can’t seem to find an equivalent of the Argus transformation to ABGR32 without using Argus.
Do you have an example code where I can convert a NvBuffer that is in NV12 format to an NvBuffer that is in ABGR32 that is not using argus?

I just saw that samples/bacjend seems to do something similar to what I want. On first glance is spawns another thread that is utilizing an NvVideoConverter to convert the frame to ABGR and pass them on to TRT, but that looks a bit of an overkill for what I am trying to do. Is there a simpler alternative?

Hi,
You can call NvBufferTransform(). There is similar code in 00_video_decode:

                /* Perform Blocklinear to PitchLinear conversion. */
                ret = NvBufferTransform(dec_buffer->planes[0].fd, ctx->dst_dma_fd, &transform_params);
                if (ret == -1)
                {
                    cerr << "Transform failed" << endl;
                    break;
                }

Thanks DaneLLL, I thought that I was converting to PitchLinear, but it appears I wasn’t. Everything works great now.

1 Like