summaryrefslogtreecommitdiffstats
path: root/libavcodec
diff options
context:
space:
mode:
authorPeter Ross <pross@xvid.org>2019-06-21 07:52:31 +1000
committerMichael Niedermayer <michael@niedermayer.cc>2019-10-30 10:06:38 +0100
commitfd172185580c1ccdcfb90bbfdb59fa806fad3117 (patch)
tree97743b09c37d6cecc1f231e31800fcbe1eb80d15 /libavcodec
parentd3dee676b8a8ab6752c599e25c9b5461f06a3959 (diff)
downloadffmpeg-streaming-fd172185580c1ccdcfb90bbfdb59fa806fad3117.zip
ffmpeg-streaming-fd172185580c1ccdcfb90bbfdb59fa806fad3117.tar.gz
vp4: prevent unaligned memory access in loop filter
VP4 applies a loop filter during motion compensation, causing the block offset will often by unaligned. This produces a bus error on some platforms, namely ARMv7 NEON. This patch adds a unaligned version of the loop filter function pointer to VP3DSPContext. Reported-by: Mike Melanson <mike@multimedia.cx> Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/vp3.c10
-rw-r--r--libavcodec/vp3dsp.c4
-rw-r--r--libavcodec/vp3dsp.h2
-rw-r--r--libavcodec/x86/vp3dsp_init.c4
4 files changed, 14 insertions, 6 deletions
diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c
index a2bd2ef..9a3821a 100644
--- a/libavcodec/vp3.c
+++ b/libavcodec/vp3.c
@@ -2031,11 +2031,17 @@ static int vp4_mc_loop_filter(Vp3DecodeContext *s, int plane, int motion_x, int
plane_width,
plane_height);
+#define safe_loop_filter(name, ptr, stride, bounding_values) \
+ if ((uintptr_t)(ptr) & 7) \
+ s->vp3dsp.name##_unaligned(ptr, stride, bounding_values); \
+ else \
+ s->vp3dsp.name(ptr, stride, bounding_values);
+
if (x_offset)
- s->vp3dsp.h_loop_filter(loop + loop_stride + x_offset + 1, loop_stride, bounding_values);
+ safe_loop_filter(h_loop_filter, loop + loop_stride + x_offset + 1, loop_stride, bounding_values);
if (y_offset)
- s->vp3dsp.v_loop_filter(loop + (y_offset + 1)*loop_stride + 1, loop_stride, bounding_values);
+ safe_loop_filter(v_loop_filter, loop + (y_offset + 1)*loop_stride + 1, loop_stride, bounding_values);
}
for (i = 0; i < 9; i++)
diff --git a/libavcodec/vp3dsp.c b/libavcodec/vp3dsp.c
index ac4c574..f485fba 100644
--- a/libavcodec/vp3dsp.c
+++ b/libavcodec/vp3dsp.c
@@ -449,8 +449,8 @@ av_cold void ff_vp3dsp_init(VP3DSPContext *c, int flags)
c->idct_put = vp3_idct_put_c;
c->idct_add = vp3_idct_add_c;
c->idct_dc_add = vp3_idct_dc_add_c;
- c->v_loop_filter = vp3_v_loop_filter_8_c;
- c->h_loop_filter = vp3_h_loop_filter_8_c;
+ c->v_loop_filter = c->v_loop_filter_unaligned = vp3_v_loop_filter_8_c;
+ c->h_loop_filter = c->h_loop_filter_unaligned = vp3_h_loop_filter_8_c;
if (ARCH_ARM)
ff_vp3dsp_init_arm(c, flags);
diff --git a/libavcodec/vp3dsp.h b/libavcodec/vp3dsp.h
index 32b2cad0..3b849ec 100644
--- a/libavcodec/vp3dsp.h
+++ b/libavcodec/vp3dsp.h
@@ -43,6 +43,8 @@ typedef struct VP3DSPContext {
void (*idct_dc_add)(uint8_t *dest, ptrdiff_t stride, int16_t *block);
void (*v_loop_filter)(uint8_t *src, ptrdiff_t stride, int *bounding_values);
void (*h_loop_filter)(uint8_t *src, ptrdiff_t stride, int *bounding_values);
+ void (*v_loop_filter_unaligned)(uint8_t *src, ptrdiff_t stride, int *bounding_values);
+ void (*h_loop_filter_unaligned)(uint8_t *src, ptrdiff_t stride, int *bounding_values);
} VP3DSPContext;
void ff_vp3dsp_v_loop_filter_12(uint8_t *first_pixel, ptrdiff_t stride, int *bounding_values);
diff --git a/libavcodec/x86/vp3dsp_init.c b/libavcodec/x86/vp3dsp_init.c
index 1ba9576..ba47e1c 100644
--- a/libavcodec/x86/vp3dsp_init.c
+++ b/libavcodec/x86/vp3dsp_init.c
@@ -59,8 +59,8 @@ av_cold void ff_vp3dsp_init_x86(VP3DSPContext *c, int flags)
c->idct_dc_add = ff_vp3_idct_dc_add_mmxext;
if (!(flags & AV_CODEC_FLAG_BITEXACT)) {
- c->v_loop_filter = ff_vp3_v_loop_filter_mmxext;
- c->h_loop_filter = ff_vp3_h_loop_filter_mmxext;
+ c->v_loop_filter = c->v_loop_filter_unaligned = ff_vp3_v_loop_filter_mmxext;
+ c->h_loop_filter = c->v_loop_filter_unaligned = ff_vp3_h_loop_filter_mmxext;
}
}
OpenPOWER on IntegriCloud