Unexpected padding when creating new surface

I’m looking to convert an image from RGBA to GRAY8 and run some additional pre-processing before running it through nvinfer without actually modifying the image in the stream. The way I’ve been going about that is to create a temporary surface that I can then pre-process and pass into nvinfer process. While working on this I noticed that the allocated size of the buffer in the temporary surface has extra padding (I assume this might be for architectural reasons?). The size of the buffer is 2,228,224 bytes for a 1920x1080 GRAY8 image. The pitch is 2048 which would look to mean that there are effectively 1088 rows in the data. Is this extra padding is to be expected? Are the extra bytes tacked to the end? Do the extra bytes hold any relevant data or are they simply padding?

More generally I’m wondering how does NvBufSurfaceCreate decide how much memory to allocate for each buffer in a batch? I believe the source code behind this is not public, but if it is I would appreciate a pointer to the right repository. A minimal example of the creation code I’m running is below. This is running on a Jetson nano.

NvBufSurface * surf = nullptr;

NvBufSurfaceCreateParams create_params;
create_params.gpuId = 0;
create_params.memType = NVBUF_MEM_DEFAULT;
create_params.colorFormat = NVBUF_COLOR_FORMAT_GRAY8;
create_params.layout = NVBUF_LAYOUT_PITCH;
create_params.height = 1080;
create_params.width = 1920;

NvBufSurfaceCreate(&surf, 1, &create_params);

// surf->surfaceList[0].dataSize is now 2228224

The extra padding is expected. NvBufSurface is hardware DMA buffer and there is hardware alignment. It is not able to be as flexible as CPU buffers due to hardware design.

1 Like

It looks like the extra bytes are added below (higher row index) and to the right (higher column index) of the images. Is that always correct?

Yes. You can get valid data through width, height, and pitch values.

1 Like