mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-03 05:10:03 +02:00
aacdec: template TNS application separately
This commit is contained in:
parent
ad16349f9b
commit
db5128ef70
@ -31,6 +31,7 @@
|
||||
|
||||
#include "libavcodec/aacdec.h"
|
||||
#include "libavcodec/aac_defines.h"
|
||||
#include "libavcodec/lpc_functions.h"
|
||||
|
||||
#include "libavcodec/aactab.h"
|
||||
|
||||
@ -174,8 +175,72 @@ static void AAC_RENAME(apply_intensity_stereo)(AACDecContext *ac,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode Temporal Noise Shaping filter coefficients and apply all-pole filters; reference: 4.6.9.3.
|
||||
*
|
||||
* @param decode 1 if tool is used normally, 0 if tool is used in LTP.
|
||||
* @param coef spectral coefficients
|
||||
*/
|
||||
static void AAC_RENAME(apply_tns)(void *_coef_param, TemporalNoiseShaping *tns,
|
||||
IndividualChannelStream *ics, int decode)
|
||||
{
|
||||
const int mmm = FFMIN(ics->tns_max_bands, ics->max_sfb);
|
||||
int w, filt, m, i;
|
||||
int bottom, top, order, start, end, size, inc;
|
||||
INTFLOAT *coef_param = _coef_param;
|
||||
INTFLOAT lpc[TNS_MAX_ORDER];
|
||||
INTFLOAT tmp[TNS_MAX_ORDER+1];
|
||||
UINTFLOAT *coef = coef_param;
|
||||
|
||||
if(!mmm)
|
||||
return;
|
||||
|
||||
for (w = 0; w < ics->num_windows; w++) {
|
||||
bottom = ics->num_swb;
|
||||
for (filt = 0; filt < tns->n_filt[w]; filt++) {
|
||||
top = bottom;
|
||||
bottom = FFMAX(0, top - tns->length[w][filt]);
|
||||
order = tns->order[w][filt];
|
||||
if (order == 0)
|
||||
continue;
|
||||
|
||||
// tns_decode_coef
|
||||
compute_lpc_coefs(tns->AAC_RENAME(coef)[w][filt], order, lpc, 0, 0, 0);
|
||||
|
||||
start = ics->swb_offset[FFMIN(bottom, mmm)];
|
||||
end = ics->swb_offset[FFMIN( top, mmm)];
|
||||
if ((size = end - start) <= 0)
|
||||
continue;
|
||||
if (tns->direction[w][filt]) {
|
||||
inc = -1;
|
||||
start = end - 1;
|
||||
} else {
|
||||
inc = 1;
|
||||
}
|
||||
start += w * 128;
|
||||
|
||||
if (decode) {
|
||||
// ar filter
|
||||
for (m = 0; m < size; m++, start += inc)
|
||||
for (i = 1; i <= FFMIN(m, order); i++)
|
||||
coef[start] -= AAC_MUL26((INTFLOAT)coef[start - i * inc], lpc[i - 1]);
|
||||
} else {
|
||||
// ma filter
|
||||
for (m = 0; m < size; m++, start += inc) {
|
||||
tmp[0] = coef[start];
|
||||
for (i = 1; i <= FFMIN(m, order); i++)
|
||||
coef[start] += AAC_MUL26(tmp[i], lpc[i - 1]);
|
||||
for (i = order; i > 0; i--)
|
||||
tmp[i] = tmp[i - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const AACDecDSP AAC_RENAME(aac_dsp) = {
|
||||
.dequant_scalefactors = &AAC_RENAME(dequant_scalefactors),
|
||||
.apply_mid_side_stereo = &AAC_RENAME(apply_mid_side_stereo),
|
||||
.apply_intensity_stereo = &AAC_RENAME(apply_intensity_stereo),
|
||||
.apply_tns = &AAC_RENAME(apply_tns),
|
||||
};
|
||||
|
@ -311,12 +311,6 @@ struct AACDecContext {
|
||||
/* aacdec functions pointers */
|
||||
void (*imdct_and_windowing)(struct AACDecContext *ac, SingleChannelElement *sce);
|
||||
void (*apply_ltp)(struct AACDecContext *ac, SingleChannelElement *sce);
|
||||
union {
|
||||
void (*apply_tns)(float coef[1024], TemporalNoiseShaping *tns,
|
||||
IndividualChannelStream *ics, int decode);
|
||||
void (*apply_tns_fixed)(int coef[1024], TemporalNoiseShaping *tns,
|
||||
IndividualChannelStream *ics, int decode);
|
||||
};
|
||||
union {
|
||||
void (*windowing_and_mdct_ltp)(struct AACDecContext *ac, float *out,
|
||||
float *in, IndividualChannelStream *ics);
|
||||
|
@ -2367,68 +2367,6 @@ static int decode_extension_payload(AACDecContext *ac, GetBitContext *gb, int cn
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode Temporal Noise Shaping filter coefficients and apply all-pole filters; reference: 4.6.9.3.
|
||||
*
|
||||
* @param decode 1 if tool is used normally, 0 if tool is used in LTP.
|
||||
* @param coef spectral coefficients
|
||||
*/
|
||||
static void apply_tns(INTFLOAT coef_param[1024], TemporalNoiseShaping *tns,
|
||||
IndividualChannelStream *ics, int decode)
|
||||
{
|
||||
const int mmm = FFMIN(ics->tns_max_bands, ics->max_sfb);
|
||||
int w, filt, m, i;
|
||||
int bottom, top, order, start, end, size, inc;
|
||||
INTFLOAT lpc[TNS_MAX_ORDER];
|
||||
INTFLOAT tmp[TNS_MAX_ORDER+1];
|
||||
UINTFLOAT *coef = coef_param;
|
||||
|
||||
if(!mmm)
|
||||
return;
|
||||
|
||||
for (w = 0; w < ics->num_windows; w++) {
|
||||
bottom = ics->num_swb;
|
||||
for (filt = 0; filt < tns->n_filt[w]; filt++) {
|
||||
top = bottom;
|
||||
bottom = FFMAX(0, top - tns->length[w][filt]);
|
||||
order = tns->order[w][filt];
|
||||
if (order == 0)
|
||||
continue;
|
||||
|
||||
// tns_decode_coef
|
||||
compute_lpc_coefs(tns->AAC_RENAME(coef)[w][filt], order, lpc, 0, 0, 0);
|
||||
|
||||
start = ics->swb_offset[FFMIN(bottom, mmm)];
|
||||
end = ics->swb_offset[FFMIN( top, mmm)];
|
||||
if ((size = end - start) <= 0)
|
||||
continue;
|
||||
if (tns->direction[w][filt]) {
|
||||
inc = -1;
|
||||
start = end - 1;
|
||||
} else {
|
||||
inc = 1;
|
||||
}
|
||||
start += w * 128;
|
||||
|
||||
if (decode) {
|
||||
// ar filter
|
||||
for (m = 0; m < size; m++, start += inc)
|
||||
for (i = 1; i <= FFMIN(m, order); i++)
|
||||
coef[start] -= AAC_MUL26((INTFLOAT)coef[start - i * inc], lpc[i - 1]);
|
||||
} else {
|
||||
// ma filter
|
||||
for (m = 0; m < size; m++, start += inc) {
|
||||
tmp[0] = coef[start];
|
||||
for (i = 1; i <= FFMIN(m, order); i++)
|
||||
coef[start] += AAC_MUL26(tmp[i], lpc[i - 1]);
|
||||
for (i = order; i > 0; i--)
|
||||
tmp[i] = tmp[i - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply windowing and MDCT to obtain the spectral
|
||||
* coefficient from the predicted sample by LTP.
|
||||
@ -2479,7 +2417,7 @@ static void apply_ltp(AACDecContext *ac, SingleChannelElement *sce)
|
||||
ac->AAC_RENAME(windowing_and_mdct_ltp)(ac, predFreq, predTime, &sce->ics);
|
||||
|
||||
if (sce->tns.present)
|
||||
ac->AAC_RENAME(apply_tns)(predFreq, &sce->tns, &sce->ics, 0);
|
||||
ac->dsp.apply_tns(predFreq, &sce->tns, &sce->ics, 0);
|
||||
|
||||
for (sfb = 0; sfb < FFMIN(sce->ics.max_sfb, MAX_LTP_LONG_SFB); sfb++)
|
||||
if (ltp->used[sfb])
|
||||
@ -2815,11 +2753,11 @@ static void spectral_to_sample(AACDecContext *ac, int samples)
|
||||
}
|
||||
}
|
||||
if (che->ch[0].tns.present)
|
||||
ac->AAC_RENAME(apply_tns)(che->ch[0].AAC_RENAME(coeffs),
|
||||
&che->ch[0].tns, &che->ch[0].ics, 1);
|
||||
ac->dsp.apply_tns(che->ch[0].AAC_RENAME(coeffs),
|
||||
&che->ch[0].tns, &che->ch[0].ics, 1);
|
||||
if (che->ch[1].tns.present)
|
||||
ac->AAC_RENAME(apply_tns)(che->ch[1].AAC_RENAME(coeffs),
|
||||
&che->ch[1].tns, &che->ch[1].ics, 1);
|
||||
ac->dsp.apply_tns(che->ch[1].AAC_RENAME(coeffs),
|
||||
&che->ch[1].tns, &che->ch[1].ics, 1);
|
||||
if (type <= TYPE_CPE)
|
||||
apply_channel_coupling(ac, che, type, i, BETWEEN_TNS_AND_IMDCT, AAC_RENAME(apply_dependent_coupling));
|
||||
if (type != TYPE_CCE || che->coup.coupling_point == AFTER_IMDCT) {
|
||||
@ -3272,7 +3210,6 @@ static void aacdec_init(AACDecContext *c)
|
||||
{
|
||||
c->imdct_and_windowing = imdct_and_windowing;
|
||||
c->apply_ltp = apply_ltp;
|
||||
c->AAC_RENAME(apply_tns) = apply_tns;
|
||||
c->AAC_RENAME(windowing_and_mdct_ltp) = windowing_and_mdct_ltp;
|
||||
c->update_ltp = update_ltp;
|
||||
#if USE_FIXED
|
||||
|
@ -275,7 +275,7 @@ static void apply_ltp_mips(AACDecContext *ac, SingleChannelElement *sce)
|
||||
ac->windowing_and_mdct_ltp(ac, predFreq, predTime, &sce->ics);
|
||||
|
||||
if (sce->tns.present)
|
||||
ac->apply_tns(predFreq, &sce->tns, &sce->ics, 0);
|
||||
ac->dsp.apply_tns(predFreq, &sce->tns, &sce->ics, 0);
|
||||
|
||||
for (sfb = 0; sfb < FFMIN(sce->ics.max_sfb, MAX_LTP_LONG_SFB); sfb++)
|
||||
if (ltp->used[sfb])
|
||||
|
Loading…
Reference in New Issue
Block a user