From b82b49a5b774b6ad9119e981c72b8f594fee2ae0 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Sat, 5 May 2012 23:24:51 +0100 Subject: mips: intreadwrite: remove unnecessary inline asm GCC actually handles unaligned accesses correctly in all cases except, absurdly, 32-bit loads on mips64. The remaining asm is thus not needed, and removing it results in better code. Signed-off-by: Mans Rullgard --- libavutil/mips/intreadwrite.h | 59 ++----------------------------------------- 1 file changed, 2 insertions(+), 57 deletions(-) (limited to 'libavutil') diff --git a/libavutil/mips/intreadwrite.h b/libavutil/mips/intreadwrite.h index 0e0cc065a9..d0c558fb81 100644 --- a/libavutil/mips/intreadwrite.h +++ b/libavutil/mips/intreadwrite.h @@ -24,7 +24,7 @@ #include #include "config.h" -#if HAVE_INLINE_ASM +#if ARCH_MIPS64 && HAVE_INLINE_ASM #define AV_RN32 AV_RN32 static av_always_inline uint32_t AV_RN32(const void *p) @@ -38,61 +38,6 @@ static av_always_inline uint32_t AV_RN32(const void *p) return v; } -#define AV_WN32 AV_WN32 -static av_always_inline void AV_WN32(void *p, uint32_t v) -{ - __asm__ ("swl %2, %0 \n\t" - "swr %2, %1 \n\t" - : "=m"(*(uint32_t *)((uint8_t *)p+3*!HAVE_BIGENDIAN)), - "=m"(*(uint32_t *)((uint8_t *)p+3*HAVE_BIGENDIAN)) - : "r"(v)); -} - -#if ARCH_MIPS64 - -#define AV_RN64 AV_RN64 -static av_always_inline uint64_t AV_RN64(const void *p) -{ - uint64_t v; - __asm__ ("ldl %0, %1 \n\t" - "ldr %0, %2 \n\t" - : "=&r"(v) - : "m"(*(const uint64_t *)((const uint8_t *)p+7*!HAVE_BIGENDIAN)), - "m"(*(const uint64_t *)((const uint8_t *)p+7*HAVE_BIGENDIAN))); - return v; -} - -#define AV_WN64 AV_WN64 -static av_always_inline void AV_WN64(void *p, uint64_t v) -{ - __asm__ ("sdl %2, %0 \n\t" - "sdr %2, %1 \n\t" - : "=m"(*(uint64_t *)((uint8_t *)p+7*!HAVE_BIGENDIAN)), - "=m"(*(uint64_t *)((uint8_t *)p+7*HAVE_BIGENDIAN)) - : "r"(v)); -} - -#else - -#define AV_RN64 AV_RN64 -static av_always_inline uint64_t AV_RN64(const void *p) -{ - union { uint64_t v; uint32_t hl[2]; } v; - v.hl[0] = AV_RN32(p); - v.hl[1] = AV_RN32((const uint8_t *)p + 4); - return v.v; -} - -#define AV_WN64 AV_WN64 -static av_always_inline void AV_WN64(void *p, uint64_t v) -{ - union { uint64_t v; uint32_t hl[2]; } vv = { v }; - AV_WN32(p, vv.hl[0]); - AV_WN32((uint8_t *)p + 4, vv.hl[1]); -} - -#endif /* ARCH_MIPS64 */ - -#endif /* HAVE_INLINE_ASM */ +#endif /* ARCH_MIPS64 && HAVE_INLINE_ASM */ #endif /* AVUTIL_MIPS_INTREADWRITE_H */ -- cgit v1.2.3 From 6766169c4198031c58a7972604d74947a16b75a7 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Sat, 5 May 2012 23:38:15 +0100 Subject: mips: intreadwrite: fix inline asm for gcc 4.8 Just like gcc 4.6 and later on ARM, gcc 4.8 on MIPS generates inefficient code when a known-unaligned location is used as a memory input operand. This applies the same fix as has been previously done to the ARM version of the code. Signed-off-by: Mans Rullgard --- libavutil/mips/intreadwrite.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'libavutil') diff --git a/libavutil/mips/intreadwrite.h b/libavutil/mips/intreadwrite.h index d0c558fb81..4dabbe6819 100644 --- a/libavutil/mips/intreadwrite.h +++ b/libavutil/mips/intreadwrite.h @@ -29,12 +29,15 @@ #define AV_RN32 AV_RN32 static av_always_inline uint32_t AV_RN32(const void *p) { + struct __attribute__((packed)) u32 { uint32_t v; }; + const uint8_t *q = p; + const struct u32 *pl = (const struct u32 *)(q + 3 * !HAVE_BIGENDIAN); + const struct u32 *pr = (const struct u32 *)(q + 3 * HAVE_BIGENDIAN); uint32_t v; __asm__ ("lwl %0, %1 \n\t" "lwr %0, %2 \n\t" : "=&r"(v) - : "m"(*(const uint32_t *)((const uint8_t *)p+3*!HAVE_BIGENDIAN)), - "m"(*(const uint32_t *)((const uint8_t *)p+3*HAVE_BIGENDIAN))); + : "m"(*pl), "m"(*pr)); return v; } -- cgit v1.2.3 From 142e740d1ecc6059556f2748a18757d399ee061f Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 6 May 2012 14:10:38 +0200 Subject: samplefmt: add a function for copying audio samples. --- libavutil/samplefmt.c | 19 +++++++++++++++++++ libavutil/samplefmt.h | 15 +++++++++++++++ 2 files changed, 34 insertions(+) (limited to 'libavutil') diff --git a/libavutil/samplefmt.c b/libavutil/samplefmt.c index 711afac287..4d94fa69be 100644 --- a/libavutil/samplefmt.c +++ b/libavutil/samplefmt.c @@ -185,3 +185,22 @@ int av_samples_alloc(uint8_t **audio_data, int *linesize, int nb_channels, } return 0; } + +int av_samples_copy(uint8_t **dst, uint8_t * const *src, int dst_offset, + int src_offset, int nb_samples, int nb_channels, + enum AVSampleFormat sample_fmt) +{ + int planar = av_sample_fmt_is_planar(sample_fmt); + int planes = planar ? nb_channels : 1; + int block_align = av_get_bytes_per_sample(sample_fmt) * (planar ? 1 : nb_channels); + int data_size = nb_samples * block_align; + int i; + + dst_offset *= block_align; + src_offset *= block_align; + + for (i = 0; i < planes; i++) + memcpy(dst[i] + dst_offset, src[i] + src_offset, data_size); + + return 0; +} diff --git a/libavutil/samplefmt.h b/libavutil/samplefmt.h index 1cb01a357f..9011889e68 100644 --- a/libavutil/samplefmt.h +++ b/libavutil/samplefmt.h @@ -194,4 +194,19 @@ int av_samples_fill_arrays(uint8_t **audio_data, int *linesize, int av_samples_alloc(uint8_t **audio_data, int *linesize, int nb_channels, int nb_samples, enum AVSampleFormat sample_fmt, int align); +/** + * Copy samples from src to dst. + * + * @param dst destination array of pointers to data planes + * @param src source array of pointers to data planes + * @param dst_offset offset in samples at which the data will be written to dst + * @param src_offset offset in samples at which the data will be read from src + * @param nb_samples number of samples to be copied + * @param nb_channels number of audio channels + * @param sample_fmt audio sample format + */ +int av_samples_copy(uint8_t **dst, uint8_t * const *src, int dst_offset, + int src_offset, int nb_samples, int nb_channels, + enum AVSampleFormat sample_fmt); + #endif /* AVUTIL_SAMPLEFMT_H */ -- cgit v1.2.3 From 6d7f61770094cc80ca2d93c4784c0091411d8242 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 8 May 2012 13:56:37 +0200 Subject: samplefmt: add a function for filling a buffer with silence. --- libavutil/samplefmt.c | 19 +++++++++++++++++++ libavutil/samplefmt.h | 12 ++++++++++++ 2 files changed, 31 insertions(+) (limited to 'libavutil') diff --git a/libavutil/samplefmt.c b/libavutil/samplefmt.c index 4d94fa69be..b6e785cb67 100644 --- a/libavutil/samplefmt.c +++ b/libavutil/samplefmt.c @@ -204,3 +204,22 @@ int av_samples_copy(uint8_t **dst, uint8_t * const *src, int dst_offset, return 0; } + +int av_samples_set_silence(uint8_t **audio_data, int offset, int nb_samples, + int nb_channels, enum AVSampleFormat sample_fmt) +{ + int planar = av_sample_fmt_is_planar(sample_fmt); + int planes = planar ? nb_channels : 1; + int block_align = av_get_bytes_per_sample(sample_fmt) * (planar ? 1 : nb_channels); + int data_size = nb_samples * block_align; + int fill_char = (sample_fmt == AV_SAMPLE_FMT_U8 || + sample_fmt == AV_SAMPLE_FMT_U8P) ? 0x80 : 0x00; + int i; + + offset *= block_align; + + for (i = 0; i < planes; i++) + memset(audio_data[i] + offset, fill_char, data_size); + + return 0; +} diff --git a/libavutil/samplefmt.h b/libavutil/samplefmt.h index 9011889e68..e3aa6a9c36 100644 --- a/libavutil/samplefmt.h +++ b/libavutil/samplefmt.h @@ -209,4 +209,16 @@ int av_samples_copy(uint8_t **dst, uint8_t * const *src, int dst_offset, int src_offset, int nb_samples, int nb_channels, enum AVSampleFormat sample_fmt); +/** + * Fill an audio buffer with silence. + * + * @param audio_data array of pointers to data planes + * @param offset offset in samples at which to start filling + * @param nb_samples number of samples to fill + * @param nb_channels number of audio channels + * @param sample_fmt audio sample format + */ +int av_samples_set_silence(uint8_t **audio_data, int offset, int nb_samples, + int nb_channels, enum AVSampleFormat sample_fmt); + #endif /* AVUTIL_SAMPLEFMT_H */ -- cgit v1.2.3