aboutsummaryrefslogtreecommitdiffstats
path: root/libavutil/frame.c
diff options
context:
space:
mode:
authorPavel Koshevoy <pkoshevoy@gmail.com>2024-11-16 08:51:52 -0700
committerJames Almer <jamrial@gmail.com>2024-11-22 10:43:55 -0300
commit46cb7b8d9dcfdea1b1df446a98ec886a4434820c (patch)
tree0ce794554d4d5eac47e788064e501b2f2bb7b71d /libavutil/frame.c
parentea91d978e3be77de42f4b93194a286108de5720f (diff)
downloadffmpeg-46cb7b8d9dcfdea1b1df446a98ec886a4434820c.tar.gz
avutil/frame: also align data pointers in av_frame_get_buffer()
This avoids unpleasant surprises to av_frame_get_buffer callers that explicitly specified 64-byte alignment and didn't get AVFrame.data pointers that are 64-byte aligned. For example, see https://github.com/sekrit-twc/zimg/issues/212 Although the zscale issue has already been resolved by other means it would still be prudent to improve the behavior of av_frame_get_buffer to fix any unknown and future instances of similar issues. Co-authored-by: James Almer <jamrial@gmail.com> Signed-off-by: James Almer <jamrial@gmail.com>
Diffstat (limited to 'libavutil/frame.c')
-rw-r--r--libavutil/frame.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/libavutil/frame.c b/libavutil/frame.c
index 093853b173..5fb47dbaa6 100644
--- a/libavutil/frame.c
+++ b/libavutil/frame.c
@@ -210,7 +210,7 @@ static int get_video_buffer(AVFrame *frame, int align)
padded_height, linesizes)) < 0)
return ret;
- total_size = 4*plane_padding;
+ total_size = 4 * plane_padding + 4 * align;
for (int i = 0; i < 4; i++) {
if (sizes[i] > SIZE_MAX - total_size)
return AVERROR(EINVAL);
@@ -230,6 +230,7 @@ static int get_video_buffer(AVFrame *frame, int align)
for (int i = 1; i < 4; i++) {
if (frame->data[i])
frame->data[i] += i * plane_padding;
+ frame->data[i] = (uint8_t *)FFALIGN((uintptr_t)frame->data[i], align);
}
frame->extended_data = frame->data;
@@ -244,6 +245,7 @@ static int get_audio_buffer(AVFrame *frame, int align)
{
int planar = av_sample_fmt_is_planar(frame->format);
int channels, planes;
+ size_t size;
int ret;
channels = frame->ch_layout.nb_channels;
@@ -256,6 +258,9 @@ static int get_audio_buffer(AVFrame *frame, int align)
return ret;
}
+ if (align <= 0)
+ align = ALIGN;
+
if (planes > AV_NUM_DATA_POINTERS) {
frame->extended_data = av_calloc(planes,
sizeof(*frame->extended_data));
@@ -270,21 +275,27 @@ static int get_audio_buffer(AVFrame *frame, int align)
} else
frame->extended_data = frame->data;
+ if (frame->linesize[0] > SIZE_MAX - align)
+ return AVERROR(EINVAL);
+ size = frame->linesize[0] + (size_t)align;
+
for (int i = 0; i < FFMIN(planes, AV_NUM_DATA_POINTERS); i++) {
- frame->buf[i] = av_buffer_alloc(frame->linesize[0]);
+ frame->buf[i] = av_buffer_alloc(size);
if (!frame->buf[i]) {
av_frame_unref(frame);
return AVERROR(ENOMEM);
}
- frame->extended_data[i] = frame->data[i] = frame->buf[i]->data;
+ frame->extended_data[i] = frame->data[i] =
+ (uint8_t *)FFALIGN((uintptr_t)frame->buf[i]->data, align);
}
for (int i = 0; i < planes - AV_NUM_DATA_POINTERS; i++) {
- frame->extended_buf[i] = av_buffer_alloc(frame->linesize[0]);
+ frame->extended_buf[i] = av_buffer_alloc(size);
if (!frame->extended_buf[i]) {
av_frame_unref(frame);
return AVERROR(ENOMEM);
}
- frame->extended_data[i + AV_NUM_DATA_POINTERS] = frame->extended_buf[i]->data;
+ frame->extended_data[i + AV_NUM_DATA_POINTERS] =
+ (uint8_t *)FFALIGN((uintptr_t)frame->extended_buf[i]->data, align);
}
return 0;