mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
Split exponent processing into separate functions.
Originally committed as revision 25991 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
0a0a8500fb
commit
dfdf73eb1a
@ -411,6 +411,41 @@ static void apply_mdct(AC3EncodeContext *s,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract exponents from the MDCT coefficients.
|
||||||
|
* This takes into account the normalization that was done to the input samples
|
||||||
|
* by adjusting the exponents by the exponent shift values.
|
||||||
|
*/
|
||||||
|
static void extract_exponents(AC3EncodeContext *s,
|
||||||
|
int32_t mdct_coef[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS],
|
||||||
|
int8_t exp_shift[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS],
|
||||||
|
uint8_t exp[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS])
|
||||||
|
{
|
||||||
|
int blk, ch, i;
|
||||||
|
|
||||||
|
/* extract exponents */
|
||||||
|
for (ch = 0; ch < s->channels; ch++) {
|
||||||
|
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
|
||||||
|
/* compute "exponents". We take into account the normalization there */
|
||||||
|
for (i = 0; i < AC3_MAX_COEFS; i++) {
|
||||||
|
int e;
|
||||||
|
int v = abs(mdct_coef[blk][ch][i]);
|
||||||
|
if (v == 0)
|
||||||
|
e = 24;
|
||||||
|
else {
|
||||||
|
e = 23 - av_log2(v) + exp_shift[blk][ch];
|
||||||
|
if (e >= 24) {
|
||||||
|
e = 24;
|
||||||
|
mdct_coef[blk][ch][i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exp[blk][ch][i] = e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate the sum of absolute differences (SAD) between 2 sets of exponents.
|
* Calculate the sum of absolute differences (SAD) between 2 sets of exponents.
|
||||||
*/
|
*/
|
||||||
@ -472,6 +507,21 @@ static void compute_exp_strategy_ch(uint8_t exp_strategy[AC3_MAX_BLOCKS][AC3_MAX
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate exponent strategies for all channels.
|
||||||
|
*/
|
||||||
|
static void compute_exp_strategy(AC3EncodeContext *s,
|
||||||
|
uint8_t exp_strategy[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS],
|
||||||
|
uint8_t exp[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS])
|
||||||
|
{
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
for (ch = 0; ch < s->channels; ch++) {
|
||||||
|
compute_exp_strategy_ch(exp_strategy, exp, ch, ch == s->lfe_channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set each encoded exponent in a block to the minimum of itself and the
|
* Set each encoded exponent in a block to the minimum of itself and the
|
||||||
* exponent in the same frequency bin of a following block.
|
* exponent in the same frequency bin of a following block.
|
||||||
@ -539,6 +589,68 @@ static int encode_exponents_blk_ch(uint8_t encoded_exp[AC3_MAX_COEFS],
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode exponents from original extracted form to what the decoder will see.
|
||||||
|
* This copies and groups exponents based on exponent strategy and reduces
|
||||||
|
* deltas between adjacent exponent groups so that they can be differentially
|
||||||
|
* encoded.
|
||||||
|
* @return bits needed to encode the exponents
|
||||||
|
*/
|
||||||
|
static int encode_exponents(AC3EncodeContext *s,
|
||||||
|
uint8_t exp[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS],
|
||||||
|
uint8_t exp_strategy[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS],
|
||||||
|
uint8_t encoded_exp[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS])
|
||||||
|
{
|
||||||
|
int blk, blk1, blk2, ch;
|
||||||
|
int frame_bits;
|
||||||
|
|
||||||
|
frame_bits = 0;
|
||||||
|
for (ch = 0; ch < s->channels; ch++) {
|
||||||
|
/* for the EXP_REUSE case we select the min of the exponents */
|
||||||
|
blk = 0;
|
||||||
|
while (blk < AC3_MAX_BLOCKS) {
|
||||||
|
blk1 = blk + 1;
|
||||||
|
while (blk1 < AC3_MAX_BLOCKS && exp_strategy[blk1][ch] == EXP_REUSE) {
|
||||||
|
exponent_min(exp[blk][ch], exp[blk1][ch], s->nb_coefs[ch]);
|
||||||
|
blk1++;
|
||||||
|
}
|
||||||
|
frame_bits += encode_exponents_blk_ch(encoded_exp[blk][ch],
|
||||||
|
exp[blk][ch], s->nb_coefs[ch],
|
||||||
|
exp_strategy[blk][ch]);
|
||||||
|
/* copy encoded exponents for reuse case */
|
||||||
|
for (blk2 = blk+1; blk2 < blk1; blk2++) {
|
||||||
|
memcpy(encoded_exp[blk2][ch], encoded_exp[blk][ch],
|
||||||
|
s->nb_coefs[ch] * sizeof(uint8_t));
|
||||||
|
}
|
||||||
|
blk = blk1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return frame_bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate final exponents from the supplied MDCT coefficients and exponent shift.
|
||||||
|
* Extract exponents from MDCT coefficients, calculate exponent strategies,
|
||||||
|
* and encode final exponents.
|
||||||
|
* @return bits needed to encode the exponents
|
||||||
|
*/
|
||||||
|
static int process_exponents(AC3EncodeContext *s,
|
||||||
|
int32_t mdct_coef[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS],
|
||||||
|
int8_t exp_shift[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS],
|
||||||
|
uint8_t exp[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS],
|
||||||
|
uint8_t exp_strategy[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS],
|
||||||
|
uint8_t encoded_exp[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS])
|
||||||
|
{
|
||||||
|
extract_exponents(s, mdct_coef, exp_shift, exp);
|
||||||
|
|
||||||
|
compute_exp_strategy(s, exp_strategy, exp);
|
||||||
|
|
||||||
|
return encode_exponents(s, exp, exp_strategy, encoded_exp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate the number of bits needed to encode a set of mantissas.
|
* Calculate the number of bits needed to encode a set of mantissas.
|
||||||
*/
|
*/
|
||||||
@ -1174,8 +1286,7 @@ static int ac3_encode_frame(AVCodecContext *avctx,
|
|||||||
{
|
{
|
||||||
AC3EncodeContext *s = avctx->priv_data;
|
AC3EncodeContext *s = avctx->priv_data;
|
||||||
const int16_t *samples = data;
|
const int16_t *samples = data;
|
||||||
int v;
|
int blk;
|
||||||
int blk, blk1, blk2, ch, i;
|
|
||||||
int16_t planar_samples[AC3_MAX_CHANNELS][AC3_BLOCK_SIZE+AC3_FRAME_SIZE];
|
int16_t planar_samples[AC3_MAX_CHANNELS][AC3_BLOCK_SIZE+AC3_FRAME_SIZE];
|
||||||
int32_t mdct_coef[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS];
|
int32_t mdct_coef[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS];
|
||||||
uint8_t exp[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS];
|
uint8_t exp[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS];
|
||||||
@ -1189,56 +1300,7 @@ static int ac3_encode_frame(AVCodecContext *avctx,
|
|||||||
|
|
||||||
apply_mdct(s, planar_samples, exp_shift, mdct_coef);
|
apply_mdct(s, planar_samples, exp_shift, mdct_coef);
|
||||||
|
|
||||||
/* extract exponents */
|
frame_bits = process_exponents(s, mdct_coef, exp_shift, exp, exp_strategy, encoded_exp);
|
||||||
for (ch = 0; ch < s->channels; ch++) {
|
|
||||||
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
|
|
||||||
/* compute "exponents". We take into account the normalization there */
|
|
||||||
for (i = 0; i < AC3_MAX_COEFS; i++) {
|
|
||||||
int e;
|
|
||||||
v = abs(mdct_coef[blk][ch][i]);
|
|
||||||
if (v == 0)
|
|
||||||
e = 24;
|
|
||||||
else {
|
|
||||||
e = 23 - av_log2(v) + exp_shift[blk][ch];
|
|
||||||
if (e >= 24) {
|
|
||||||
e = 24;
|
|
||||||
mdct_coef[blk][ch][i] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exp[blk][ch][i] = e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* compute exponent strategies */
|
|
||||||
for (ch = 0; ch < s->channels; ch++) {
|
|
||||||
compute_exp_strategy_ch(exp_strategy, exp, ch, ch == s->lfe_channel);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* encode exponents */
|
|
||||||
frame_bits = 0;
|
|
||||||
for (ch = 0; ch < s->channels; ch++) {
|
|
||||||
/* compute the exponents as the decoder will see them. The
|
|
||||||
EXP_REUSE case must be handled carefully : we select the
|
|
||||||
min of the exponents */
|
|
||||||
blk = 0;
|
|
||||||
while (blk < AC3_MAX_BLOCKS) {
|
|
||||||
blk1 = blk + 1;
|
|
||||||
while (blk1 < AC3_MAX_BLOCKS && exp_strategy[blk1][ch] == EXP_REUSE) {
|
|
||||||
exponent_min(exp[blk][ch], exp[blk1][ch], s->nb_coefs[ch]);
|
|
||||||
blk1++;
|
|
||||||
}
|
|
||||||
frame_bits += encode_exponents_blk_ch(encoded_exp[blk][ch],
|
|
||||||
exp[blk][ch], s->nb_coefs[ch],
|
|
||||||
exp_strategy[blk][ch]);
|
|
||||||
/* copy encoded exponents for reuse case */
|
|
||||||
for (blk2 = blk+1; blk2 < blk1; blk2++) {
|
|
||||||
memcpy(encoded_exp[blk2][ch], encoded_exp[blk][ch],
|
|
||||||
s->nb_coefs[ch] * sizeof(uint8_t));
|
|
||||||
}
|
|
||||||
blk = blk1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* adjust for fractional frame sizes */
|
/* adjust for fractional frame sizes */
|
||||||
while (s->bits_written >= s->bit_rate && s->samples_written >= s->sample_rate) {
|
while (s->bits_written >= s->bit_rate && s->samples_written >= s->sample_rate) {
|
||||||
|
Loading…
Reference in New Issue
Block a user