---
libavcodec/ac3dec_data.c | 6 ---
libavcodec/ac3dec_data.h | 1 -
libavcodec/ac3enc.c | 68 +++++++++++++++++++++++++-------
libavcodec/ac3enc_fixed.c | 12 ++++++
libavcodec/ac3enc_float.c | 96 +++++++++++++++++++++++++++++++++++++++++++++
libavcodec/ac3tab.c | 6 +++
libavcodec/ac3tab.h | 1 +
7 files changed, 168 insertions(+), 22 deletions(-)
diff --git a/libavcodec/ac3dec_data.c b/libavcodec/ac3dec_data.c
index ea13d3d..c403902 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 9ed7c73..e2ab7dd 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 affe2cf..65774dd 100644
--- a/libavcodec/ac3enc.c
+++ b/libavcodec/ac3enc.c
@@ -46,6 +46,13 @@
/** 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)))
@@ -102,6 +109,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;
/**
@@ -149,6 +158,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)
@@ -352,6 +363,8 @@ static void apply_window(DSPContext *dsp, SampleType *output, const SampleType *
static int normalize_samples(AC3EncodeContext *s);
+static void compute_rematrixing(AC3EncodeContext *s);
+
/**
* LUT for number of exponent groups.
@@ -784,7 +797,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
@@ -799,11 +811,6 @@ static void count_frame_bits_fixed(AC3EncodeContext *s)
/* audio blocks */
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
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)
frame_bits++; /* lfeexpstr */
@@ -883,6 +890,15 @@ 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) {
+ frame_bits++;
+ if (s->blocks[blk].new_rematrixing_strategy)
+ frame_bits += 4;
+ }
+
+ /* channel bandwidth code */
for (ch = 0; ch < s->fbw_channels; ch++) {
if (exp_strategy[ch] != EXP_REUSE)
frame_bits += 6 + 2; /* chbwcod[6], gainrng[2] */
@@ -1421,16 +1437,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]);
}
}
@@ -1768,6 +1779,9 @@ static int ac3_encode_frame(AVCodecContext *avctx, unsigned char *frame,
apply_mdct(s);
+ if (s->channel_mode == AC3_CHMODE_STEREO)
+ compute_rematrixing(s);
+
process_exponents(s);
ret = compute_bit_allocation(s);
@@ -1962,6 +1976,28 @@ static av_cold void set_bandwidth(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 (CONFIG_AC3ENC_FLOAT)
+ 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));
+ }
+}
+
+
static av_cold int allocate_buffers(AVCodecContext *avctx)
{
int blk, ch;
@@ -2063,6 +2099,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.c b/libavcodec/ac3enc_fixed.c
index 5561c7e..97c0b00 100644
--- a/libavcodec/ac3enc_fixed.c
+++ b/libavcodec/ac3enc_fixed.c
@@ -319,6 +319,18 @@ static int normalize_samples(AC3EncodeContext *s)
}
+/**
+ * Determine rematrixing flags and apply rematrixing to coefficients.
+ */
+static void compute_rematrixing(AC3EncodeContext *s)
+{
+ /* The fixed-point encoder cannot use rematrixing because it is not
+ accurate enough. The result always has lower quality. */
+ assert(s->rematrixing == AC3_REMATRIXING_NONE);
+ return;
+}
+
+
#ifdef TEST
/*************************************************************************/
/* TEST */
diff --git a/libavcodec/ac3enc_float.c b/libavcodec/ac3enc_float.c
index b026139..2d7970d 100644
--- a/libavcodec/ac3enc_float.c
+++ b/libavcodec/ac3enc_float.c
@@ -97,6 +97,102 @@ static int normalize_samples(AC3EncodeContext *s)
}
+/**
+ * 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;
+
+ nb_coefs = FFMIN(s->nb_coefs[0], s->nb_coefs[1]);
+
+ /* calculate sum of squared coeffs for each block and band */
+ for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
+ block = &s->blocks[blk];
+ for (bnd = 0; bnd < 4; bnd++) {
+ /* calculate sums 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]);
+ float sum[4] = {0,};
+ for (i = start; i < end; i++) {
+ float lt = block->mdct_coef[0][i];
+ float rt = block->mdct_coef[1][i];
+ sum[0] += lt * lt;
+ sum[1] += rt * rt;
+ sum[2] += (lt + rt) * (lt + rt);
+ sum[3] += (lt - rt) * (lt - rt);
+ }
+
+ /* 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;
+ }
+ }
+
+ /* for each block, determine if new rematrixing flags will be sent */
+ s->blocks[0].new_rematrixing_strategy = 1;
+ for (blk = 1; blk < AC3_MAX_BLOCKS; blk++) {
+ block = &s->blocks[blk];
+ block0 = &s->blocks[blk-1];
+ block->new_rematrixing_strategy = 0;
+ for (bnd = 0; bnd < 4; bnd++) {
+ if (block->rematrixing_flags[bnd] != block0->rematrixing_flags[bnd]) {
+ block->new_rematrixing_strategy = 1;
+ break;
+ }
+ }
+ }
+}
+
+
+/**
+ * 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;
+
+ 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++) {
+ float lt = block->mdct_coef[0][i];
+ float rt = block->mdct_coef[1][i];
+ block->mdct_coef[0][i] = (lt + rt) * 0.5;
+ block->mdct_coef[1][i] = (lt - rt) * 0.5;
+ }
+ }
+ }
+ }
+}
+
+
+/**
+ * Determine rematrixing flags and apply rematrixing to coefficients.
+ */
+static void compute_rematrixing(AC3EncodeContext *s)
+{
+ if (!(s->rematrixing & AC3_REMATRIXING_IS_STATIC))
+ compute_rematrixing_strategy(s);
+ if (s->rematrixing != AC3_REMATRIXING_NONE)
+ apply_rematrixing(s);
+}
+
+
AVCodec ac3_encoder = {
"ac3",
AVMEDIA_TYPE_AUDIO,
diff --git a/libavcodec/ac3tab.c b/libavcodec/ac3tab.c
index 79f628f..4fc0824 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 4d41337..dd8cabf 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];
_______________________________________________
FFmpeg-soc mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/ffmpeg-soc