Nvbuf_utils: Can not get HW buffer from FD... Exiting... error

Hi,
I am currently trying to do jpeg decoding using the Hardware decoder on Xavier NX, The decoding was working in Jetpack5.0, but when I switched to the newer Jetpack version of 5.0.2, the same jpeg decoding was not working and gave the error mentioned in the title & below
nvbuf_utils: Can not get HW buffer from FD… Exiting…

I found that am getting this error while getting params from the Hardware buffer fd in the below code

NvJPEGDecoder *jpegdec = NvJPEGDecoder::createJPEGDecoder(“jpegdec”);
ret = jpegdec->decodeToFd(fd, buffer, file_size, pixfmt, width, height);
NvBufferParams input_params = {0};
ret = NvBufferGetParams(fd, &input_params);

In the above code, at last line I am getting the error, can you please help me why I am getting this error after switching to newer version of jetpack & not in old version as mentioned

Hi,
We have switched to NvBufSurface APIs on Jetpack 5. Please refer to
Jetson Linux 35.1 | NVIDIA Developer

nvbuf_utils to NvUtils Migration Guide

okay, thanks

Do You have any examples related to decoding a jpeg file using this changed API?

I have tried this sample code, but I am getting segmentation fault,

ret = jpegdec->decodeToFd(fd, jstream, size, pixfmt, width, height);
NvBufSurf::NvCommonAllocateParams params;
/* Create PitchLinear output buffer for transform. */
params.memType = NVBUF_MEM_SURFACE_ARRAY;
params.width = width;
params.height = height;
params.layout = NVBUF_LAYOUT_PITCH;
params.colorFormat = NvBufferColorFormat_YUV422;
params.memtag = NvBufSurfaceTag_VIDEO_CONVERT;

ret = NvBufSurf::NvAllocate(&params, 1, &dst_dma_fd);

/* Clip & Stitch can be done by adjusting rectangle. */
NvBufSurf::NvCommonTransformParams transform_params;
transform_params.src_top = 0;
transform_params.src_left = 0;
transform_params.src_width = width;
transform_params.src_height = height;
transform_params.dst_top = 0;
transform_params.dst_left = 0;
transform_params.dst_width = width;
transform_params.dst_height = height;
transform_params.flag = NVBUFSURF_TRANSFORM_FILTER;
transform_params.flip = NvBufSurfTransform_None;
transform_params.filter = NvBufSurfTransformInter_Nearest;

ret = NvBufSurf::NvTransform(&transform_params, fd, dst_dma_fd);

NvBufSurface *pSurf = NULL;
ret = NvBufSurfaceFromFd(dst_dma_fd,(void**)(&pSurf));
ret = NvBufSurfaceMapEglImage(pSurf, 0);

ret = NvBufSurface2Raw(pSurf,0,0,width,height,YUV);
ret = NvBufSurface2Raw(pSurf,0,1,width/2,height,YUV+(height * width));
ret = NvBufSurface2Raw(pSurf,0,2,width/2,height,YUV+(height * width)+(height * int(width / 2)));

in the NvBufSurface2Raw function, I am getting the segmentation fault, I have allocated memory for YUV already.

Hi,
You may refer to

/usr/src/jetson_multimedia_api/samples/12_camera_v4l2_cuda/

There is code about MJPEG decoding and then convert to YUV420. Please take a look.

The code I have posted is mostly took from 06_jpeg_decode and 12_camera_v4l2_cuda only

Hi,
For saving frame data to a file, please refer to dump_dmabuf() in

/usr/src/jetson_multimedia_api/samples/common/classes/NvUtils.cpp

Yes, I was saving the decoder output using dump_dmabuf(), but Now I want to copy the DMA buffer fd to some other CPU buffer, in previous versions I was copying using NvBuffer2Raw, but now according to the migration guide in jetpack 5.0.2 you provided I need to use NvBufSurface2Raw, this function is giving me segmentation fault when I am copying, can you please provide some example for copying the DMA buffer fd to CPU buffer?

Hi,
Please refer to the patch to 12_camera_v4l2_cuda:

