From b57c1da81e4f9d46af6ad9f69e6e2255d5b8aaff Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Wed, 5 Dec 2012 02:11:22 +0000 Subject: [PATCH 1/3] arm: detect cpu features at runtime on Linux This allows compiling optimised functions for features not enabled in the core build and selecting these at runtime if the system has the necessary support. Signed-off-by: Mans Rullgard --- configure | 4 ++- libavutil/arm/cpu.c | 83 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 62f3f0ba67..bf809c6f93 100755 --- a/configure +++ b/configure @@ -3161,7 +3161,9 @@ EOF enabled vfp && check_insn vfp 'fadds s0, s0, s0' enabled vfpv3 && check_insn vfpv3 'vmov.f32 s0, #1.0' - map 'enabled_any ${v}_external ${v}_inline || disable $v' $ARCH_EXT_LIST_ARM + [ $target_os = linux ] || + map 'enabled_any ${v}_external ${v}_inline || disable $v' \ + $ARCH_EXT_LIST_ARM check_inline_asm asm_mod_q '"add r0, %Q0, %R0" :: "r"((long long)0)' check_inline_asm asm_mod_y '"vmul.i32 d0, d0, %y0" :: "x"(0)' diff --git a/libavutil/arm/cpu.c b/libavutil/arm/cpu.c index 7058aeb1f1..041afc985a 100644 --- a/libavutil/arm/cpu.c +++ b/libavutil/arm/cpu.c @@ -19,6 +19,87 @@ #include "libavutil/cpu.h" #include "config.h" +#define CORE_FLAG(f) \ + (AV_CPU_FLAG_ ## f * (HAVE_ ## f ## _EXTERNAL || HAVE_ ## f ## _INLINE)) + +#define CORE_CPU_FLAGS \ + (CORE_FLAG(ARMV5TE) | \ + CORE_FLAG(ARMV6) | \ + CORE_FLAG(ARMV6T2) | \ + CORE_FLAG(VFP) | \ + CORE_FLAG(VFPV3) | \ + CORE_FLAG(NEON)) + +#if defined __linux__ || defined __ANDROID__ + +#include +#include + +#define AT_HWCAP 16 + +/* Relevant HWCAP values from kernel headers */ +#define HWCAP_VFP (1 << 6) +#define HWCAP_EDSP (1 << 7) +#define HWCAP_THUMBEE (1 << 11) +#define HWCAP_NEON (1 << 12) +#define HWCAP_VFPv3 (1 << 13) +#define HWCAP_TLS (1 << 15) + +static int get_hwcap(uint32_t *hwcap) +{ + struct { uint32_t a_type; uint32_t a_val; } auxv; + FILE *f = fopen("/proc/self/auxv", "r"); + int err = -1; + + if (!f) + return -1; + + while (fread(&auxv, sizeof(auxv), 1, f) > 0) { + if (auxv.a_type == AT_HWCAP) { + *hwcap = auxv.a_val; + err = 0; + break; + } + } + + fclose(f); + return err; +} + +int ff_get_cpu_flags_arm(void) +{ + int flags = CORE_CPU_FLAGS; + uint32_t hwcap; + + if (get_hwcap(&hwcap) < 0) + return flags; + +#define check_cap(cap, flag) do { \ + if (hwcap & HWCAP_ ## cap) \ + flags |= AV_CPU_FLAG_ ## flag; \ + } while (0) + + /* No flags explicitly indicate v6 or v6T2 so check others which + imply support. */ + check_cap(EDSP, ARMV5TE); + check_cap(TLS, ARMV6); + check_cap(THUMBEE, ARMV6T2); + check_cap(VFP, VFP); + check_cap(VFPv3, VFPV3); + check_cap(NEON, NEON); + + /* The v6 checks above are not reliable so let higher flags + trickle down. */ + if (flags & (AV_CPU_FLAG_VFPV3 | AV_CPU_FLAG_NEON)) + flags |= AV_CPU_FLAG_ARMV6T2; + if (flags & AV_CPU_FLAG_ARMV6T2) + flags |= AV_CPU_FLAG_ARMV6; + + return flags; +} + +#else + int ff_get_cpu_flags_arm(void) { return AV_CPU_FLAG_ARMV5TE * HAVE_ARMV5TE | @@ -28,3 +109,5 @@ int ff_get_cpu_flags_arm(void) AV_CPU_FLAG_VFPV3 * HAVE_VFPV3 | AV_CPU_FLAG_NEON * HAVE_NEON; } + +#endif From 41540b36a19d326e778268e910aff4217b20eb97 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 30 Sep 2012 02:39:55 +0200 Subject: [PATCH 2/3] bitstream: add get_bits64() to support reading more than 32 bits at once Also remove a duplicate function in the MPEG-TS demuxer. Signed-off-by: Michael Niedermayer Signed-off-by: Justin Ruggles --- libavcodec/get_bits.h | 18 ++++++++++++++++++ libavformat/mpegts.c | 13 ------------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/libavcodec/get_bits.h b/libavcodec/get_bits.h index f91441c120..c56a2c2d10 100644 --- a/libavcodec/get_bits.h +++ b/libavcodec/get_bits.h @@ -313,6 +313,24 @@ static inline unsigned int get_bits_long(GetBitContext *s, int n) } } +/* + * Read 0-64 bits. + */ +static inline uint64_t get_bits64(GetBitContext *s, int n) +{ + if (n <= 32) { + return get_bits_long(s, n); + } else { +#ifdef BITSTREAM_READER_LE + uint64_t ret = get_bits_long(s, 32); + return ret | (uint64_t)get_bits_long(s, n - 32) << 32; +#else + uint64_t ret = (uint64_t)get_bits_long(s, n - 32) << 32; + return ret | get_bits_long(s, 32); +#endif + } +} + /** * Read 0-32 bits as a signed integer. */ diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index 4aabcd7e60..7c4d447ddc 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -665,19 +665,6 @@ static void new_pes_packet(PESContext *pes, AVPacket *pkt) pes->flags = 0; } -static uint64_t get_bits64(GetBitContext *gb, int bits) -{ - uint64_t ret = 0; - while (bits > 17) { - ret <<= 17; - ret |= get_bits(gb, 17); - bits -= 17; - } - ret <<= bits; - ret |= get_bits(gb, bits); - return ret; -} - static int read_sl_header(PESContext *pes, SLConfigDescr *sl, const uint8_t *buf, int buf_size) { GetBitContext gb; From 096abfa15052977eed93f0b5e01afd2d47c53c1f Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 3 Oct 2012 16:06:23 +0200 Subject: [PATCH 3/3] parser: fix large overreads Signed-off-by: Michael Niedermayer Signed-off-by: Justin Ruggles --- libavcodec/parser.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libavcodec/parser.c b/libavcodec/parser.c index 7ace766eb9..0767a34959 100644 --- a/libavcodec/parser.c +++ b/libavcodec/parser.c @@ -254,7 +254,9 @@ int ff_combine_frame(ParseContext *pc, int next, const uint8_t **buf, int *buf_s if(!new_buffer) return AVERROR(ENOMEM); pc->buffer = new_buffer; - memcpy(&pc->buffer[pc->index], *buf, next + FF_INPUT_BUFFER_PADDING_SIZE ); + if (next > -FF_INPUT_BUFFER_PADDING_SIZE) + memcpy(&pc->buffer[pc->index], *buf, + next + FF_INPUT_BUFFER_PADDING_SIZE); pc->index = 0; *buf= pc->buffer; }