[FFmpeg-devel] [PATCH v4] avcodec/h264_mb: Fix tmp buffer overlap

Bin Peng pengbin at visionular.com
Tue Dec 24 09:49:49 EET 2024


When decoding a bitstream with weighted-bipred enabled,
the results on ARM and x86 platforms may differ.

The reason for the inconsistency is that the value of
STRIDE_ALIGN differs between platforms. And STRIDE_ALIGN
is set to the buffer stride of temporary buffers for U
and V components in mc_part_weighted.

If the buffer stride is 32 or 64 (as on x86 platforms),
the U and V pixels can be interleaved row by row without
overlapping, resulting in correct output.
However, on ARM platforms where the stride is 16,
the V component will overwrite part of the U component's pixels,
leading to incorrect predicted pixels.

Fixes: ticket 11357

Signed-off-by: Bin Peng <pengbin at visionular.com>
---
 libavcodec/utils.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 2dbd677920..d280e1c324 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -147,6 +147,7 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height,
     int i;
     int w_align = 1;
     int h_align = 1;
+    int stride_align = STRIDE_ALIGN;
     AVPixFmtDescriptor const *desc = av_pix_fmt_desc_get(s->pix_fmt);
 
     if (desc) {
@@ -342,13 +343,14 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height,
         // increasing witdth ensure that the temporary area is large enough,
         // the next rounded up width is 32
         *width = FFMAX(*width, 32);
+        stride_align = FFMAX(stride_align, 32);
     }
     if (s->codec_id == AV_CODEC_ID_SVQ3) {
         *width = FFMAX(*width, 32);
     }
 
     for (i = 0; i < 4; i++)
-        linesize_align[i] = STRIDE_ALIGN;
+        linesize_align[i] = stride_align;
 }
 
 void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height)
-- 
2.25.1



More information about the ffmpeg-devel mailing list