[FFmpeg-devel] [PATCH] lavu/get_video_buffer: also align data pointers (v3)

Pavel Koshevoy pkoshevoy at gmail.com
Sat Nov 16 17:51:52 EET 2024


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.
---
 doc/APIchanges      | 4 ++++
 libavutil/frame.c   | 4 +++-
 libavutil/frame.h   | 7 ++++---
 libavutil/version.h | 2 +-
 4 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/doc/APIchanges b/doc/APIchanges
index 15606cafac..45528fad7d 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -2,6 +2,10 @@ The last version increases of all libraries were on 2024-03-07
 
 API changes, most recent first:
 
+2024-11-16 - xxxxxxxxxx - lavu 59.47.101 - frame.h
+  Make get_video_buffer (called by av_frame_get_buffer) also align the
+  data pointers according to the specified alignment.
+
 2024-11-13 - xxxxxxxxxx - lavu 59.47.100 - channel_layout.h
   Add AV_CHAN_BINAURAL_LEFT, AV_CHAN_BINAURAL_RIGHT
   Add AV_CH_BINAURAL_LEFT, AV_CH_BINAURAL_RIGHT
diff --git a/libavutil/frame.c b/libavutil/frame.c
index f0a0dba018..7faf7aeae8 100644
--- a/libavutil/frame.c
+++ b/libavutil/frame.c
@@ -216,6 +216,7 @@ static int get_video_buffer(AVFrame *frame, int align)
         total_size += sizes[i];
     }
 
+    total_size += align - 1;
     frame->buf[0] = av_buffer_alloc(total_size);
     if (!frame->buf[0]) {
         ret = AVERROR(ENOMEM);
@@ -223,7 +224,8 @@ static int get_video_buffer(AVFrame *frame, int align)
     }
 
     if ((ret = av_image_fill_pointers(frame->data, frame->format, padded_height,
-                                      frame->buf[0]->data, frame->linesize)) < 0)
+                                      (uint8_t *)FFALIGN((uintptr_t)frame->buf[0]->data, align),
+                                      frame->linesize)) < 0)
         goto fail;
 
     for (int i = 1; i < 4; i++) {
diff --git a/libavutil/frame.h b/libavutil/frame.h
index f7806566d5..c107f43bc0 100644
--- a/libavutil/frame.h
+++ b/libavutil/frame.h
@@ -887,9 +887,10 @@ void av_frame_move_ref(AVFrame *dst, AVFrame *src);
  *           cases.
  *
  * @param frame frame in which to store the new buffers.
- * @param align Required buffer size alignment. If equal to 0, alignment will be
- *              chosen automatically for the current CPU. It is highly
- *              recommended to pass 0 here unless you know what you are doing.
+ * @param align Required buffer size and data pointer alignment. If equal to 0,
+ *              alignment will be chosen automatically for the current CPU.
+ *              It is highly recommended to pass 0 here unless you know what
+ *              you are doing.
  *
  * @return 0 on success, a negative AVERROR on error.
  */
diff --git a/libavutil/version.h b/libavutil/version.h
index c1878a49ad..6a4abcf7f5 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -80,7 +80,7 @@
 
 #define LIBAVUTIL_VERSION_MAJOR  59
 #define LIBAVUTIL_VERSION_MINOR  47
-#define LIBAVUTIL_VERSION_MICRO 100
+#define LIBAVUTIL_VERSION_MICRO 101
 
 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
                                                LIBAVUTIL_VERSION_MINOR, \
-- 
2.43.0



More information about the ffmpeg-devel mailing list