From 4010d724e1d57858d56bff66fa245f2d5646be6e Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Thu, 26 Apr 2012 16:02:37 -0400 Subject: [PATCH 1/6] lavr: use 8.8 instead of 10.6 as the 16-bit fixed-point mixing coeff type --- doc/APIchanges | 3 +++ libavresample/audio_mix.c | 10 +++++----- libavresample/audio_mix.h | 2 +- libavresample/audio_mix_matrix.c | 10 +++++----- libavresample/avresample.h | 2 +- libavresample/options.c | 4 ++-- libavresample/version.h | 2 +- 7 files changed, 18 insertions(+), 15 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index 41cd0a187f..fd834f170b 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,9 @@ libavutil: 2011-04-18 API changes, most recent first: +2012-xx-xx - xxxxxxx - lavr 0.0.1 + Change AV_MIX_COEFF_TYPE_Q6 to AV_MIX_COEFF_TYPE_Q8. + 2012-04-25 - 3527a73 - lavu 51.29.0 - cpu.h Add av_parse_cpu_flags() diff --git a/libavresample/audio_mix.c b/libavresample/audio_mix.c index 34252bf68d..76f10eaab2 100644 --- a/libavresample/audio_mix.c +++ b/libavresample/audio_mix.c @@ -27,7 +27,7 @@ #include "audio_data.h" #include "audio_mix.h" -static const char *coeff_type_names[] = { "q6", "q15", "flt" }; +static const char *coeff_type_names[] = { "q8", "q15", "flt" }; void ff_audio_mix_set_func(AudioMix *am, enum AVSampleFormat fmt, enum AVMixCoeffType coeff_type, int in_channels, @@ -89,7 +89,7 @@ static void MIX_FUNC_NAME(fmt, cfmt)(stype **samples, ctype **matrix, \ MIX_FUNC_GENERIC(FLTP, FLT, float, float, float, sum) MIX_FUNC_GENERIC(S16P, FLT, int16_t, float, float, av_clip_int16(lrintf(sum))) MIX_FUNC_GENERIC(S16P, Q15, int16_t, int32_t, int64_t, av_clip_int16(sum >> 15)) -MIX_FUNC_GENERIC(S16P, Q6, int16_t, int16_t, int32_t, av_clip_int16(sum >> 6)) +MIX_FUNC_GENERIC(S16P, Q8, int16_t, int16_t, int32_t, av_clip_int16(sum >> 8)) /* TODO: templatize the channel-specific C functions */ @@ -221,8 +221,8 @@ static int mix_function_init(AudioMix *am) ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_Q15, 0, 0, 1, 1, "C", MIX_FUNC_NAME(S16P, Q15)); - ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_Q6, - 0, 0, 1, 1, "C", MIX_FUNC_NAME(S16P, Q6)); + ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_Q8, + 0, 0, 1, 1, "C", MIX_FUNC_NAME(S16P, Q8)); /* channel-specific C versions */ @@ -320,7 +320,7 @@ void ff_audio_mix_close(AudioMix *am) av_free(am->matrix[0]); am->matrix = NULL; } - memset(am->matrix_q6, 0, sizeof(am->matrix_q6 )); + memset(am->matrix_q8, 0, sizeof(am->matrix_q8 )); memset(am->matrix_q15, 0, sizeof(am->matrix_q15)); memset(am->matrix_flt, 0, sizeof(am->matrix_flt)); } diff --git a/libavresample/audio_mix.h b/libavresample/audio_mix.h index ffa1b23842..61db33047d 100644 --- a/libavresample/audio_mix.h +++ b/libavresample/audio_mix.h @@ -47,7 +47,7 @@ typedef struct AudioMix { mix_func *mix; mix_func *mix_generic; - int16_t *matrix_q6[AVRESAMPLE_MAX_CHANNELS]; + int16_t *matrix_q8[AVRESAMPLE_MAX_CHANNELS]; int32_t *matrix_q15[AVRESAMPLE_MAX_CHANNELS]; float *matrix_flt[AVRESAMPLE_MAX_CHANNELS]; void **matrix; diff --git a/libavresample/audio_mix_matrix.c b/libavresample/audio_mix_matrix.c index 96c49ef26f..6135b02422 100644 --- a/libavresample/audio_mix_matrix.c +++ b/libavresample/audio_mix_matrix.c @@ -257,14 +257,14 @@ int avresample_get_matrix(AVAudioResampleContext *avr, double *matrix, } switch (avr->mix_coeff_type) { - case AV_MIX_COEFF_TYPE_Q6: - if (!avr->am->matrix_q6[0]) { + case AV_MIX_COEFF_TYPE_Q8: + if (!avr->am->matrix_q8[0]) { av_log(avr, AV_LOG_ERROR, "matrix is not set\n"); return AVERROR(EINVAL); } for (o = 0; o < out_channels; o++) for (i = 0; i < in_channels; i++) - matrix[o * stride + i] = avr->am->matrix_q6[o][i] / 64.0; + matrix[o * stride + i] = avr->am->matrix_q8[o][i] / 256.0; break; case AV_MIX_COEFF_TYPE_Q15: if (!avr->am->matrix_q15[0]) { @@ -325,8 +325,8 @@ int avresample_set_matrix(AVAudioResampleContext *avr, const double *matrix, avr->am->matrix = (void **)avr->am->matrix_## type; switch (avr->mix_coeff_type) { - case AV_MIX_COEFF_TYPE_Q6: - CONVERT_MATRIX(q6, av_clip_int16(lrint(64.0 * v))) + case AV_MIX_COEFF_TYPE_Q8: + CONVERT_MATRIX(q8, av_clip_int16(lrint(256.0 * v))) break; case AV_MIX_COEFF_TYPE_Q15: CONVERT_MATRIX(q15, av_clipl_int32(llrint(32768.0 * v))) diff --git a/libavresample/avresample.h b/libavresample/avresample.h index 41688ed555..7350805e41 100644 --- a/libavresample/avresample.h +++ b/libavresample/avresample.h @@ -39,7 +39,7 @@ typedef struct AVAudioResampleContext AVAudioResampleContext; /** Mixing Coefficient Types */ enum AVMixCoeffType { - AV_MIX_COEFF_TYPE_Q6, /** 16-bit 10.6 fixed-point */ + AV_MIX_COEFF_TYPE_Q8, /** 16-bit 8.8 fixed-point */ AV_MIX_COEFF_TYPE_Q15, /** 32-bit 17.15 fixed-point */ AV_MIX_COEFF_TYPE_FLT, /** floating-point */ AV_MIX_COEFF_TYPE_NB, /** Number of coeff types. Not part of ABI */ diff --git a/libavresample/options.c b/libavresample/options.c index 0be1a26117..5430c4ddf2 100644 --- a/libavresample/options.c +++ b/libavresample/options.c @@ -40,8 +40,8 @@ static const AVOption options[] = { { "out_sample_fmt", "Output Sample Format", OFFSET(out_sample_fmt), AV_OPT_TYPE_INT, { AV_SAMPLE_FMT_S16 }, AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_NB-1, PARAM }, { "out_sample_rate", "Output Sample Rate", OFFSET(out_sample_rate), AV_OPT_TYPE_INT, { 48000 }, 1, INT_MAX, PARAM }, { "internal_sample_fmt", "Internal Sample Format", OFFSET(internal_sample_fmt), AV_OPT_TYPE_INT, { AV_SAMPLE_FMT_FLTP }, AV_SAMPLE_FMT_NONE, AV_SAMPLE_FMT_NB-1, PARAM }, - { "mix_coeff_type", "Mixing Coefficient Type", OFFSET(mix_coeff_type), AV_OPT_TYPE_INT, { AV_MIX_COEFF_TYPE_FLT }, AV_MIX_COEFF_TYPE_Q6, AV_MIX_COEFF_TYPE_NB-1, PARAM, "mix_coeff_type" }, - { "q6", "16-bit 10.6 Fixed-Point", 0, AV_OPT_TYPE_CONST, { AV_MIX_COEFF_TYPE_Q6 }, INT_MIN, INT_MAX, PARAM, "mix_coeff_type" }, + { "mix_coeff_type", "Mixing Coefficient Type", OFFSET(mix_coeff_type), AV_OPT_TYPE_INT, { AV_MIX_COEFF_TYPE_FLT }, AV_MIX_COEFF_TYPE_Q8, AV_MIX_COEFF_TYPE_NB-1, PARAM, "mix_coeff_type" }, + { "q8", "16-bit 8.8 Fixed-Point", 0, AV_OPT_TYPE_CONST, { AV_MIX_COEFF_TYPE_Q8 }, INT_MIN, INT_MAX, PARAM, "mix_coeff_type" }, { "q15", "32-bit 17.15 Fixed-Point", 0, AV_OPT_TYPE_CONST, { AV_MIX_COEFF_TYPE_Q15 }, INT_MIN, INT_MAX, PARAM, "mix_coeff_type" }, { "flt", "Floating-Point", 0, AV_OPT_TYPE_CONST, { AV_MIX_COEFF_TYPE_FLT }, INT_MIN, INT_MAX, PARAM, "mix_coeff_type" }, { "center_mix_level", "Center Mix Level", OFFSET(center_mix_level), AV_OPT_TYPE_DOUBLE, { M_SQRT1_2 }, -32.0, 32.0, PARAM }, diff --git a/libavresample/version.h b/libavresample/version.h index 4113edc21d..47504c9380 100644 --- a/libavresample/version.h +++ b/libavresample/version.h @@ -21,7 +21,7 @@ #define LIBAVRESAMPLE_VERSION_MAJOR 0 #define LIBAVRESAMPLE_VERSION_MINOR 0 -#define LIBAVRESAMPLE_VERSION_MICRO 0 +#define LIBAVRESAMPLE_VERSION_MICRO 1 #define LIBAVRESAMPLE_VERSION_INT AV_VERSION_INT(LIBAVRESAMPLE_VERSION_MAJOR, \ LIBAVRESAMPLE_VERSION_MINOR, \ From 4bf2e7c5f1c0ad3997fd7c9859c16db8e4e16df6 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Tue, 1 May 2012 18:27:19 +0100 Subject: [PATCH 2/6] twinvq: fix out of bounds array access ModeTab.fmode has only 3 elements, so indexing it with ftype in the initialier for 'size' is invalid when ftype == FT_PPC. This fixes crashes with gcc 4.8. Signed-off-by: Mans Rullgard --- libavcodec/twinvq.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libavcodec/twinvq.c b/libavcodec/twinvq.c index 1577d77be3..67bc16088e 100644 --- a/libavcodec/twinvq.c +++ b/libavcodec/twinvq.c @@ -1000,14 +1000,16 @@ static av_cold void construct_perm_table(TwinContext *tctx,enum FrameType ftype) { int block_size; const ModeTab *mtab = tctx->mtab; - int size = tctx->avctx->channels*mtab->fmode[ftype].sub; + int size; int16_t *tmp_perm = (int16_t *) tctx->tmp_buf; if (ftype == FT_PPC) { size = tctx->avctx->channels; block_size = mtab->ppc_shape_len; - } else + } else { + size = tctx->avctx->channels * mtab->fmode[ftype].sub; block_size = mtab->size / mtab->fmode[ftype].sub; + } permutate_in_line(tmp_perm, tctx->n_div[ftype], size, block_size, tctx->length[ftype], From ff80c68264fc90df3b97a817279f156afec5b964 Mon Sep 17 00:00:00 2001 From: Hendrik Leppkes Date: Sun, 29 Apr 2012 17:21:55 +0000 Subject: [PATCH 3/6] pcm_bluray: set bits_per_raw_sample for > 16-bit Signed-off-by: Michael Niedermayer Signed-off-by: Derek Buitenhuis --- libavcodec/pcm-mpeg.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/pcm-mpeg.c b/libavcodec/pcm-mpeg.c index 3604013e08..51a08d68d2 100644 --- a/libavcodec/pcm-mpeg.c +++ b/libavcodec/pcm-mpeg.c @@ -75,6 +75,7 @@ static int pcm_bluray_parse_header(AVCodecContext *avctx, } avctx->sample_fmt = avctx->bits_per_coded_sample == 16 ? AV_SAMPLE_FMT_S16 : AV_SAMPLE_FMT_S32; + avctx->bits_per_raw_sample = avctx->bits_per_coded_sample; /* get the sample rate. Not all values are known or exist. */ switch (header[2] & 0x0f) { From 4b7fa553a90361da730dfffc92c4bb75a181897d Mon Sep 17 00:00:00 2001 From: Hendrik Leppkes Date: Sun, 29 Apr 2012 16:33:41 +0000 Subject: [PATCH 4/6] indeo3: fix motion vector validation The index of the motion vector has to be checked before being multiplied by 2 for the array index. Signed-off-by: Michael Niedermayer Signed-off-by: Derek Buitenhuis --- libavcodec/indeo3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/indeo3.c b/libavcodec/indeo3.c index ed3535adc7..80839406c0 100644 --- a/libavcodec/indeo3.c +++ b/libavcodec/indeo3.c @@ -773,12 +773,12 @@ static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx, /* get motion vector index and setup the pointer to the mv set */ if (!ctx->need_resync) ctx->next_cell_data = &ctx->gb.buffer[(get_bits_count(&ctx->gb) + 7) >> 3]; - mv_idx = *(ctx->next_cell_data++) << 1; + mv_idx = *(ctx->next_cell_data++); if (mv_idx >= ctx->num_vectors) { av_log(avctx, AV_LOG_ERROR, "motion vector index out of range\n"); return AVERROR_INVALIDDATA; } - curr_cell.mv_ptr = &ctx->mc_vectors[mv_idx]; + curr_cell.mv_ptr = &ctx->mc_vectors[mv_idx << 1]; curr_cell.tree = 1; /* enter the VQ tree */ UPDATE_BITPOS(8); } else { /* VQ tree DATA code */ From adebad07e084af91cad1b162d89c86c9e08e0a31 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Wed, 2 May 2012 12:46:22 +0100 Subject: [PATCH 5/6] arm: intreadwrite: fix inline asm constraints for gcc 4.6 and later With a dereferenced type-cast pointer as memory operand, gcc 4.6 and later will sometimes copy the data to a temporary location, the address of which is used as the operand value, if it thinks the target address might be misaligned. Using a pointer to a packed struct type instead does the right thing. The 16-bit case is special since the ldrh instruction addressing modes are limited compared to ldr. The "Uq" constraint produces a memory reference suitable for an ldrsb instruction, which supports the same addressing modes as ldrh. However, the restrictions appear to apply only when the operand addresses a single byte. The memory reference must thus be split into two operands each targeting one byte. Finally, the "Uq" constraint is only available in ARM mode. The Thumb-2 ldrh instruction supports most addressing modes so the normal "m" constraint can be used there. Signed-off-by: Mans Rullgard --- libavutil/arm/intreadwrite.h | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/libavutil/arm/intreadwrite.h b/libavutil/arm/intreadwrite.h index 613abe511c..ec92d4d04b 100644 --- a/libavutil/arm/intreadwrite.h +++ b/libavutil/arm/intreadwrite.h @@ -27,8 +27,13 @@ #define AV_RN16 AV_RN16 static av_always_inline unsigned AV_RN16(const void *p) { + const uint8_t *q = p; unsigned v; - __asm__ ("ldrh %0, %1" : "=r"(v) : "m"(*(const uint16_t *)p)); +#ifdef __thumb__ + __asm__ ("ldrh %0, %1" : "=r"(v) : "m"(q[0]), "m"(q[1])); +#else + __asm__ ("ldrh %0, %1" : "=r"(v) : "Uq"(q[0]), "m"(q[1])); +#endif return v; } @@ -41,8 +46,9 @@ static av_always_inline void AV_WN16(void *p, uint16_t v) #define AV_RN32 AV_RN32 static av_always_inline uint32_t AV_RN32(const void *p) { + const struct __attribute__((packed)) { uint32_t v; } *q = p; uint32_t v; - __asm__ ("ldr %0, %1" : "=r"(v) : "m"(*(const uint32_t *)p)); + __asm__ ("ldr %0, %1" : "=r"(v) : "m"(*q)); return v; } @@ -55,11 +61,12 @@ static av_always_inline void AV_WN32(void *p, uint32_t v) #define AV_RN64 AV_RN64 static av_always_inline uint64_t AV_RN64(const void *p) { + const struct __attribute__((packed)) { uint32_t v; } *q = p; uint64_t v; __asm__ ("ldr %Q0, %1 \n\t" "ldr %R0, %2 \n\t" : "=&r"(v) - : "m"(*(const uint32_t*)p), "m"(*((const uint32_t*)p+1))); + : "m"(q[0]), "m"(q[1])); return v; } From ababec7b95d84e911ecda6056e8b8c90287a6e7a Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Wed, 2 May 2012 15:09:54 +0100 Subject: [PATCH 6/6] arm: intreadwrite: disable inline asm for gcc 4.7 and later Starting with version 4.7, gcc properly supports unaligned memory accesses on ARM. Not using the inline asm with these compilers results in better code. Signed-off-by: Mans Rullgard --- libavutil/arm/intreadwrite.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavutil/arm/intreadwrite.h b/libavutil/arm/intreadwrite.h index ec92d4d04b..86b93c940c 100644 --- a/libavutil/arm/intreadwrite.h +++ b/libavutil/arm/intreadwrite.h @@ -21,8 +21,9 @@ #include #include "config.h" +#include "libavutil/attributes.h" -#if HAVE_FAST_UNALIGNED && HAVE_INLINE_ASM +#if HAVE_FAST_UNALIGNED && HAVE_INLINE_ASM && !AV_GCC_VERSION_AT_LEAST(4,7) #define AV_RN16 AV_RN16 static av_always_inline unsigned AV_RN16(const void *p)