@@ -644,6 +644,24 @@ start_capture(context_t * ctx)
                 /* Convert the decoded buffer to YUV420P */
                 if (NvBufSurf::NvTransform(&transform_params, fd, ctx->render_dmabuf_fd))
                     ERROR_RETURN("Failed to convert the buffer");
+
+if (ctx->frame == 123)
+{
+    NvBufSurface *pSurf = NULL;
+    unsigned char *ptr;
+    int size, file;
+
+    NvBufSurfaceFromFd(ctx->render_dmabuf_fd, (void**)(&pSurf));
+    size = width*height*3/2;
+    ptr = (unsigned char *)malloc(size);
+    NvBufSurface2Raw(pSurf,0,0,width,height,ptr);
+    NvBufSurface2Raw(pSurf,0,1,(width>>1),(height>>1), ptr + (height * width));
+    NvBufSurface2Raw(pSurf,0,2,(width>>1),(height>>1), ptr + (height*width) + ((height *width)>>2) );
+    file = open("/tmp/dump.yuv", O_CREAT | O_WRONLY | O_APPEND | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
+    write(file, ptr, size);
+    close(file);
+    free(ptr);
+}
             } else {
                 NvBufSurface *pSurf = NULL;
                 if (-1 == NvBufSurfaceFromFd(ctx->g_buff[v4l2_buf.index].dmabuff_fd,

Okay, thanks, will try this

I have tried the patch you have given, but I am not getting proper YUV data when visualizing YUV in rawpixels.net it is showing a green image. Below is the code I followed

uint32_t width, height, pixfmt;
int fd = -1;
int dst_dma_fd = -1;
int ret;

ret = jpegdec->decodeToFd(fd, jstream, size, pixfmt, width, height);
int yuv_size = int(height*width*3/2);
unsigned char *YUV = new unsigned char[yuv_size]();
NvBufSurf::NvCommonAllocateParams params = {0};
/* Create PitchLinear output buffer for transform. */
params.memType = NVBUF_MEM_SURFACE_ARRAY;
params.width = width;
params.height = height;
params.layout = NVBUF_LAYOUT_PITCH;
params.colorFormat = NVBUF_COLOR_FORMAT_YUV420;
params.memtag = NvBufSurfaceTag_NONE;

ret = NvBufSurf::NvAllocate(&params, 1, &dst_dma_fd);

/* Clip & Stitch can be done by adjusting rectangle. */
NvBufSurf::NvCommonTransformParams transform_params;
transform_params.src_top = 0;
transform_params.src_left = 0;
transform_params.src_width = width;
transform_params.src_height = height;
transform_params.dst_top = 0;
transform_params.dst_left = 0;
transform_params.dst_width = width;
transform_params.dst_height = height;
transform_params.flag = NVBUFSURF_TRANSFORM_FILTER;
transform_params.flip = NvBufSurfTransform_None;
transform_params.filter = NvBufSurfTransformInter_Nearest;
ret = NvBufSurf::NvTransform(&transform_params, fd, dst_dma_fd);

NvBufSurface *pSurf = NULL;
ret = NvBufSurfaceFromFd(dst_dma_fd,(void**)(&pSurf));
 NvBufSurface2Raw(pSurf,0,0,width,height,YUV);
NvBufSurface2Raw(pSurf,0,1,(width>>1),(height>>1), YUV + (height * width));
NvBufSurface2Raw(pSurf,0,2,(width>>1),(height>>1), YUV + (height*width) + ((height *width)>>2) );
int file = open("./dump.yuv", O_CREAT | O_WRONLY | O_APPEND | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
write(file, YUV,yuv_size);
close(file);
delete YUV;

Can you please look at the cod & what am doing wrong?

Hi,
You may try 7yuv http://datahammer.de/
We can see correct result with it.

The code is correct, right?

even in the tool provided by you also gave same green image when opening the generated YUV

Hi,
We don’t see anything suspicious in the code. Would suggest set up Xavier developer kit + USB camera to run 12_camera_v4l2_cuda + the patch. See if you can get valid result in this setup.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.