Hi,
I have an imaging pipeline that has an input GPU buffer (block linear, ARGB) being converted into an output pitch linear buffer (also ARGB) using NvBufferTransform so that this is done in the hardware. The input buffer has an alpha channel that has information in it that needs to be preserved.
Unexpectedly, when the conversion is done, the input color data is scaled by its alpha channel (as in, blended with black), and the alpha channel is lost, so that it is set always to 0xFF (fully opaque) in the output. NvBufferTransform is not a composition operation, and not a conversion to XRGB, so it doesn’t make sense that alpha is getting lost.
Input buffer:
NvBufferCreateParams input_params = {
.width = (int32_t)width,
.height = (int32_t)height,
.payloadType = NvBufferPayload_SurfArray,
.memsize = 0,
.layout = NvBufferLayout_BlockLinear,
.colorFormat = NvBufferColorFormat_ARGB32,
.nvbuf_tag = NvBufferTag_VIDEO_CONVERT,
};
ret = NvBufferCreateEx (&nvBufBlock, &input_params);
if (ret)
qFatal("Unable to create block linear buffer.\n");
Output buffer:
NvBufferCreateParams input_params = {
.width = (int32_t)width,
.height = (int32_t)height,
.payloadType = NvBufferPayload_SurfArray,
.memsize = 0,
.layout = NvBufferLayout_Pitch,
.colorFormat = NvBufferColorFormat_ARGB32,
.nvbuf_tag = NvBufferTag_VIDEO_CONVERT,
};
ret = NvBufferCreateEx (&nvBufPitch, &input_params);
if (ret)
qFatal("Unable to create pitch buffer.\n");
Conversion:
const NvBufferRect src_rect = {
.top = 0,
.left = 0,
.width = width,
.height = height,
};
const NvBufferRect dest_rect = src_rect;
NvBufferTransformParams transform_params = {
.transform_flag = NVBUFFER_TRANSFORM_FILTER | NVBUFFER_TRANSFORM_FLIP,
.transform_flip = NvBufferTransform_FlipY,
.transform_filter = NvBufferTransform_Filter_Smart,
.src_rect = src_rect,
.dst_rect = dest_rect,
.session = NULL,
};
// Convert Blocklinear to PitchLinear
int ret = NvBufferTransform(nvBufBlock, nvBufPitch, &transform_params);
if (ret == -1)
qFatal("Transform failed");
If I map both the buffers and memcpy, I can see that the alpha channel is there and correct, but obviously the surface format is wrong. And this is slow, with memcpy being done on the CPU.
Is there a different way to do this conversion correctly that still performs well, so that I can convert between surface formats with the same ARGB format, and preserve the alpha channel?
Kurt