* mans/ac3: ac3enc: slightly faster quantize_mantissas_blk_ch() ac3enc: NEON optimised sum_square_butterfly_float ac3enc: neon optimised sum_square_butterfly_int32 ac3enc: move inner loop of compute_rematrixing_strategy to ac3dsp Conflicts: libavcodec/ac3enc_template.c Merged-by: Michael Niedermayer <michaelni@gmx.at>tags/n0.9
| @@ -23,6 +23,7 @@ | |||||
| #include "avcodec.h" | #include "avcodec.h" | ||||
| #include "ac3.h" | #include "ac3.h" | ||||
| #include "ac3dsp.h" | #include "ac3dsp.h" | ||||
| #include "mathops.h" | |||||
| static void ac3_exponent_min_c(uint8_t *exp, int num_reuse_blocks, int nb_coefs) | static void ac3_exponent_min_c(uint8_t *exp, int num_reuse_blocks, int nb_coefs) | ||||
| { | { | ||||
| @@ -169,6 +170,48 @@ static void ac3_extract_exponents_c(uint8_t *exp, int32_t *coef, int nb_coefs) | |||||
| } | } | ||||
| } | } | ||||
| static void ac3_sum_square_butterfly_int32_c(int64_t sum[4], | |||||
| const int32_t *coef0, | |||||
| const int32_t *coef1, | |||||
| int len) | |||||
| { | |||||
| int i; | |||||
| sum[0] = sum[1] = sum[2] = sum[3] = 0; | |||||
| for (i = 0; i < len; i++) { | |||||
| int lt = coef0[i]; | |||||
| int rt = coef1[i]; | |||||
| int md = lt + rt; | |||||
| int sd = lt - rt; | |||||
| MAC64(sum[0], lt, lt); | |||||
| MAC64(sum[1], rt, rt); | |||||
| MAC64(sum[2], md, md); | |||||
| MAC64(sum[3], sd, sd); | |||||
| } | |||||
| } | |||||
| static void ac3_sum_square_butterfly_float_c(float sum[4], | |||||
| const float *coef0, | |||||
| const float *coef1, | |||||
| int len) | |||||
| { | |||||
| int i; | |||||
| sum[0] = sum[1] = sum[2] = sum[3] = 0; | |||||
| for (i = 0; i < len; i++) { | |||||
| float lt = coef0[i]; | |||||
| float rt = coef1[i]; | |||||
| float md = lt + rt; | |||||
| float sd = lt - rt; | |||||
| sum[0] += lt * lt; | |||||
| sum[1] += rt * rt; | |||||
| sum[2] += md * md; | |||||
| sum[3] += sd * sd; | |||||
| } | |||||
| } | |||||
| av_cold void ff_ac3dsp_init(AC3DSPContext *c, int bit_exact) | av_cold void ff_ac3dsp_init(AC3DSPContext *c, int bit_exact) | ||||
| { | { | ||||
| c->ac3_exponent_min = ac3_exponent_min_c; | c->ac3_exponent_min = ac3_exponent_min_c; | ||||
| @@ -180,6 +223,8 @@ av_cold void ff_ac3dsp_init(AC3DSPContext *c, int bit_exact) | |||||
| c->update_bap_counts = ac3_update_bap_counts_c; | c->update_bap_counts = ac3_update_bap_counts_c; | ||||
| c->compute_mantissa_size = ac3_compute_mantissa_size_c; | c->compute_mantissa_size = ac3_compute_mantissa_size_c; | ||||
| c->extract_exponents = ac3_extract_exponents_c; | c->extract_exponents = ac3_extract_exponents_c; | ||||
| c->sum_square_butterfly_int32 = ac3_sum_square_butterfly_int32_c; | |||||
| c->sum_square_butterfly_float = ac3_sum_square_butterfly_float_c; | |||||
| if (ARCH_ARM) | if (ARCH_ARM) | ||||
| ff_ac3dsp_init_arm(c, bit_exact); | ff_ac3dsp_init_arm(c, bit_exact); | ||||
| @@ -125,6 +125,12 @@ typedef struct AC3DSPContext { | |||||
| int (*compute_mantissa_size)(uint16_t mant_cnt[6][16]); | int (*compute_mantissa_size)(uint16_t mant_cnt[6][16]); | ||||
| void (*extract_exponents)(uint8_t *exp, int32_t *coef, int nb_coefs); | void (*extract_exponents)(uint8_t *exp, int32_t *coef, int nb_coefs); | ||||
| void (*sum_square_butterfly_int32)(int64_t sum[4], const int32_t *coef0, | |||||
| const int32_t *coef1, int len); | |||||
| void (*sum_square_butterfly_float)(float sum[4], const float *coef0, | |||||
| const float *coef1, int len); | |||||
| } AC3DSPContext; | } AC3DSPContext; | ||||
| void ff_ac3dsp_init (AC3DSPContext *c, int bit_exact); | void ff_ac3dsp_init (AC3DSPContext *c, int bit_exact); | ||||
| @@ -1163,14 +1163,11 @@ static void quantize_mantissas_blk_ch(AC3Mant *s, int32_t *fixed_coef, | |||||
| int i; | int i; | ||||
| for (i = start_freq; i < end_freq; i++) { | for (i = start_freq; i < end_freq; i++) { | ||||
| int v; | |||||
| int c = fixed_coef[i]; | int c = fixed_coef[i]; | ||||
| int e = exp[i]; | int e = exp[i]; | ||||
| int b = bap[i]; | |||||
| switch (b) { | |||||
| case 0: | |||||
| v = 0; | |||||
| break; | |||||
| int v = bap[i]; | |||||
| if (v) | |||||
| switch (v) { | |||||
| case 1: | case 1: | ||||
| v = sym_quant(c, e, 3); | v = sym_quant(c, e, 3); | ||||
| switch (s->mant1_cnt) { | switch (s->mant1_cnt) { | ||||
| @@ -1239,7 +1236,7 @@ static void quantize_mantissas_blk_ch(AC3Mant *s, int32_t *fixed_coef, | |||||
| v = asym_quant(c, e, 16); | v = asym_quant(c, e, 16); | ||||
| break; | break; | ||||
| default: | default: | ||||
| v = asym_quant(c, e, b - 1); | |||||
| v = asym_quant(c, e, v - 1); | |||||
| break; | break; | ||||
| } | } | ||||
| qmant[i] = v; | qmant[i] = v; | ||||
| @@ -103,6 +103,12 @@ static void scale_coefficients(AC3EncodeContext *s) | |||||
| } | } | ||||
| } | } | ||||
| static void sum_square_butterfly(AC3EncodeContext *s, int64_t sum[4], | |||||
| const int32_t *coef0, const int32_t *coef1, | |||||
| int len) | |||||
| { | |||||
| s->ac3dsp.sum_square_butterfly_int32(sum, coef0, coef1, len); | |||||
| } | |||||
| /** | /** | ||||
| * Clip MDCT coefficients to allowable range. | * Clip MDCT coefficients to allowable range. | ||||
| @@ -110,6 +110,12 @@ static void scale_coefficients(AC3EncodeContext *s) | |||||
| chan_size * (s->channels + cpl)); | chan_size * (s->channels + cpl)); | ||||
| } | } | ||||
| static void sum_square_butterfly(AC3EncodeContext *s, float sum[4], | |||||
| const float *coef0, const float *coef1, | |||||
| int len) | |||||
| { | |||||
| s->ac3dsp.sum_square_butterfly_float(sum, coef0, coef1, len); | |||||
| } | |||||
| /** | /** | ||||
| * Clip MDCT coefficients to allowable range. | * Clip MDCT coefficients to allowable range. | ||||
| @@ -43,6 +43,9 @@ static void clip_coefficients(DSPContext *dsp, CoefType *coef, unsigned int len) | |||||
| static CoefType calc_cpl_coord(CoefSumType energy_ch, CoefSumType energy_cpl); | static CoefType calc_cpl_coord(CoefSumType energy_ch, CoefSumType energy_cpl); | ||||
| static void sum_square_butterfly(AC3EncodeContext *s, CoefSumType sum[4], | |||||
| const CoefType *coef0, const CoefType *coef1, | |||||
| int len); | |||||
| int AC3_NAME(allocate_sample_buffers)(AC3EncodeContext *s) | int AC3_NAME(allocate_sample_buffers)(AC3EncodeContext *s) | ||||
| { | { | ||||
| @@ -334,7 +337,7 @@ static void apply_channel_coupling(AC3EncodeContext *s) | |||||
| static void compute_rematrixing_strategy(AC3EncodeContext *s) | static void compute_rematrixing_strategy(AC3EncodeContext *s) | ||||
| { | { | ||||
| int nb_coefs; | int nb_coefs; | ||||
| int blk, bnd, i; | |||||
| int blk, bnd; | |||||
| AC3Block *block, *av_uninit(block0); | AC3Block *block, *av_uninit(block0); | ||||
| if (s->channel_mode != AC3_CHMODE_STEREO) | if (s->channel_mode != AC3_CHMODE_STEREO) | ||||
| @@ -362,17 +365,9 @@ static void compute_rematrixing_strategy(AC3EncodeContext *s) | |||||
| /* calculate calculate sum of squared coeffs for one band in one block */ | /* calculate calculate sum of squared coeffs for one band in one block */ | ||||
| int start = ff_ac3_rematrix_band_tab[bnd]; | int start = ff_ac3_rematrix_band_tab[bnd]; | ||||
| int end = FFMIN(nb_coefs, ff_ac3_rematrix_band_tab[bnd+1]); | int end = FFMIN(nb_coefs, ff_ac3_rematrix_band_tab[bnd+1]); | ||||
| CoefSumType sum[4] = {0,}; | |||||
| for (i = start; i < end; i++) { | |||||
| CoefType lt = block->mdct_coef[1][i]; | |||||
| CoefType rt = block->mdct_coef[2][i]; | |||||
| CoefType md = lt + rt; | |||||
| CoefType sd = lt - rt; | |||||
| MAC_COEF(sum[0], lt, lt); | |||||
| MAC_COEF(sum[1], rt, rt); | |||||
| MAC_COEF(sum[2], md, md); | |||||
| MAC_COEF(sum[3], sd, sd); | |||||
| } | |||||
| CoefSumType sum[4]; | |||||
| sum_square_butterfly(s, sum, block->mdct_coef[1] + start, | |||||
| block->mdct_coef[2] + start, end - start); | |||||
| /* compare sums to determine if rematrixing will be used for this band */ | /* compare sums to determine if rematrixing will be used for this band */ | ||||
| if (FFMIN(sum[2], sum[3]) < FFMIN(sum[0], sum[1])) | if (FFMIN(sum[2], sum[3]) < FFMIN(sum[0], sum[1])) | ||||
| @@ -29,6 +29,14 @@ void ff_ac3_lshift_int16_neon(int16_t *src, unsigned len, unsigned shift); | |||||
| void ff_ac3_rshift_int32_neon(int32_t *src, unsigned len, unsigned shift); | void ff_ac3_rshift_int32_neon(int32_t *src, unsigned len, unsigned shift); | ||||
| void ff_float_to_fixed24_neon(int32_t *dst, const float *src, unsigned int len); | void ff_float_to_fixed24_neon(int32_t *dst, const float *src, unsigned int len); | ||||
| void ff_ac3_extract_exponents_neon(uint8_t *exp, int32_t *coef, int nb_coefs); | void ff_ac3_extract_exponents_neon(uint8_t *exp, int32_t *coef, int nb_coefs); | ||||
| void ff_ac3_sum_square_butterfly_int32_neon(int64_t sum[4], | |||||
| const int32_t *coef0, | |||||
| const int32_t *coef1, | |||||
| int len); | |||||
| void ff_ac3_sum_square_butterfly_float_neon(float sum[4], | |||||
| const float *coef0, | |||||
| const float *coef1, | |||||
| int len); | |||||
| void ff_ac3_bit_alloc_calc_bap_armv6(int16_t *mask, int16_t *psd, | void ff_ac3_bit_alloc_calc_bap_armv6(int16_t *mask, int16_t *psd, | ||||
| int start, int end, | int start, int end, | ||||
| @@ -52,5 +60,7 @@ av_cold void ff_ac3dsp_init_arm(AC3DSPContext *c, int bit_exact) | |||||
| c->ac3_rshift_int32 = ff_ac3_rshift_int32_neon; | c->ac3_rshift_int32 = ff_ac3_rshift_int32_neon; | ||||
| c->float_to_fixed24 = ff_float_to_fixed24_neon; | c->float_to_fixed24 = ff_float_to_fixed24_neon; | ||||
| c->extract_exponents = ff_ac3_extract_exponents_neon; | c->extract_exponents = ff_ac3_extract_exponents_neon; | ||||
| c->sum_square_butterfly_int32 = ff_ac3_sum_square_butterfly_int32_neon; | |||||
| c->sum_square_butterfly_float = ff_ac3_sum_square_butterfly_float_neon; | |||||
| } | } | ||||
| } | } | ||||
| @@ -108,3 +108,47 @@ function ff_ac3_extract_exponents_neon, export=1 | |||||
| bgt 1b | bgt 1b | ||||
| bx lr | bx lr | ||||
| endfunc | endfunc | ||||
| function ff_ac3_sum_square_butterfly_int32_neon, export=1 | |||||
| vmov.i64 q0, #0 | |||||
| vmov.i64 q1, #0 | |||||
| vmov.i64 q2, #0 | |||||
| vmov.i64 q3, #0 | |||||
| 1: | |||||
| vld1.32 {d16}, [r1]! | |||||
| vld1.32 {d17}, [r2]! | |||||
| vadd.s32 d18, d16, d17 | |||||
| vsub.s32 d19, d16, d17 | |||||
| vmlal.s32 q0, d16, d16 | |||||
| vmlal.s32 q1, d17, d17 | |||||
| vmlal.s32 q2, d18, d18 | |||||
| vmlal.s32 q3, d19, d19 | |||||
| subs r3, r3, #2 | |||||
| bgt 1b | |||||
| vadd.s64 d0, d0, d1 | |||||
| vadd.s64 d1, d2, d3 | |||||
| vadd.s64 d2, d4, d5 | |||||
| vadd.s64 d3, d6, d7 | |||||
| vst1.64 {q0-q1}, [r0] | |||||
| bx lr | |||||
| endfunc | |||||
| function ff_ac3_sum_square_butterfly_float_neon, export=1 | |||||
| vmov.f32 q0, #0.0 | |||||
| vmov.f32 q1, #0.0 | |||||
| 1: | |||||
| vld1.32 {d16}, [r1]! | |||||
| vld1.32 {d17}, [r2]! | |||||
| vadd.f32 d18, d16, d17 | |||||
| vsub.f32 d19, d16, d17 | |||||
| vmla.f32 d0, d16, d16 | |||||
| vmla.f32 d1, d17, d17 | |||||
| vmla.f32 d2, d18, d18 | |||||
| vmla.f32 d3, d19, d19 | |||||
| subs r3, r3, #2 | |||||
| bgt 1b | |||||
| vpadd.f32 d0, d0, d1 | |||||
| vpadd.f32 d1, d2, d3 | |||||
| vst1.32 {q0}, [r0] | |||||
| bx lr | |||||
| endfunc | |||||