From 079849f40c52de33941c2776e8c971954b298b48 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 19 Aug 2017 23:38:58 +0200 Subject: [PATCH] avcodec/me_cmp: Fix crashes on ARM due to misalignment Adds a diff_pixels_unaligned() Fixes: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=872503 Signed-off-by: Michael Niedermayer (cherry picked from commit bc488ec28aec4bc91ba47283c49c9f7f25696eaa) Signed-off-by: Michael Niedermayer --- libavcodec/me_cmp.c | 10 +++++----- libavcodec/pixblockdsp.c | 1 + libavcodec/pixblockdsp.h | 5 +++++ libavcodec/x86/pixblockdsp_init.c | 2 ++ 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/libavcodec/me_cmp.c b/libavcodec/me_cmp.c index dc76b07ba2..4234000487 100644 --- a/libavcodec/me_cmp.c +++ b/libavcodec/me_cmp.c @@ -555,7 +555,7 @@ static int dct_sad8x8_c(MpegEncContext *s, uint8_t *src1, av_assert2(h == 8); - s->pdsp.diff_pixels(temp, src1, src2, stride); + s->pdsp.diff_pixels_unaligned(temp, src1, src2, stride); s->fdsp.fdct(temp); return s->mecc.sum_abs_dctelem(temp); } @@ -595,7 +595,7 @@ static int dct264_sad8x8_c(MpegEncContext *s, uint8_t *src1, int16_t dct[8][8]; int i, sum = 0; - s->pdsp.diff_pixels(dct[0], src1, src2, stride); + s->pdsp.diff_pixels_unaligned(dct[0], src1, src2, stride); #define SRC(x) dct[i][x] #define DST(x, v) dct[i][x] = v @@ -622,7 +622,7 @@ static int dct_max8x8_c(MpegEncContext *s, uint8_t *src1, av_assert2(h == 8); - s->pdsp.diff_pixels(temp, src1, src2, stride); + s->pdsp.diff_pixels_unaligned(temp, src1, src2, stride); s->fdsp.fdct(temp); for (i = 0; i < 64; i++) @@ -641,7 +641,7 @@ static int quant_psnr8x8_c(MpegEncContext *s, uint8_t *src1, av_assert2(h == 8); s->mb_intra = 0; - s->pdsp.diff_pixels(temp, src1, src2, stride); + s->pdsp.diff_pixels_unaligned(temp, src1, src2, stride); memcpy(bak, temp, 64 * sizeof(int16_t)); @@ -744,7 +744,7 @@ static int bit8x8_c(MpegEncContext *s, uint8_t *src1, uint8_t *src2, av_assert2(h == 8); - s->pdsp.diff_pixels(temp, src1, src2, stride); + s->pdsp.diff_pixels_unaligned(temp, src1, src2, stride); s->block_last_index[0 /* FIXME */] = last = diff --git a/libavcodec/pixblockdsp.c b/libavcodec/pixblockdsp.c index 322e1dd111..a681674579 100644 --- a/libavcodec/pixblockdsp.c +++ b/libavcodec/pixblockdsp.c @@ -55,6 +55,7 @@ av_cold void ff_pixblockdsp_init(PixblockDSPContext *c, AVCodecContext *avctx) { const unsigned high_bit_depth = avctx->bits_per_raw_sample > 8; + c->diff_pixels_unaligned = c->diff_pixels = diff_pixels_c; switch (avctx->bits_per_raw_sample) { diff --git a/libavcodec/pixblockdsp.h b/libavcodec/pixblockdsp.h index 79ed86c3a6..b14514de7e 100644 --- a/libavcodec/pixblockdsp.h +++ b/libavcodec/pixblockdsp.h @@ -31,6 +31,11 @@ typedef struct PixblockDSPContext { const uint8_t *s1 /* align 8 */, const uint8_t *s2 /* align 8 */, int stride); + void (*diff_pixels_unaligned)(int16_t *av_restrict block /* align 16 */, + const uint8_t *s1, + const uint8_t *s2, + int stride); + } PixblockDSPContext; void ff_pixblockdsp_init(PixblockDSPContext *c, AVCodecContext *avctx); diff --git a/libavcodec/x86/pixblockdsp_init.c b/libavcodec/x86/pixblockdsp_init.c index 4d06a44c6d..b9027dee54 100644 --- a/libavcodec/x86/pixblockdsp_init.c +++ b/libavcodec/x86/pixblockdsp_init.c @@ -39,12 +39,14 @@ av_cold void ff_pixblockdsp_init_x86(PixblockDSPContext *c, if (EXTERNAL_MMX(cpu_flags)) { if (!high_bit_depth) c->get_pixels = ff_get_pixels_mmx; + c->diff_pixels_unaligned = c->diff_pixels = ff_diff_pixels_mmx; } if (EXTERNAL_SSE2(cpu_flags)) { if (!high_bit_depth) c->get_pixels = ff_get_pixels_sse2; + c->diff_pixels_unaligned = c->diff_pixels = ff_diff_pixels_sse2; } }