* 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>tags/n1.1
| @@ -3497,7 +3497,9 @@ EOF | |||||
| enabled vfp && check_insn vfp 'fadds s0, s0, s0' | enabled vfp && check_insn vfp 'fadds s0, s0, s0' | ||||
| enabled vfpv3 && check_insn vfpv3 'vmov.f32 s0, #1.0' | 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_q '"add r0, %Q0, %R0" :: "r"((long long)0)' | ||||
| check_inline_asm asm_mod_y '"vmul.i32 d0, d0, %y0" :: "x"(0)' | check_inline_asm asm_mod_y '"vmul.i32 d0, d0, %y0" :: "x"(0)' | ||||
| @@ -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) | static inline uint64_t get_bits64(GetBitContext *s, int n) | ||||
| { | { | ||||
| if (n <= 32) | |||||
| if (n <= 32) { | |||||
| return get_bits_long(s, n); | return get_bits_long(s, n); | ||||
| else { | |||||
| } else { | |||||
| #ifdef BITSTREAM_READER_LE | #ifdef BITSTREAM_READER_LE | ||||
| uint64_t ret = get_bits_long(s, 32); | 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 | #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 | #endif | ||||
| } | } | ||||
| } | } | ||||
| @@ -253,8 +253,9 @@ int ff_combine_frame(ParseContext *pc, int next, const uint8_t **buf, int *buf_s | |||||
| if(!new_buffer) | if(!new_buffer) | ||||
| return AVERROR(ENOMEM); | return AVERROR(ENOMEM); | ||||
| pc->buffer = new_buffer; | 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; | pc->index = 0; | ||||
| *buf= pc->buffer; | *buf= pc->buffer; | ||||
| } | } | ||||
| @@ -714,18 +714,9 @@ static void new_pes_packet(PESContext *pes, AVPacket *pkt) | |||||
| static uint64_t get_ts64(GetBitContext *gb, int bits) | static uint64_t get_ts64(GetBitContext *gb, int bits) | ||||
| { | { | ||||
| uint64_t ret = 0; | |||||
| if (get_bits_left(gb) < bits) | if (get_bits_left(gb) < bits) | ||||
| return AV_NOPTS_VALUE; | 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) | static int read_sl_header(PESContext *pes, SLConfigDescr *sl, const uint8_t *buf, int buf_size) | ||||
| @@ -19,6 +19,87 @@ | |||||
| #include "libavutil/cpu.h" | #include "libavutil/cpu.h" | ||||
| #include "config.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) | int ff_get_cpu_flags_arm(void) | ||||
| { | { | ||||
| return AV_CPU_FLAG_ARMV5TE * HAVE_ARMV5TE | | 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_VFPV3 * HAVE_VFPV3 | | ||||
| AV_CPU_FLAG_NEON * HAVE_NEON; | AV_CPU_FLAG_NEON * HAVE_NEON; | ||||
| } | } | ||||
| #endif | |||||