aacdec: move from scalefactor ranged arrays to flat arrays

AAC uses an unconventional system to send scalefactors
(the volume+quantization value for each band).
Each window is split into either 1 or 8 blocks (long vs short),
and transformed separately from one another, with the coefficients
for each being also completely independent. The scalefactors
slightly increase from 64 (long) to 128 (short) to accomodate
better per-block-per-band volume for each window.

To reduce overhead, the codec signals scalefactor sizes in an obtuse way,
where each group's scalefactor types are sent via a variable length decoding,
with a range.
But our decoder was written in a way where those ranges were carried through
the entire decoder, and to actually read them you had to use the range.

Instead of having a dedicated array with a range for each scalefactor,
just let the decoder directly index each scalefactor.

This also switches the form of quantized scalefactors to the format
the spec uses, where for intensity stereo and regular, scalefactors
are stored in a scalefactor - 100 form, rather than as-is.

USAC gets rid of the complex scalefactor handling. This commit permits
for code sharing between both.
release/7.1
Lynne 6 months ago
parent caeb275092
commit 39b8d84b53
No known key found for this signature in database
GPG Key ID: A2FEA5F03F034464
  1. 100
      libavcodec/aac/aacdec.c
  2. 5
      libavcodec/aac/aacdec.h
  3. 95
      libavcodec/aac/aacdec_dsp_template.c

