diff --git a/libavcodec/ac3enc.c b/libavcodec/ac3enc.c index 3cfbbdf969..cf9c4d179f 100644 --- a/libavcodec/ac3enc.c +++ b/libavcodec/ac3enc.c @@ -2167,7 +2167,7 @@ static av_cold int validate_options(AC3EncodeContext *s) (s->channel_mode == AC3_CHMODE_STEREO); s->cpl_enabled = s->options.channel_coupling && - s->channel_mode >= AC3_CHMODE_STEREO && !s->fixed_point; + s->channel_mode >= AC3_CHMODE_STEREO; return 0; } diff --git a/libavcodec/ac3enc.h b/libavcodec/ac3enc.h index 65e88c9e01..bf5ccea19f 100644 --- a/libavcodec/ac3enc.h +++ b/libavcodec/ac3enc.h @@ -52,6 +52,7 @@ #define MAC_COEF(d,a,b) ((d)+=(a)*(b)) #define COEF_MIN (-16777215.0/16777216.0) #define COEF_MAX ( 16777215.0/16777216.0) +#define NEW_CPL_COORD_THRESHOLD 0.03 typedef float SampleType; typedef float CoefType; typedef float CoefSumType; @@ -60,6 +61,7 @@ typedef float CoefSumType; #define MAC_COEF(d,a,b) MAC64(d,a,b) #define COEF_MIN -16777215 #define COEF_MAX 16777215 +#define NEW_CPL_COORD_THRESHOLD 503317 typedef int16_t SampleType; typedef int32_t CoefType; typedef int64_t CoefSumType; diff --git a/libavcodec/ac3enc_fixed.c b/libavcodec/ac3enc_fixed.c index 951b73d69b..adb735279d 100644 --- a/libavcodec/ac3enc_fixed.c +++ b/libavcodec/ac3enc_fixed.c @@ -29,6 +29,7 @@ #define CONFIG_FFT_FLOAT 0 #undef CONFIG_AC3ENC_FLOAT #include "ac3enc.h" +#include "eac3enc.h" #define AC3ENC_TYPE AC3ENC_TYPE_AC3_FIXED #include "ac3enc_opts_template.c" @@ -112,6 +113,22 @@ static void clip_coefficients(DSPContext *dsp, int32_t *coef, unsigned int len) } +/** + * Calculate a single coupling coordinate. + */ +static CoefType calc_cpl_coord(CoefSumType energy_ch, CoefSumType energy_cpl) +{ + if (energy_cpl <= COEF_MAX) { + return 1048576; + } else { + uint64_t coord = energy_ch / (energy_cpl >> 24); + uint32_t coord32 = FFMIN(coord, 1073741824); + coord32 = ff_sqrt(coord32) << 9; + return FFMIN(coord32, COEF_MAX); + } +} + + static av_cold int ac3_fixed_encode_init(AVCodecContext *avctx) { AC3EncodeContext *s = avctx->priv_data; diff --git a/libavcodec/ac3enc_float.c b/libavcodec/ac3enc_float.c index 32ec558e70..598c69db1b 100644 --- a/libavcodec/ac3enc_float.c +++ b/libavcodec/ac3enc_float.c @@ -120,6 +120,18 @@ static void clip_coefficients(DSPContext *dsp, float *coef, unsigned int len) } +/** + * Calculate a single coupling coordinate. + */ +static CoefType calc_cpl_coord(CoefSumType energy_ch, CoefSumType energy_cpl) +{ + float coord = 0.125; + if (energy_cpl > 0) + coord *= sqrtf(energy_ch / energy_cpl); + return FFMIN(coord, COEF_MAX); +} + + #if CONFIG_AC3_ENCODER AVCodec ff_ac3_encoder = { .name = "ac3", diff --git a/libavcodec/ac3enc_opts_template.c b/libavcodec/ac3enc_opts_template.c index fdbbd5f743..a8bbedbf9e 100644 --- a/libavcodec/ac3enc_opts_template.c +++ b/libavcodec/ac3enc_opts_template.c @@ -72,11 +72,9 @@ static const AVOption eac3_options[] = { {"hdcd", "HDCD", 0, FF_OPT_TYPE_CONST, {.dbl = AC3ENC_OPT_ADCONV_HDCD }, INT_MIN, INT_MAX, AC3ENC_PARAM, "ad_conv_type"}, /* Other Encoding Options */ {"stereo_rematrixing", "Stereo Rematrixing", OFFSET(stereo_rematrixing), FF_OPT_TYPE_INT, {.dbl = AC3ENC_OPT_ON }, AC3ENC_OPT_OFF, AC3ENC_OPT_ON, AC3ENC_PARAM}, -#if AC3ENC_TYPE != AC3ENC_TYPE_AC3_FIXED {"channel_coupling", "Channel Coupling", OFFSET(channel_coupling), FF_OPT_TYPE_INT, {.dbl = AC3ENC_OPT_AUTO }, AC3ENC_OPT_AUTO, AC3ENC_OPT_ON, AC3ENC_PARAM, "channel_coupling"}, {"auto", "Selected by the Encoder", 0, FF_OPT_TYPE_CONST, {.dbl = AC3ENC_OPT_AUTO }, INT_MIN, INT_MAX, AC3ENC_PARAM, "channel_coupling"}, {"cpl_start_band", "Coupling Start Band", OFFSET(cpl_start), FF_OPT_TYPE_INT, {.dbl = AC3ENC_OPT_AUTO }, AC3ENC_OPT_AUTO, 15, AC3ENC_PARAM, "cpl_start_band"}, {"auto", "Selected by the Encoder", 0, FF_OPT_TYPE_CONST, {.dbl = AC3ENC_OPT_AUTO }, INT_MIN, INT_MAX, AC3ENC_PARAM, "cpl_start_band"}, -#endif {NULL} }; diff --git a/libavcodec/ac3enc_template.c b/libavcodec/ac3enc_template.c index e7b8967edd..7e2bf3a9ca 100644 --- a/libavcodec/ac3enc_template.c +++ b/libavcodec/ac3enc_template.c @@ -41,6 +41,8 @@ static int normalize_samples(AC3EncodeContext *s); static void clip_coefficients(DSPContext *dsp, CoefType *coef, unsigned int len); +static CoefType calc_cpl_coord(CoefSumType energy_ch, CoefSumType energy_cpl); + int AC3_NAME(allocate_sample_buffers)(AC3EncodeContext *s) { @@ -118,32 +120,25 @@ static void apply_mdct(AC3EncodeContext *s) } -/** - * Calculate a single coupling coordinate. - */ -static inline float calc_cpl_coord(float energy_ch, float energy_cpl) -{ - float coord = 0.125; - if (energy_cpl > 0) - coord *= sqrtf(energy_ch / energy_cpl); - return FFMIN(coord, COEF_MAX); -} - - /** * Calculate coupling channel and coupling coordinates. */ static void apply_channel_coupling(AC3EncodeContext *s) { + LOCAL_ALIGNED_16(CoefType, cpl_coords, [AC3_MAX_BLOCKS], [AC3_MAX_CHANNELS][16]); #if CONFIG_AC3ENC_FLOAT - LOCAL_ALIGNED_16(float, cpl_coords, [AC3_MAX_BLOCKS], [AC3_MAX_CHANNELS][16]); LOCAL_ALIGNED_16(int32_t, fixed_cpl_coords, [AC3_MAX_BLOCKS], [AC3_MAX_CHANNELS][16]); +#else + int32_t (*fixed_cpl_coords)[AC3_MAX_CHANNELS][16] = cpl_coords; +#endif int blk, ch, bnd, i, j; CoefSumType energy[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][16] = {{{0}}}; int cpl_start, num_cpl_coefs; memset(cpl_coords, 0, AC3_MAX_BLOCKS * sizeof(*cpl_coords)); - memset(fixed_cpl_coords, 0, AC3_MAX_BLOCKS * sizeof(*fixed_cpl_coords)); +#if CONFIG_AC3ENC_FLOAT + memset(fixed_cpl_coords, 0, AC3_MAX_BLOCKS * sizeof(*cpl_coords)); +#endif /* align start to 16-byte boundary. align length to multiple of 32. note: coupling start bin % 4 will always be 1 */ @@ -231,11 +226,11 @@ static void apply_channel_coupling(AC3EncodeContext *s) } else { CoefSumType coord_diff = 0; for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { - coord_diff += fabs(cpl_coords[blk-1][ch][bnd] - - cpl_coords[blk ][ch][bnd]); + coord_diff += FFABS(cpl_coords[blk-1][ch][bnd] - + cpl_coords[blk ][ch][bnd]); } coord_diff /= s->num_cpl_bands; - if (coord_diff > 0.03) + if (coord_diff > NEW_CPL_COORD_THRESHOLD) block->new_cpl_coords[ch] = 1; } } @@ -282,9 +277,11 @@ static void apply_channel_coupling(AC3EncodeContext *s) if (!block->cpl_in_use) continue; +#if CONFIG_AC3ENC_FLOAT s->ac3dsp.float_to_fixed24(fixed_cpl_coords[blk][1], cpl_coords[blk][1], s->fbw_channels * 16); +#endif s->ac3dsp.extract_exponents(block->cpl_coord_exp[1], fixed_cpl_coords[blk][1], s->fbw_channels * 16); @@ -328,7 +325,6 @@ static void apply_channel_coupling(AC3EncodeContext *s) if (CONFIG_EAC3_ENCODER && s->eac3) ff_eac3_set_cpl_states(s); -#endif /* CONFIG_AC3ENC_FLOAT */ } diff --git a/tests/ref/acodec/ac3_fixed b/tests/ref/acodec/ac3_fixed index ca8a082c75..dba2dfc5e7 100644 --- a/tests/ref/acodec/ac3_fixed +++ b/tests/ref/acodec/ac3_fixed @@ -1,2 +1,2 @@ -0f14801e166819dd4a58981aea36e08b *./tests/data/acodec/ac3.rm +e7fa185030a56d9db8663ad9e38c6c94 *./tests/data/acodec/ac3.rm 98751 ./tests/data/acodec/ac3.rm diff --git a/tests/ref/seek/ac3_rm b/tests/ref/seek/ac3_rm index 05772fcf98..b38758bb2c 100644 --- a/tests/ref/seek/ac3_rm +++ b/tests/ref/seek/ac3_rm @@ -5,35 +5,40 @@ ret:-1 st:-1 flags:1 ts: 1.894167 ret:-1 st: 0 flags:0 ts: 0.788000 ret: 0 st: 0 flags:1 ts:-0.317000 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 271 size: 556 -ret: 0 st:-1 flags:0 ts: 2.576668 -ret: 0 st: 0 flags:1 dts: 2.577000 pts: 2.577000 pos: 42397 size: 558 +ret:-1 st:-1 flags:0 ts: 2.576668 ret:-1 st:-1 flags:1 ts: 1.470835 ret:-1 st: 0 flags:0 ts: 0.365000 ret: 0 st: 0 flags:1 ts:-0.741000 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 271 size: 556 -ret: 0 st:-1 flags:0 ts: 2.153336 -ret: 0 st: 0 flags:1 dts: 2.159000 pts: 2.159000 pos: 35567 size: 556 +ret:-1 st:-1 flags:0 ts: 2.153336 ret:-1 st:-1 flags:1 ts: 1.047503 ret: 0 st: 0 flags:0 ts:-0.058000 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 271 size: 556 ret:-1 st: 0 flags:1 ts: 2.836000 -ret:-1 st:-1 flags:0 ts: 1.730004 -ret:-1 st:-1 flags:1 ts: 0.624171 +ret: 0 st:-1 flags:0 ts: 1.730004 +ret: 0 st: 0 flags:1 dts:8589.800000 pts:8589.800000 pos: 65950 size: 32801 +ret: 0 st:-1 flags:1 ts: 0.624171 +ret: 0 st: 0 flags:1 dts: 0.256000 pts: 0.256000 pos: 65337 size: 400 ret: 0 st: 0 flags:0 ts:-0.482000 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 271 size: 556 -ret: 0 st: 0 flags:1 ts: 2.413000 -ret: 0 st: 0 flags:1 dts: 2.368000 pts: 2.368000 pos: 38981 size: 558 -ret:-1 st:-1 flags:0 ts: 1.306672 -ret:-1 st:-1 flags:1 ts: 0.200839 +ret:-1 st: 0 flags:1 ts: 2.413000 +ret: 0 st:-1 flags:0 ts: 1.306672 +ret: 0 st: 0 flags:1 dts:8589.800000 pts:8589.800000 pos: 65950 size: 32801 +ret: 0 st:-1 flags:1 ts: 0.200839 +ret: 0 st: 0 flags:1 dts: 0.034000 pts: 0.034000 pos: 839 size: 558 ret: 0 st: 0 flags:0 ts:-0.905000 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 271 size: 556 -ret:-1 st: 0 flags:1 ts: 1.989000 -ret:-1 st:-1 flags:0 ts: 0.883340 +ret: 0 st: 0 flags:1 ts: 1.989000 +ret: 0 st: 0 flags:1 dts: 0.256000 pts: 0.256000 pos: 65337 size: 400 +ret: 0 st:-1 flags:0 ts: 0.883340 +ret: 0 st: 0 flags:1 dts: 3.378000 pts: 3.378000 pos: 55491 size: 558 ret: 0 st:-1 flags:1 ts:-0.222493 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 271 size: 556 ret: 0 st: 0 flags:0 ts: 2.672000 -ret: 0 st: 0 flags:1 dts: 2.821000 pts: 2.821000 pos: 46383 size: 556 -ret:-1 st: 0 flags:1 ts: 1.566000 -ret:-1 st:-1 flags:0 ts: 0.460008 +ret: 0 st: 0 flags:1 dts: 3.378000 pts: 3.378000 pos: 55491 size: 558 +ret: 0 st: 0 flags:1 ts: 1.566000 +ret: 0 st: 0 flags:1 dts: 0.256000 pts: 0.256000 pos: 65337 size: 400 +ret: 0 st:-1 flags:0 ts: 0.460008 +ret: 0 st: 0 flags:1 dts: 3.378000 pts: 3.378000 pos: 55491 size: 558 ret: 0 st:-1 flags:1 ts:-0.645825 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 271 size: 556