diff options
author | Justin Ruggles <justin.ruggles@gmail.com> | 2011-01-08 23:21:17 +0000 |
---|---|---|
committer | Justin Ruggles <justin.ruggles@gmail.com> | 2011-01-08 23:21:17 +0000 |
commit | dc7e07ac1f015117a3abaa9c5f3a594cc7fd0b7a (patch) | |
tree | ddbd5861f46a4a12808c7c9fe6f846faa8dc7b01 | |
parent | d267b339e4dbf8d70455e3163b2d39aff0efe314 (diff) | |
download | ffmpeg-dc7e07ac1f015117a3abaa9c5f3a594cc7fd0b7a.tar.gz |
Add stereo rematrixing support to the AC-3 encoders.
This improves the audio quality significantly for stereo source with both the
fixed-point and floating-point AC-3 encoders.
Update acodec-ac3_fixed and seek-ac3_rm test references.
Originally committed as revision 26271 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r-- | libavcodec/ac3dec_data.c | 6 | ||||
-rw-r--r-- | libavcodec/ac3dec_data.h | 1 | ||||
-rw-r--r-- | libavcodec/ac3enc.c | 147 | ||||
-rw-r--r-- | libavcodec/ac3enc_fixed.h | 1 | ||||
-rw-r--r-- | libavcodec/ac3enc_float.h | 1 | ||||
-rw-r--r-- | libavcodec/ac3tab.c | 6 | ||||
-rw-r--r-- | libavcodec/ac3tab.h | 1 | ||||
-rw-r--r-- | tests/ref/acodec/ac3_fixed | 2 | ||||
-rw-r--r-- | tests/ref/seek/ac3_rm | 21 |
9 files changed, 152 insertions, 34 deletions
diff --git a/libavcodec/ac3dec_data.c b/libavcodec/ac3dec_data.c index ea13d3de51..c40390245c 100644 --- a/libavcodec/ac3dec_data.c +++ b/libavcodec/ac3dec_data.c @@ -43,12 +43,6 @@ const uint8_t ff_ac3_ungroup_3_in_5_bits_tab[32][3] = { { 3, 0, 1 }, { 3, 0, 2 }, { 3, 1, 0 }, { 3, 1, 1 } }; -/** - * Table of bin locations for rematrixing bands - * reference: Section 7.5.2 Rematrixing : Frequency Band Definitions - */ -const uint8_t ff_ac3_rematrix_band_tab[5] = { 13, 25, 37, 61, 253 }; - const uint8_t ff_eac3_hebap_tab[64] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, diff --git a/libavcodec/ac3dec_data.h b/libavcodec/ac3dec_data.h index 9ed7c73188..e2ab7ddbe5 100644 --- a/libavcodec/ac3dec_data.h +++ b/libavcodec/ac3dec_data.h @@ -25,7 +25,6 @@ #include <stdint.h> extern const uint8_t ff_ac3_ungroup_3_in_5_bits_tab[32][3]; -extern const uint8_t ff_ac3_rematrix_band_tab[5]; extern const uint8_t ff_eac3_hebap_tab[64]; extern const uint8_t ff_eac3_default_cpl_band_struct[18]; diff --git a/libavcodec/ac3enc.c b/libavcodec/ac3enc.c index d9a54325c0..f96883464f 100644 --- a/libavcodec/ac3enc.c +++ b/libavcodec/ac3enc.c @@ -45,6 +45,12 @@ /** Maximum number of exponent groups. +1 for separate DC exponent. */ #define AC3_MAX_EXP_GROUPS 85 +/* stereo rematrixing algorithms */ +#define AC3_REMATRIXING_IS_STATIC 0x1 +#define AC3_REMATRIXING_SUMS 0 +#define AC3_REMATRIXING_NONE 1 +#define AC3_REMATRIXING_ALWAYS 3 + /** Scale a float value by 2^bits and convert to an integer. */ #define SCALE_FLOAT(a, bits) lrintf((a) * (float)(1 << (bits))) @@ -71,6 +77,8 @@ typedef struct AC3Block { uint16_t **qmant; ///< quantized mantissas uint8_t exp_strategy[AC3_MAX_CHANNELS]; ///< exponent strategies int8_t exp_shift[AC3_MAX_CHANNELS]; ///< exponent shift values + uint8_t new_rematrixing_strategy; ///< send new rematrixing flags in this block + uint8_t rematrixing_flags[4]; ///< rematrixing flags } AC3Block; /** @@ -107,6 +115,8 @@ typedef struct AC3EncodeContext { int bandwidth_code[AC3_MAX_CHANNELS]; ///< bandwidth code (0 to 60) (chbwcod) int nb_coefs[AC3_MAX_CHANNELS]; + int rematrixing; ///< determines how rematrixing strategy is calculated + /* bitrate allocation control */ int slow_gain_code; ///< slow gain code (sgaincod) int slow_decay_code; ///< slow decay code (sdcycod) @@ -262,6 +272,114 @@ static void apply_mdct(AC3EncodeContext *s) /** + * Initialize stereo rematrixing. + * If the strategy does not change for each frame, set the rematrixing flags. + */ +static void rematrixing_init(AC3EncodeContext *s) +{ + if (s->channel_mode == AC3_CHMODE_STEREO) + s->rematrixing = AC3_REMATRIXING_SUMS; + else + s->rematrixing = AC3_REMATRIXING_NONE; + /* NOTE: AC3_REMATRIXING_ALWAYS might be used in + the future in conjunction with channel coupling. */ + + if (s->rematrixing & AC3_REMATRIXING_IS_STATIC) { + int flag = (s->rematrixing == AC3_REMATRIXING_ALWAYS); + s->blocks[0].new_rematrixing_strategy = 1; + memset(s->blocks[0].rematrixing_flags, flag, + sizeof(s->blocks[0].rematrixing_flags)); + } +} + + +/** + * Determine rematrixing flags for each block and band. + */ +static void compute_rematrixing_strategy(AC3EncodeContext *s) +{ + int nb_coefs; + int blk, bnd, i; + AC3Block *block, *block0; + + if (s->rematrixing & AC3_REMATRIXING_IS_STATIC) + return; + + nb_coefs = FFMIN(s->nb_coefs[0], s->nb_coefs[1]); + + s->blocks[0].new_rematrixing_strategy = 1; + for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { + block = &s->blocks[blk]; + for (bnd = 0; bnd < 4; bnd++) { + /* calculate calculate sum of squared coeffs for one band in one block */ + int start = ff_ac3_rematrix_band_tab[bnd]; + 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[0][i]; + CoefType rt = block->mdct_coef[1][i]; + CoefType md = lt + rt; + CoefType sd = lt - rt; + sum[0] += lt * lt; + sum[1] += rt * rt; + sum[2] += md * md; + sum[3] += sd * sd; + } + + /* compare sums to determine if rematrixing will be used for this band */ + if (FFMIN(sum[2], sum[3]) < FFMIN(sum[0], sum[1])) + block->rematrixing_flags[bnd] = 1; + else + block->rematrixing_flags[bnd] = 0; + + /* determine if new rematrixing flags will be sent */ + if (blk && + !block->new_rematrixing_strategy && + block->rematrixing_flags[bnd] != block0->rematrixing_flags[bnd]) { + block->new_rematrixing_strategy = 1; + } + } + block0 = block; + } +} + + +/** + * Apply stereo rematrixing to coefficients based on rematrixing flags. + */ +static void apply_rematrixing(AC3EncodeContext *s) +{ + int nb_coefs; + int blk, bnd, i; + int start, end; + uint8_t *flags; + + if (s->rematrixing == AC3_REMATRIXING_NONE) + return; + + nb_coefs = FFMIN(s->nb_coefs[0], s->nb_coefs[1]); + + for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { + AC3Block *block = &s->blocks[blk]; + if (block->new_rematrixing_strategy) + flags = block->rematrixing_flags; + for (bnd = 0; bnd < 4; bnd++) { + if (flags[bnd]) { + start = ff_ac3_rematrix_band_tab[bnd]; + end = FFMIN(nb_coefs, ff_ac3_rematrix_band_tab[bnd+1]); + for (i = start; i < end; i++) { + int32_t lt = block->fixed_coef[0][i]; + int32_t rt = block->fixed_coef[1][i]; + block->fixed_coef[0][i] = (lt + rt) >> 1; + block->fixed_coef[1][i] = (lt - rt) >> 1; + } + } + } + } +} + + +/** * Initialize exponent tables. */ static av_cold void exponent_init(AC3EncodeContext *s) @@ -592,7 +710,6 @@ static void count_frame_bits_fixed(AC3EncodeContext *s) /* assumptions: * no dynamic range codes * no channel coupling - * no rematrixing * bit allocation parameters do not change between blocks * SNR offsets do not change between blocks * no delta bit allocation @@ -609,8 +726,6 @@ static void count_frame_bits_fixed(AC3EncodeContext *s) frame_bits += s->fbw_channels * 2 + 2; /* blksw * c, dithflag * c, dynrnge, cplstre */ if (s->channel_mode == AC3_CHMODE_STEREO) { frame_bits++; /* rematstr */ - if (!blk) - frame_bits += 4; } frame_bits += 2 * s->fbw_channels; /* chexpstr[2] * c */ if (s->lfe_on) @@ -681,6 +796,13 @@ static void count_frame_bits(AC3EncodeContext *s) for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { uint8_t *exp_strategy = s->blocks[blk].exp_strategy; + + /* stereo rematrixing */ + if (s->channel_mode == AC3_CHMODE_STEREO && + s->blocks[blk].new_rematrixing_strategy) { + frame_bits += 4; + } + for (ch = 0; ch < s->fbw_channels; ch++) { if (exp_strategy[ch] != EXP_REUSE) frame_bits += 6 + 2; /* chbwcod[6], gainrng[2] */ @@ -1194,16 +1316,11 @@ static void output_audio_block(AC3EncodeContext *s, int block_num) /* stereo rematrixing */ if (s->channel_mode == AC3_CHMODE_STEREO) { - if (!block_num) { - /* first block must define rematrixing (rematstr) */ - put_bits(&s->pb, 1, 1); - - /* dummy rematrixing rematflg(1:4)=0 */ + put_bits(&s->pb, 1, block->new_rematrixing_strategy); + if (block->new_rematrixing_strategy) { + /* rematrixing flags */ for (rbnd = 0; rbnd < 4; rbnd++) - put_bits(&s->pb, 1, 0); - } else { - /* no matrixing (but should be used in the future) */ - put_bits(&s->pb, 1, 0); + put_bits(&s->pb, 1, block->rematrixing_flags[rbnd]); } } @@ -1394,8 +1511,12 @@ static int ac3_encode_frame(AVCodecContext *avctx, unsigned char *frame, apply_mdct(s); + compute_rematrixing_strategy(s); + scale_coefficients(s); + apply_rematrixing(s); + process_exponents(s); ret = compute_bit_allocation(s); @@ -1707,6 +1828,8 @@ static av_cold int ac3_encode_init(AVCodecContext *avctx) set_bandwidth(s); + rematrixing_init(s); + exponent_init(s); bit_alloc_init(s); diff --git a/libavcodec/ac3enc_fixed.h b/libavcodec/ac3enc_fixed.h index 32d29a9bae..12c8ace4aa 100644 --- a/libavcodec/ac3enc_fixed.h +++ b/libavcodec/ac3enc_fixed.h @@ -34,6 +34,7 @@ typedef int16_t SampleType; typedef int32_t CoefType; +typedef int64_t CoefSumType; /** diff --git a/libavcodec/ac3enc_float.h b/libavcodec/ac3enc_float.h index 29a479a00e..1726ca045f 100644 --- a/libavcodec/ac3enc_float.h +++ b/libavcodec/ac3enc_float.h @@ -34,6 +34,7 @@ typedef float SampleType; typedef float CoefType; +typedef float CoefSumType; typedef struct AC3MDCTContext { diff --git a/libavcodec/ac3tab.c b/libavcodec/ac3tab.c index 79f628fbd9..4fc0824a46 100644 --- a/libavcodec/ac3tab.c +++ b/libavcodec/ac3tab.c @@ -132,6 +132,12 @@ const uint16_t ff_ac3_bitrate_tab[19] = { 160, 192, 224, 256, 320, 384, 448, 512, 576, 640 }; +/** + * Table of bin locations for rematrixing bands + * reference: Section 7.5.2 Rematrixing : Frequency Band Definitions + */ +const uint8_t ff_ac3_rematrix_band_tab[5] = { 13, 25, 37, 61, 253 }; + /* AC-3 MDCT window */ /* MDCT window */ diff --git a/libavcodec/ac3tab.h b/libavcodec/ac3tab.h index 4d41337d3a..dd8cabfcfd 100644 --- a/libavcodec/ac3tab.h +++ b/libavcodec/ac3tab.h @@ -32,6 +32,7 @@ extern const uint8_t ff_ac3_enc_channel_map[8][2][6]; extern const uint8_t ff_ac3_dec_channel_map[8][2][6]; extern const uint16_t ff_ac3_sample_rate_tab[3]; extern const uint16_t ff_ac3_bitrate_tab[19]; +extern const uint8_t ff_ac3_rematrix_band_tab[5]; extern const int16_t ff_ac3_window[AC3_WINDOW_SIZE/2]; extern const uint8_t ff_ac3_log_add_tab[260]; extern const uint16_t ff_ac3_hearing_threshold_tab[AC3_CRITICAL_BANDS][3]; diff --git a/tests/ref/acodec/ac3_fixed b/tests/ref/acodec/ac3_fixed index 3ca8219e63..17159e18a7 100644 --- a/tests/ref/acodec/ac3_fixed +++ b/tests/ref/acodec/ac3_fixed @@ -1,2 +1,2 @@ -b315176b519a63a35cb91566e768f62b *./tests/data/acodec/ac3.rm +9823c8f74097eab5d148cf0536ae932e *./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 6d47c47281..7b7d5b0bf7 100644 --- a/tests/ref/seek/ac3_rm +++ b/tests/ref/seek/ac3_rm @@ -5,11 +5,9 @@ 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: 4.179000 pts: 4.179000 pos: 68585 size: 556 +ret:-1 st:-1 flags:0 ts: 2.576668 ret:-1 st:-1 flags:1 ts: 1.470835 -ret: 0 st: 0 flags:0 ts: 0.365000 -ret: 0 st: 0 flags:1 dts: 0.383000 pts: 0.383000 pos: 6533 size: 558 +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:-1 st:-1 flags:0 ts: 2.153336 @@ -18,25 +16,20 @@ 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: 0 st:-1 flags:1 ts: 0.624171 -ret: 0 st: 0 flags:1 dts: 0.452000 pts: 0.452000 pos: 7671 size: 558 +ret:-1 st:-1 flags:1 ts: 0.624171 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.333000 pts: 2.333000 pos: 38413 size: 556 +ret:-1 st: 0 flags:1 ts: 2.413000 ret:-1 st:-1 flags:0 ts: 1.306672 ret:-1 st:-1 flags:1 ts: 0.200839 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: 0 st: 0 flags:1 ts: 1.989000 -ret: 0 st: 0 flags:1 dts: 1.985000 pts: 1.985000 pos: 32719 size: 558 +ret:-1 st: 0 flags:1 ts: 1.989000 ret:-1 st:-1 flags:0 ts: 0.883340 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: 4.179000 pts: 4.179000 pos: 68585 size: 556 +ret:-1 st: 0 flags:0 ts: 2.672000 ret:-1 st: 0 flags:1 ts: 1.566000 -ret: 0 st:-1 flags:0 ts: 0.460008 -ret: 0 st: 0 flags:1 dts: 4.179000 pts: 4.179000 pos: 68585 size: 556 +ret:-1 st:-1 flags:0 ts: 0.460008 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 |