aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2012-12-08 14:58:56 +0100
committerMichael Niedermayer <michaelni@gmx.at>2012-12-08 14:58:56 +0100
commit57cee850238488a6088085ae078af17f04f2198a (patch)
tree9551a690983609d59e91e3c63ae4b15114eecb34
parent7efee140d7d6fe197a73a178314eacd330a8cc77 (diff)
parent096abfa15052977eed93f0b5e01afd2d47c53c1f (diff)
downloadffmpeg-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-xconfigure4
-rw-r--r--libavcodec/get_bits.h10
-rw-r--r--libavcodec/parser.c5
-rw-r--r--libavformat/mpegts.c11
-rw-r--r--libavutil/arm/cpu.c83
5 files changed, 95 insertions, 18 deletions
diff --git a/configure b/configure
index 63e6ccc466..48bfed279f 100755
--- a/configure
+++ b/configure
@@ -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