1
0
mirror of https://git.ffmpeg.org/ffmpeg.git synced 2026-10-24 02:09:03 +03:00

avutil/hwcontext_vulkan: copy only the bytes of the visible rows

copy_buffer_data() copied FFABS(linesize) bytes per row between the
software frame and the staging buffer. The last row of a plane does not
have to extend to the full linesize, so this read past the end of the
software frame on upload and wrote past it on download.

The staging path is always taken for frames with a negative linesize,
and by default for multi-plane formats on the NVIDIA proprietary driver,
where host image copies are disabled and host memory import is avoided.

Same issue as fixed for hwcontext_cuda in f07f02abb8.

Out of array read and write replicated through the API with ASAN.
This commit is contained in:
Prasanna Dabi
2026-10-20 07:49:28 +00:00
committed by prasanna8585
parent 744588782d
commit fdd4e83ea0

View File

@@ -4725,6 +4725,15 @@ static int copy_buffer_data(AVHWFramesContext *hwfc, FFVkBuffer *vkbuf,
{
int err;
VulkanDevicePriv *p = hwfc->device_ctx->hwctx;
int bytewidth[AV_NUM_DATA_POINTERS];
/* Copy only the visible bytes of each row, the last row of a plane
* does not have to extend to the full linesize. */
for (int i = 0; i < planes; i++) {
bytewidth[i] = av_image_get_linesize(swf->format, swf->width, i);
if (bytewidth[i] < 0)
return bytewidth[i];
}
if (upload) {
for (int i = 0; i < planes; i++)
@@ -4732,7 +4741,7 @@ static int copy_buffer_data(AVHWFramesContext *hwfc, FFVkBuffer *vkbuf,
region[i].bufferRowLength,
swf->data[i],
swf->linesize[i],
FFABS(swf->linesize[i]),
bytewidth[i],
region[i].imageExtent.height);
err = ff_vk_flush_buffer(&p->vkctx, vkbuf, 0, VK_WHOLE_SIZE, 1);
@@ -4754,7 +4763,7 @@ static int copy_buffer_data(AVHWFramesContext *hwfc, FFVkBuffer *vkbuf,
swf->linesize[i],
vkbuf->mapped_mem + region[i].bufferOffset,
region[i].bufferRowLength,
FFABS(swf->linesize[i]),
bytewidth[i],
region[i].imageExtent.height);
}