mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-11-21 10:55:51 +02:00
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
This commit is contained in:
parent
d267b339e4
commit
dc7e07ac1f
@ -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,
|
||||
|
@ -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];
|
||||
|
@ -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)
|
||||
@ -261,6 +271,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.
|
||||
*/
|
||||
@ -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);
|
||||
|
@ -34,6 +34,7 @@
|
||||
|
||||
typedef int16_t SampleType;
|
||||
typedef int32_t CoefType;
|
||||
typedef int64_t CoefSumType;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -34,6 +34,7 @@
|
||||
|
||||
typedef float SampleType;
|
||||
typedef float CoefType;
|
||||
typedef float CoefSumType;
|
||||
|
||||
|
||||
typedef struct AC3MDCTContext {
|
||||
|
@ -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 */
|
||||
|
@ -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];
|
||||
|
@ -1,2 +1,2 @@
|
||||
b315176b519a63a35cb91566e768f62b *./tests/data/acodec/ac3.rm
|
||||
9823c8f74097eab5d148cf0536ae932e *./tests/data/acodec/ac3.rm
|
||||
98751 ./tests/data/acodec/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
|
||||
|
Loading…
Reference in New Issue
Block a user