@ -1412,13 +1412,13 @@ fail:
*
* @return Returns error status. 0 - OK, !0 - error
*/
static int decode_band_types(AACDecContext *ac, enum BandType band_type[120],
int band_type_run_end[120], GetBitContext *gb,
IndividualChannelStream *ics)
static int decode_band_types(AACDecContext *ac, SingleChannelElement *sce,
GetBitContext *gb)
{
int g, idx = 0;
IndividualChannelStream *ics = &sce->ics;
const int bits = (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) ? 3 : 5;
for (g = 0; g < ics->num_window_groups; g++) {
for (int g = 0; g < ics->num_window_groups; g++) {
int k = 0;
while (k < ics->max_sfb) {
uint8_t sect_end = k;
@ -1442,10 +1442,8 @@ static int decode_band_types(AACDecContext *ac, enum BandType band_type[120],
return AVERROR_INVALIDDATA;
}
} while (sect_len_incr == (1 << bits) - 1);
for (; k < sect_end; k++) {
band_type [idx] = sect_band_type;
band_type_run_end[idx++] = sect_end;
}
for (; k < sect_end; k++)
sce->band_type[g*ics->max_sfb + k] = sect_band_type;
}
}
return 0;
@ -1461,69 +1459,59 @@ static int decode_band_types(AACDecContext *ac, enum BandType band_type[120],
*
* @return Returns error status. 0 - OK, !0 - error
*/
static int decode_scalefactors(AACDecContext *ac, int sfo[120],
GetBitContext *gb,
unsigned int global_gain,
IndividualChannelStream *ics,
enum BandType band_type[120],
int band_type_run_end[120])
static int decode_scalefactors(AACDecContext *ac, SingleChannelElement *sce,
GetBitContext *gb, unsigned int global_gain)
{
int g, i, idx = 0;
IndividualChannelStream *ics = &sce->ics;
int offset[3] = { global_gain, global_gain - NOISE_OFFSET, 0 };
int clipped_offset;
int noise_flag = 1;
for (g = 0; g < ics->num_window_groups; g++) {
for (i = 0; i < ics->max_sfb;) {
int run_end = band_type_run_end[idx];
switch (band_type[idx]) {
for (int g = 0; g < ics->num_window_groups; g++) {
for (int sfb = 0; sfb < ics->max_sfb; sfb++) {
switch (sce->band_type[g*ics->max_sfb + sfb]) {
case ZERO_BT:
for (; i < run_end; i++, idx++)
sfo[idx] = 0;
sce->sfo[g*ics->max_sfb + sfb] = 0;
break;
case INTENSITY_BT: /* fallthrough */
case INTENSITY_BT2:
for (; i < run_end; i++, idx++) {
offset[2] += get_vlc2(gb, ff_vlc_scalefactors, 7, 3) - SCALE_DIFF_ZERO;
clipped_offset = av_clip(offset[2], -155, 100);
if (offset[2] != clipped_offset) {
avpriv_request_sample(ac->avctx,
"If you heard an audible artifact, there may be a bug in the decoder. "
"Clipped intensity stereo position (%d -> %d)",
offset[2], clipped_offset);
}
sfo[idx] = clipped_offset;
offset[2] += get_vlc2(gb, ff_vlc_scalefactors, 7, 3) - SCALE_DIFF_ZERO;
clipped_offset = av_clip(offset[2], -155, 100);
if (offset[2] != clipped_offset) {
avpriv_request_sample(ac->avctx,
"If you heard an audible artifact, there may be a bug in the decoder. "
"Clipped intensity stereo position (%d -> %d)",
offset[2], clipped_offset);
}
sce->sfo[g*ics->max_sfb + sfb] = clipped_offset - 100;
break;
case NOISE_BT:
for (; i < run_end; i++, idx++) {
if (noise_flag-- > 0)
offset[1] += get_bits(gb, NOISE_PRE_BITS) - NOISE_PRE;
else
offset[1] += get_vlc2(gb, ff_vlc_scalefactors, 7, 3) - SCALE_DIFF_ZERO;
clipped_offset = av_clip(offset[1], -100, 155);
if (offset[1] != clipped_offset) {
avpriv_request_sample(ac->avctx,
"If you heard an audible artifact, there may be a bug in the decoder. "
"Clipped noise gain (%d -> %d)",
offset[1], clipped_offset);
}
sfo[idx] = clipped_offset;
if (noise_flag-- > 0)
offset[1] += get_bits(gb, NOISE_PRE_BITS) - NOISE_PRE;
else
offset[1] += get_vlc2(gb, ff_vlc_scalefactors, 7, 3) - SCALE_DIFF_ZERO;
clipped_offset = av_clip(offset[1], -100, 155);
if (offset[1] != clipped_offset) {
avpriv_request_sample(ac->avctx,
"If you heard an audible artifact, there may be a bug in the decoder. "
"Clipped noise gain (%d -> %d)",
offset[1], clipped_offset);
}
sce->sfo[g*ics->max_sfb + sfb] = clipped_offset;
break;
default:
for (; i < run_end; i++, idx++) {
offset[0] += get_vlc2(gb, ff_vlc_scalefactors, 7, 3) - SCALE_DIFF_ZERO;
if (offset[0] > 255U) {
av_log(ac->avctx, AV_LOG_ERROR,
"Scalefactor (%d) out of range.\n", offset[0]);
return AVERROR_INVALIDDATA;
}
sfo[idx] = offset[0];
offset[0] += get_vlc2(gb, ff_vlc_scalefactors, 7, 3) - SCALE_DIFF_ZERO;
if (offset[0] > 255U) {
av_log(ac->avctx, AV_LOG_ERROR,
"Scalefactor (%d) out of range.\n", offset[0]);
return AVERROR_INVALIDDATA;
}
sce->sfo[g*ics->max_sfb + sfb] = offset[0] - 100;
break;
}
}
}
return 0;
}
@ -1680,11 +1668,9 @@ int ff_aac_decode_ics(AACDecContext *ac, SingleChannelElement *sce,
goto fail;
}
if ((ret = decode_band_types(ac, sce->band_type,
sce->band_type_run_end, gb, ics)) < 0)
if ((ret = decode_band_types(ac, sce, gb)) < 0)
goto fail;
if ((ret = decode_scalefactors(ac, sce->sfo, gb, global_gain, ics,
sce->band_type, sce->band_type_run_end)) < 0)
if ((ret = decode_scalefactors(ac, sce, gb, global_gain)) < 0)
goto fail;
ac->dsp.dequant_scalefactors(sce);

@ -146,9 +146,8 @@ typedef struct SingleChannelElement {
IndividualChannelStream ics;
TemporalNoiseShaping tns;
enum BandType band_type[128]; ///< band types
int band_type_run_end[120]; ///< band type run end points
int sfo[120]; ///< scalefactor offsets
INTFLOAT_UNION(sf, [120]); ///< scalefactors
int sfo[128]; ///< scalefactor offsets
INTFLOAT_UNION(sf, [128]); ///< scalefactors (8 windows * 16 sfb max)
INTFLOAT_ALIGNED_UNION(32, coeffs, 1024); ///< coefficients for IMDCT, maybe processed
INTFLOAT_ALIGNED_UNION(32, saved, 1536); ///< overlap
INTFLOAT_ALIGNED_UNION(32, ret_buf, 2048); ///< PCM output buffer

@ -41,47 +41,37 @@
static void AAC_RENAME(dequant_scalefactors)(SingleChannelElement *sce)
{
IndividualChannelStream *ics = &sce->ics;
const enum BandType *band_type = sce->band_type;
const int *band_type_run_end = sce->band_type_run_end;
const int *sfo = sce->sfo;
INTFLOAT *sf = sce->AAC_RENAME(sf);
int g, i, idx = 0;
for (g = 0; g < ics->num_window_groups; g++) {
for (i = 0; i < ics->max_sfb;) {
int run_end = band_type_run_end[idx];
switch (band_type[idx]) {
int idx = 0;
for (int g = 0; g < ics->num_window_groups; g++) {
for (int sfb = 0; sfb < ics->max_sfb; sfb++, idx++) {
switch (sce->band_type[g*ics->max_sfb + sfb]) {
case ZERO_BT:
for (; i < run_end; i++, idx++)
sf[idx] = FIXR(0.);
sf[idx] = FIXR(0.);
break;
case INTENSITY_BT: /* fallthrough */
case INTENSITY_BT2:
for (; i < run_end; i++, idx++) {
#if USE_FIXED
sf[idx] = 100 - sfo[idx];
sf[idx] = 100 - (sfo[idx] + 100);
#else
sf[idx] = ff_aac_pow2sf_tab[-sfo[idx] + POW_SF2_ZERO];
sf[idx] = ff_aac_pow2sf_tab[-sfo[idx] - 100 + POW_SF2_ZERO];
#endif /* USE_FIXED */
}
break;
case NOISE_BT:
for (; i < run_end; i++, idx++) {
#if USE_FIXED
sf[idx] = -(100 + sfo[idx]);
sf[idx] = -(100 + sfo[idx]);
#else
sf[idx] = -ff_aac_pow2sf_tab[sfo[idx] + POW_SF2_ZERO];
sf[idx] = -ff_aac_pow2sf_tab[sfo[idx] + POW_SF2_ZERO];
#endif /* USE_FIXED */
}
break;
default:
for (; i < run_end; i++, idx++) {
#if USE_FIXED
sf[idx] = -sfo[idx];
sf[idx] = -sfo[idx] - 100;
#else
sf[idx] = -ff_aac_pow2sf_tab[sfo[idx] - 100 + POW_SF2_ZERO];
sf[idx] = -ff_aac_pow2sf_tab[sfo[idx] + POW_SF2_ZERO];
#endif /* USE_FIXED */
}
break;
}
}
@ -96,25 +86,23 @@ static void AAC_RENAME(apply_mid_side_stereo)(AACDecContext *ac, ChannelElement
const IndividualChannelStream *ics = &cpe->ch[0].ics;
INTFLOAT *ch0 = cpe->ch[0].AAC_RENAME(coeffs);
INTFLOAT *ch1 = cpe->ch[1].AAC_RENAME(coeffs);
int g, i, group, idx = 0;
const uint16_t *offsets = ics->swb_offset;
for (g = 0; g < ics->num_window_groups; g++) {
for (i = 0; i < ics->max_sfb; i++, idx++) {
for (int g = 0; g < ics->num_window_groups; g++) {
for (int sfb = 0; sfb < ics->max_sfb; sfb++) {
const int idx = g*ics->max_sfb + sfb;
if (cpe->ms_mask[idx] &&
cpe->ch[0].band_type[idx] < NOISE_BT &&
cpe->ch[1].band_type[idx] < NOISE_BT) {
for (int group = 0; group < ics->group_len[g]; group++)
#if USE_FIXED
for (group = 0; group < ics->group_len[g]; group++) {
ac->fdsp->butterflies_fixed(ch0 + group * 128 + offsets[i],
ch1 + group * 128 + offsets[i],
offsets[i+1] - offsets[i]);
ac->fdsp->butterflies_fixed(ch0 + group * 128 + offsets[sfb],
ch1 + group * 128 + offsets[sfb],
offsets[sfb+1] - offsets[sfb]);
#else
for (group = 0; group < ics->group_len[g]; group++) {
ac->fdsp->butterflies_float(ch0 + group * 128 + offsets[i],
ch1 + group * 128 + offsets[i],
offsets[i+1] - offsets[i]);
ac->fdsp->butterflies_float(ch0 + group * 128 + offsets[sfb],
ch1 + group * 128 + offsets[sfb],
offsets[sfb+1] - offsets[sfb]);
#endif /* USE_FIXED */
}
}
}
ch0 += ics->group_len[g] * 128;
@ -136,37 +124,30 @@ static void AAC_RENAME(apply_intensity_stereo)(AACDecContext *ac,
SingleChannelElement *sce1 = &cpe->ch[1];
INTFLOAT *coef0 = cpe->ch[0].AAC_RENAME(coeffs), *coef1 = cpe->ch[1].AAC_RENAME(coeffs);
const uint16_t *offsets = ics->swb_offset;
int g, group, i, idx = 0;
int c;
INTFLOAT scale;
for (g = 0; g < ics->num_window_groups; g++) {
for (i = 0; i < ics->max_sfb;) {
for (int g = 0; g < ics->num_window_groups; g++) {
for (int sfb = 0; sfb < ics->max_sfb; sfb++) {
const int idx = g*ics->max_sfb + sfb;
if (sce1->band_type[idx] == INTENSITY_BT ||
sce1->band_type[idx] == INTENSITY_BT2) {
const int bt_run_end = sce1->band_type_run_end[idx];
for (; i < bt_run_end; i++, idx++) {
c = -1 + 2 * (sce1->band_type[idx] - 14);
if (ms_present)
c *= 1 - 2 * cpe->ms_mask[idx];
scale = c * sce1->AAC_RENAME(sf)[idx];
for (group = 0; group < ics->group_len[g]; group++)
c = -1 + 2 * (sce1->band_type[idx] - 14);
if (ms_present)
c *= 1 - 2 * cpe->ms_mask[idx];
scale = c * sce1->AAC_RENAME(sf)[idx];
for (int group = 0; group < ics->group_len[g]; group++)
#if USE_FIXED
subband_scale(coef1 + group * 128 + offsets[i],
coef0 + group * 128 + offsets[i],
scale,
23,
offsets[i + 1] - offsets[i] ,ac->avctx);
subband_scale(coef1 + group * 128 + offsets[sfb],
coef0 + group * 128 + offsets[sfb],
scale,
23,
offsets[sfb + 1] - offsets[sfb], ac->avctx);
#else
ac->fdsp->vector_fmul_scalar(coef1 + group * 128 + offsets[i],
coef0 + group * 128 + offsets[i],
scale,
offsets[i + 1] - offsets[i]);
ac->fdsp->vector_fmul_scalar(coef1 + group * 128 + offsets[sfb],
coef0 + group * 128 + offsets[sfb],
scale,
offsets[sfb + 1] - offsets[sfb]);
#endif /* USE_FIXED */
}
} else {
int bt_run_end = sce1->band_type_run_end[idx];
idx += bt_run_end - i;
i = bt_run_end;
}
}
coef0 += ics->group_len[g] * 128;

Loading…
Cancel
Save