diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-12-08 14:58:56 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-12-08 14:58:56 +0100 |
commit | 57cee850238488a6088085ae078af17f04f2198a (patch) | |
tree | 9551a690983609d59e91e3c63ae4b15114eecb34 | |
parent | 7efee140d7d6fe197a73a178314eacd330a8cc77 (diff) | |
parent | 096abfa15052977eed93f0b5e01afd2d47c53c1f (diff) | |
download | ffmpeg-57cee850238488a6088085ae078af17f04f2198a.tar.gz |
Merge commit '096abfa15052977eed93f0b5e01afd2d47c53c1f'
* commit '096abfa15052977eed93f0b5e01afd2d47c53c1f':
parser: fix large overreads
bitstream: add get_bits64() to support reading more than 32 bits at once
arm: detect cpu features at runtime on Linux
Conflicts:
libavcodec/parser.c
libavformat/mpegts.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
-rwxr-xr-x | configure | 4 | ||||
-rw-r--r-- | libavcodec/get_bits.h | 10 | ||||
-rw-r--r-- | libavcodec/parser.c | 5 | ||||
-rw-r--r-- | libavformat/mpegts.c | 11 | ||||
-rw-r--r-- | libavutil/arm/cpu.c | 83 |
5 files changed, 95 insertions, 18 deletions
@@ -3497,7 +3497,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/libavcodec/get_bits.h b/libavcodec/get_bits.h index 965d69c061..777176dd30 100644 --- a/libavcodec/get_bits.h +++ b/libavcodec/get_bits.h @@ -322,15 +322,15 @@ static inline unsigned int get_bits_long(GetBitContext *s, int n) */ static inline uint64_t get_bits64(GetBitContext *s, int n) { - if (n <= 32) + if (n <= 32) { return get_bits_long(s, n); - else { + } else { #ifdef BITSTREAM_READER_LE uint64_t ret = get_bits_long(s, 32); - return ret | (((uint64_t)get_bits_long(s, n-32)) << 32); + return ret | (uint64_t)get_bits_long(s, n - 32) << 32; #else - uint64_t ret = ((uint64_t)get_bits_long(s, 32)) << (n-32); - return ret | get_bits_long(s, n-32); + uint64_t ret = (uint64_t)get_bits_long(s, n - 32) << 32; + return ret | get_bits_long(s, 32); #endif } } diff --git a/libavcodec/parser.c b/libavcodec/parser.c index 2e204e2c2a..3b4715035a 100644 --- a/libavcodec/parser.c +++ b/libavcodec/parser.c @@ -253,8 +253,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; - if(FF_INPUT_BUFFER_PADDING_SIZE > -next) - 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; } diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index 167194c808..788a59b316 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -714,18 +714,9 @@ static void new_pes_packet(PESContext *pes, AVPacket *pkt) static uint64_t get_ts64(GetBitContext *gb, int bits) { - uint64_t ret = 0; - if (get_bits_left(gb) < bits) return AV_NOPTS_VALUE; - while (bits > 17) { - ret <<= 17; - ret |= get_bits(gb, 17); - bits -= 17; - } - ret <<= bits; - ret |= get_bits(gb, bits); - return ret; + return get_bits64(gb, bits); } static int read_sl_header(PESContext *pes, SLConfigDescr *sl, const uint8_t *buf, int buf_size) 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 <stdint.h> +#include <stdio.h> + +#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 |