1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2025-08-04 22:03:09 +02:00

avcodec/h264_mb: Fix tmp_cr for arm

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 did overwrite part of the U component's pixels,
leading to incorrect predicted pixels.

The bug can be reproduced by the following bitstream.

https://trac.ffmpeg.org/attachment/ticket/11357/inter_weighted_bipred2.264

Fixes: ticket 11357
Commit-msg-mostly-by: Bin Peng <pengbin@visionular.com>
Reviewed-by: Bin Peng <pengbin@visionular.com>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
This commit is contained in:
Michael Niedermayer
2025-04-16 02:25:00 +02:00
parent fd5a3c5fed
commit 74fd2c3ddb

View File

@ -407,7 +407,7 @@ static av_always_inline void mc_part_weighted(const H264Context *h, H264SliceCon
/* don't optimize for luma-only case, since B-frames usually /* don't optimize for luma-only case, since B-frames usually
* use implicit weights => chroma too. */ * use implicit weights => chroma too. */
uint8_t *tmp_cb = sl->bipred_scratchpad; uint8_t *tmp_cb = sl->bipred_scratchpad;
uint8_t *tmp_cr = sl->bipred_scratchpad + (16 << pixel_shift); uint8_t *tmp_cr = sl->bipred_scratchpad + (8 << pixel_shift + (chroma_idc == 3));
uint8_t *tmp_y = sl->bipred_scratchpad + 16 * sl->mb_uvlinesize; uint8_t *tmp_y = sl->bipred_scratchpad + 16 * sl->mb_uvlinesize;
int refn0 = sl->ref_cache[0][scan8[n]]; int refn0 = sl->ref_cache[0][scan8[n]];
int refn1 = sl->ref_cache[1][scan8[n]]; int refn1 = sl->ref_cache[1][scan8[n]];