mirror of https://git.ffmpeg.org/ffmpeg.git
Convert floating-point MDCT coefficients to 24-bit fixed-point all at once
instead of doing it separately in 2 different functions. This makes float AC-3 encoding approx. 3-7% faster overall. Also, the coefficient conversion can now be easily SIMD-optimized. Originally committed as revision 26232 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
87c1410d11
commit
ac05f9030e
|
@ -62,6 +62,7 @@
|
||||||
typedef struct AC3Block {
|
typedef struct AC3Block {
|
||||||
uint8_t **bap; ///< bit allocation pointers (bap)
|
uint8_t **bap; ///< bit allocation pointers (bap)
|
||||||
CoefType **mdct_coef; ///< MDCT coefficients
|
CoefType **mdct_coef; ///< MDCT coefficients
|
||||||
|
int32_t **fixed_coef; ///< fixed-point MDCT coefficients
|
||||||
uint8_t **exp; ///< original exponents
|
uint8_t **exp; ///< original exponents
|
||||||
uint8_t **grouped_exp; ///< grouped exponents
|
uint8_t **grouped_exp; ///< grouped exponents
|
||||||
int16_t **psd; ///< psd per frequency bin
|
int16_t **psd; ///< psd per frequency bin
|
||||||
|
@ -128,6 +129,7 @@ typedef struct AC3EncodeContext {
|
||||||
uint8_t *bap_buffer;
|
uint8_t *bap_buffer;
|
||||||
uint8_t *bap1_buffer;
|
uint8_t *bap1_buffer;
|
||||||
CoefType *mdct_coef_buffer;
|
CoefType *mdct_coef_buffer;
|
||||||
|
int32_t *fixed_coef_buffer;
|
||||||
uint8_t *exp_buffer;
|
uint8_t *exp_buffer;
|
||||||
uint8_t *grouped_exp_buffer;
|
uint8_t *grouped_exp_buffer;
|
||||||
int16_t *psd_buffer;
|
int16_t *psd_buffer;
|
||||||
|
@ -153,6 +155,8 @@ static void apply_window(SampleType *output, const SampleType *input,
|
||||||
|
|
||||||
static int normalize_samples(AC3EncodeContext *s);
|
static int normalize_samples(AC3EncodeContext *s);
|
||||||
|
|
||||||
|
static void scale_coefficients(AC3EncodeContext *s);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* LUT for number of exponent groups.
|
* LUT for number of exponent groups.
|
||||||
|
@ -286,11 +290,11 @@ static void extract_exponents(AC3EncodeContext *s)
|
||||||
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
|
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
|
||||||
AC3Block *block = &s->blocks[blk];
|
AC3Block *block = &s->blocks[blk];
|
||||||
uint8_t *exp = block->exp[ch];
|
uint8_t *exp = block->exp[ch];
|
||||||
CoefType *coef = block->mdct_coef[ch];
|
int32_t *coef = block->fixed_coef[ch];
|
||||||
int exp_shift = block->exp_shift[ch];
|
int exp_shift = block->exp_shift[ch];
|
||||||
for (i = 0; i < AC3_MAX_COEFS; i++) {
|
for (i = 0; i < AC3_MAX_COEFS; i++) {
|
||||||
int e;
|
int e;
|
||||||
int v = abs(SCALE_COEF(coef[i]));
|
int v = abs(coef[i]);
|
||||||
if (v == 0)
|
if (v == 0)
|
||||||
e = 24;
|
e = 24;
|
||||||
else {
|
else {
|
||||||
|
@ -1017,7 +1021,7 @@ static inline int asym_quant(int c, int e, int qbits)
|
||||||
/**
|
/**
|
||||||
* Quantize a set of mantissas for a single channel in a single block.
|
* Quantize a set of mantissas for a single channel in a single block.
|
||||||
*/
|
*/
|
||||||
static void quantize_mantissas_blk_ch(AC3EncodeContext *s, CoefType *mdct_coef,
|
static void quantize_mantissas_blk_ch(AC3EncodeContext *s, int32_t *fixed_coef,
|
||||||
int8_t exp_shift, uint8_t *exp,
|
int8_t exp_shift, uint8_t *exp,
|
||||||
uint8_t *bap, uint16_t *qmant, int n)
|
uint8_t *bap, uint16_t *qmant, int n)
|
||||||
{
|
{
|
||||||
|
@ -1025,7 +1029,7 @@ static void quantize_mantissas_blk_ch(AC3EncodeContext *s, CoefType *mdct_coef,
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
int v;
|
int v;
|
||||||
int c = SCALE_COEF(mdct_coef[i]);
|
int c = fixed_coef[i];
|
||||||
int e = exp[i] - exp_shift;
|
int e = exp[i] - exp_shift;
|
||||||
int b = bap[i];
|
int b = bap[i];
|
||||||
switch (b) {
|
switch (b) {
|
||||||
|
@ -1122,7 +1126,7 @@ static void quantize_mantissas(AC3EncodeContext *s)
|
||||||
s->qmant1_ptr = s->qmant2_ptr = s->qmant4_ptr = NULL;
|
s->qmant1_ptr = s->qmant2_ptr = s->qmant4_ptr = NULL;
|
||||||
|
|
||||||
for (ch = 0; ch < s->channels; ch++) {
|
for (ch = 0; ch < s->channels; ch++) {
|
||||||
quantize_mantissas_blk_ch(s, block->mdct_coef[ch], block->exp_shift[ch],
|
quantize_mantissas_blk_ch(s, block->fixed_coef[ch], block->exp_shift[ch],
|
||||||
block->exp[ch], block->bap[ch],
|
block->exp[ch], block->bap[ch],
|
||||||
block->qmant[ch], s->nb_coefs[ch]);
|
block->qmant[ch], s->nb_coefs[ch]);
|
||||||
}
|
}
|
||||||
|
@ -1390,6 +1394,8 @@ static int ac3_encode_frame(AVCodecContext *avctx, unsigned char *frame,
|
||||||
|
|
||||||
apply_mdct(s);
|
apply_mdct(s);
|
||||||
|
|
||||||
|
scale_coefficients(s);
|
||||||
|
|
||||||
process_exponents(s);
|
process_exponents(s);
|
||||||
|
|
||||||
ret = compute_bit_allocation(s);
|
ret = compute_bit_allocation(s);
|
||||||
|
@ -1420,6 +1426,7 @@ static av_cold int ac3_encode_close(AVCodecContext *avctx)
|
||||||
av_freep(&s->bap_buffer);
|
av_freep(&s->bap_buffer);
|
||||||
av_freep(&s->bap1_buffer);
|
av_freep(&s->bap1_buffer);
|
||||||
av_freep(&s->mdct_coef_buffer);
|
av_freep(&s->mdct_coef_buffer);
|
||||||
|
av_freep(&s->fixed_coef_buffer);
|
||||||
av_freep(&s->exp_buffer);
|
av_freep(&s->exp_buffer);
|
||||||
av_freep(&s->grouped_exp_buffer);
|
av_freep(&s->grouped_exp_buffer);
|
||||||
av_freep(&s->psd_buffer);
|
av_freep(&s->psd_buffer);
|
||||||
|
@ -1430,6 +1437,7 @@ static av_cold int ac3_encode_close(AVCodecContext *avctx)
|
||||||
AC3Block *block = &s->blocks[blk];
|
AC3Block *block = &s->blocks[blk];
|
||||||
av_freep(&block->bap);
|
av_freep(&block->bap);
|
||||||
av_freep(&block->mdct_coef);
|
av_freep(&block->mdct_coef);
|
||||||
|
av_freep(&block->fixed_coef);
|
||||||
av_freep(&block->exp);
|
av_freep(&block->exp);
|
||||||
av_freep(&block->grouped_exp);
|
av_freep(&block->grouped_exp);
|
||||||
av_freep(&block->psd);
|
av_freep(&block->psd);
|
||||||
|
@ -1639,6 +1647,26 @@ static av_cold int allocate_buffers(AVCodecContext *avctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (CONFIG_AC3ENC_FLOAT) {
|
||||||
|
FF_ALLOC_OR_GOTO(avctx, s->fixed_coef_buffer, AC3_MAX_BLOCKS * s->channels *
|
||||||
|
AC3_MAX_COEFS * sizeof(*s->fixed_coef_buffer), alloc_fail);
|
||||||
|
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
|
||||||
|
AC3Block *block = &s->blocks[blk];
|
||||||
|
FF_ALLOCZ_OR_GOTO(avctx, block->fixed_coef, s->channels *
|
||||||
|
sizeof(*block->fixed_coef), alloc_fail);
|
||||||
|
for (ch = 0; ch < s->channels; ch++)
|
||||||
|
block->fixed_coef[ch] = &s->fixed_coef_buffer[AC3_MAX_COEFS * (blk * s->channels + ch)];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
|
||||||
|
AC3Block *block = &s->blocks[blk];
|
||||||
|
FF_ALLOCZ_OR_GOTO(avctx, block->fixed_coef, s->channels *
|
||||||
|
sizeof(*block->fixed_coef), alloc_fail);
|
||||||
|
for (ch = 0; ch < s->channels; ch++)
|
||||||
|
block->fixed_coef[ch] = (int32_t *)block->mdct_coef[ch];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
alloc_fail:
|
alloc_fail:
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
|
|
|
@ -319,6 +319,17 @@ static int normalize_samples(AC3EncodeContext *s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scale MDCT coefficients from float to fixed-point.
|
||||||
|
*/
|
||||||
|
static void scale_coefficients(AC3EncodeContext *s)
|
||||||
|
{
|
||||||
|
/* scaling/conversion is obviously not needed for the fixed-point encoder
|
||||||
|
since the coefficients are already fixed-point. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef TEST
|
#ifdef TEST
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
/* TEST */
|
/* TEST */
|
||||||
|
|
|
@ -35,8 +35,6 @@
|
||||||
typedef int16_t SampleType;
|
typedef int16_t SampleType;
|
||||||
typedef int32_t CoefType;
|
typedef int32_t CoefType;
|
||||||
|
|
||||||
#define SCALE_COEF(a) (a)
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compex number.
|
* Compex number.
|
||||||
|
|
|
@ -102,6 +102,17 @@ static int normalize_samples(AC3EncodeContext *s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scale MDCT coefficients from float to 24-bit fixed-point.
|
||||||
|
*/
|
||||||
|
static void scale_coefficients(AC3EncodeContext *s)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < AC3_MAX_COEFS * AC3_MAX_BLOCKS * s->channels; i++)
|
||||||
|
s->fixed_coef_buffer[i] = SCALE_FLOAT(s->mdct_coef_buffer[i], 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
AVCodec ac3_encoder = {
|
AVCodec ac3_encoder = {
|
||||||
"ac3",
|
"ac3",
|
||||||
AVMEDIA_TYPE_AUDIO,
|
AVMEDIA_TYPE_AUDIO,
|
||||||
|
|
|
@ -35,8 +35,6 @@
|
||||||
typedef float SampleType;
|
typedef float SampleType;
|
||||||
typedef float CoefType;
|
typedef float CoefType;
|
||||||
|
|
||||||
#define SCALE_COEF(a) SCALE_FLOAT((a), 24)
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct AC3MDCTContext {
|
typedef struct AC3MDCTContext {
|
||||||
const float *window; ///< MDCT window function
|
const float *window; ///< MDCT window function
|
||||||
|
|
Loading…
Reference in New Issue