diff --git a/libavcodec/arm/dcadsp_init_arm.c b/libavcodec/arm/dcadsp_init_arm.c index a54951584f..40ad78745c 100644 --- a/libavcodec/arm/dcadsp_init_arm.c +++ b/libavcodec/arm/dcadsp_init_arm.c @@ -59,7 +59,7 @@ av_cold void ff_dcadsp_init_arm(DCADSPContext *s) { int cpu_flags = av_get_cpu_flags(); - if (have_vfp(cpu_flags) && !have_vfpv3(cpu_flags)) { + if (have_vfp_vm(cpu_flags)) { s->lfe_fir[0] = ff_dca_lfe_fir32_vfp; s->lfe_fir[1] = ff_dca_lfe_fir64_vfp; s->qmf_32_subbands = ff_dca_qmf_32_subbands_vfp; @@ -75,7 +75,7 @@ av_cold void ff_synth_filter_init_arm(SynthFilterContext *s) { int cpu_flags = av_get_cpu_flags(); - if (have_vfp(cpu_flags) && !have_vfpv3(cpu_flags)) + if (have_vfp_vm(cpu_flags)) s->synth_filter_float = ff_synth_filter_float_vfp; if (have_neon(cpu_flags)) s->synth_filter_float = ff_synth_filter_float_neon; diff --git a/libavcodec/arm/fft_init_arm.c b/libavcodec/arm/fft_init_arm.c index 5087f5f64d..055c2c1cb2 100644 --- a/libavcodec/arm/fft_init_arm.c +++ b/libavcodec/arm/fft_init_arm.c @@ -40,7 +40,7 @@ av_cold void ff_fft_init_arm(FFTContext *s) { int cpu_flags = av_get_cpu_flags(); - if (have_vfp(cpu_flags) && !have_vfpv3(cpu_flags)) { + if (have_vfp_vm(cpu_flags)) { s->fft_calc = ff_fft_calc_vfp; #if CONFIG_MDCT s->imdct_half = ff_imdct_half_vfp; diff --git a/libavcodec/arm/fmtconvert_init_arm.c b/libavcodec/arm/fmtconvert_init_arm.c index 58589c46ef..69b75bb274 100644 --- a/libavcodec/arm/fmtconvert_init_arm.c +++ b/libavcodec/arm/fmtconvert_init_arm.c @@ -38,7 +38,7 @@ av_cold void ff_fmt_convert_init_arm(FmtConvertContext *c, AVCodecContext *avctx { int cpu_flags = av_get_cpu_flags(); - if (have_vfp(cpu_flags)) { + if (have_vfp_vm(cpu_flags)) { if (!have_vfpv3(cpu_flags)) { c->int32_to_float_fmul_scalar = ff_int32_to_float_fmul_scalar_vfp; c->int32_to_float_fmul_array8 = ff_int32_to_float_fmul_array8_vfp; diff --git a/libavutil/arm/cpu.c b/libavutil/arm/cpu.c index 02def0b470..3889ef011c 100644 --- a/libavutil/arm/cpu.c +++ b/libavutil/arm/cpu.c @@ -137,6 +137,10 @@ int ff_get_cpu_flags_arm(void) if (flags & AV_CPU_FLAG_ARMV6T2) flags |= AV_CPU_FLAG_ARMV6; + /* set the virtual VFPv2 vector mode flag */ + if ((flags & AV_CPU_FLAG_VFP) && !(flags & (AV_CPU_FLAG_VFPV3 | AV_CPU_FLAG_NEON))) + flags |= AV_CPU_FLAG_VFP_VM; + return flags; } diff --git a/libavutil/arm/cpu.h b/libavutil/arm/cpu.h index 9b3b6ff58b..27a2edacf5 100644 --- a/libavutil/arm/cpu.h +++ b/libavutil/arm/cpu.h @@ -31,4 +31,9 @@ #define have_neon(flags) CPUEXT(flags, NEON) #define have_setend(flags) CPUEXT(flags, SETEND) +/* some functions use the VFPv2 vector mode which is deprecated in ARMv7-A + * and might trap on such CPU depending on the OS configuration */ +#define have_vfp_vm(flags) \ + (have_armv6(flags) && ((flags) & AV_CPU_FLAG_VFP_VM)) + #endif /* AVUTIL_ARM_CPU_H */ diff --git a/libavutil/cpu.c b/libavutil/cpu.c index 1acae013ca..89066d8e2a 100644 --- a/libavutil/cpu.c +++ b/libavutil/cpu.c @@ -152,6 +152,7 @@ int av_parse_cpu_flags(const char *s) { "armv6", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV6 }, .unit = "flags" }, { "armv6t2", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV6T2 }, .unit = "flags" }, { "vfp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFP }, .unit = "flags" }, + { "vfp_vm", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFP_VM }, .unit = "flags" }, { "vfpv3", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFPV3 }, .unit = "flags" }, { "neon", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_NEON }, .unit = "flags" }, #elif ARCH_AARCH64 @@ -315,6 +316,7 @@ static const struct { { AV_CPU_FLAG_ARMV6, "armv6" }, { AV_CPU_FLAG_ARMV6T2, "armv6t2" }, { AV_CPU_FLAG_VFP, "vfp" }, + { AV_CPU_FLAG_VFP_VM, "vfp_vm" }, { AV_CPU_FLAG_VFPV3, "vfpv3" }, { AV_CPU_FLAG_NEON, "neon" }, { AV_CPU_FLAG_SETEND, "setend" }, diff --git a/libavutil/cpu.h b/libavutil/cpu.h index bff8518cc5..cc4e30c4cd 100644 --- a/libavutil/cpu.h +++ b/libavutil/cpu.h @@ -64,6 +64,7 @@ #define AV_CPU_FLAG_VFPV3 (1 << 4) #define AV_CPU_FLAG_NEON (1 << 5) #define AV_CPU_FLAG_ARMV8 (1 << 6) +#define AV_CPU_FLAG_VFP_VM (1 << 7) ///< VFPv2 vector mode, deprecated in ARMv7-A and unavailable in various CPUs implementations #define AV_CPU_FLAG_SETEND (1 <<16) /** diff --git a/libavutil/version.h b/libavutil/version.h index 22cd66b554..9ffa7a8666 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -64,7 +64,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 55 -#define LIBAVUTIL_VERSION_MINOR 11 +#define LIBAVUTIL_VERSION_MINOR 12 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ diff --git a/tests/checkasm/checkasm.c b/tests/checkasm/checkasm.c index 3548bb33b5..ba7a83cae2 100644 --- a/tests/checkasm/checkasm.c +++ b/tests/checkasm/checkasm.c @@ -103,6 +103,7 @@ static const struct { { "ARMV6", "armv6", AV_CPU_FLAG_ARMV6 }, { "ARMV6T2", "armv6t2", AV_CPU_FLAG_ARMV6T2 }, { "VFP", "vfp", AV_CPU_FLAG_VFP }, + { "VFP_VM", "vfp_vm", AV_CPU_FLAG_VFP_VM }, { "VFPV3", "vfp3", AV_CPU_FLAG_VFPV3 }, { "NEON", "neon", AV_CPU_FLAG_NEON }, #elif ARCH_PPC