#include "sbr.h"
#include "aacsbr.h"
#include "mpeg4audio.h"
-#include "aac_parser.h"
+#include "aacadtsdec.h"
#include <assert.h>
#include <errno.h>
static ChannelElement *get_che(AACContext *ac, int type, int elem_id)
{
- /* Some buggy encoders appear to set all elem_ids to zero and rely on
- channels always occurring in the same order. This is expressly forbidden
- by the spec but we will try to work around it.
- */
- int err_printed = 0;
- while (ac->tags_seen_this_frame[type][elem_id] && elem_id < MAX_ELEM_ID) {
- if (ac->output_configured < OC_LOCKED && !err_printed) {
- av_log(ac->avctx, AV_LOG_WARNING, "Duplicate channel tag found, attempting to remap.\n");
- err_printed = 1;
- }
- elem_id++;
- }
- if (elem_id == MAX_ELEM_ID)
- return NULL;
- ac->tags_seen_this_frame[type][elem_id] = 1;
-
- if (ac->tag_che_map[type][elem_id]) {
+ // For PCE based channel configurations map the channels solely based on tags.
+ if (!ac->m4ac.chan_config) {
return ac->tag_che_map[type][elem_id];
}
- if (ac->tags_mapped >= tags_per_config[ac->m4ac.chan_config]) {
- return NULL;
- }
+ // For indexed channel configurations map the channels solely based on position.
switch (ac->m4ac.chan_config) {
case 7:
if (ac->tags_mapped == 3 && type == TYPE_CPE) {
}
memset(ac->tag_che_map, 0, 4 * MAX_ELEM_ID * sizeof(ac->che[0][0]));
- ac->tags_mapped = 0;
avctx->channel_layout = aac_channel_layout[channel_config - 1];
} else {
}
memcpy(ac->tag_che_map, ac->che, 4 * MAX_ELEM_ID * sizeof(ac->che[0][0]));
- ac->tags_mapped = 4 * MAX_ELEM_ID;
avctx->channel_layout = 0;
}
static av_cold int aac_decode_init(AVCodecContext *avctx)
{
AACContext *ac = avctx->priv_data;
- int i;
ac->avctx = avctx;
ac->m4ac.sample_rate = avctx->sample_rate;
ac->sf_offset = 60;
}
-#if !CONFIG_HARDCODED_TABLES
- for (i = 0; i < 428; i++)
- ff_aac_pow2sf_tab[i] = pow(2, (i - 200) / 4.);
-#endif /* CONFIG_HARDCODED_TABLES */
+ ff_aac_tableinit();
INIT_VLC_STATIC(&vlc_scalefactors,7,FF_ARRAY_ELEMS(ff_aac_scalefactor_code),
ff_aac_scalefactor_bits, sizeof(ff_aac_scalefactor_bits[0]), sizeof(ff_aac_scalefactor_bits[0]),
const int c = 1024 / ics->num_windows;
const uint16_t *offsets = ics->swb_offset;
float *coef_base = coef;
- int err_idx;
for (g = 0; g < ics->num_windows; g++)
memset(coef + g * 128 + offsets[ics->max_sfb], 0, sizeof(float) * (c - offsets[ics->max_sfb]));
const float *vq = ff_aac_codebook_vector_vals[cbt_m1];
const uint16_t *cb_vector_idx = ff_aac_codebook_vector_idx[cbt_m1];
VLC_TYPE (*vlc_tab)[2] = vlc_spectral[cbt_m1].table;
- const int cb_size = ff_aac_spectral_sizes[cbt_m1];
OPEN_READER(re, gb);
switch (cbt_m1 >> 1) {
UPDATE_CACHE(re, gb);
GET_VLC(code, re, gb, vlc_tab, 8, 2);
-
- if (code >= cb_size) {
- err_idx = code;
- goto err_cb_overflow;
- }
-
cb_idx = cb_vector_idx[code];
cf = VMUL4(cf, vq, cb_idx, sf + idx);
} while (len -= 4);
UPDATE_CACHE(re, gb);
GET_VLC(code, re, gb, vlc_tab, 8, 2);
-
- if (code >= cb_size) {
- err_idx = code;
- goto err_cb_overflow;
- }
-
#if MIN_CACHE_BITS < 20
UPDATE_CACHE(re, gb);
#endif
UPDATE_CACHE(re, gb);
GET_VLC(code, re, gb, vlc_tab, 8, 2);
-
- if (code >= cb_size) {
- err_idx = code;
- goto err_cb_overflow;
- }
-
cb_idx = cb_vector_idx[code];
cf = VMUL2(cf, vq, cb_idx, sf + idx);
} while (len -= 2);
UPDATE_CACHE(re, gb);
GET_VLC(code, re, gb, vlc_tab, 8, 2);
-
- if (code >= cb_size) {
- err_idx = code;
- goto err_cb_overflow;
- }
-
cb_idx = cb_vector_idx[code];
nnz = cb_idx >> 8 & 15;
sign = SHOW_UBITS(re, gb, nnz) << (cb_idx >> 12);
continue;
}
- if (code >= cb_size) {
- err_idx = code;
- goto err_cb_overflow;
- }
-
cb_idx = cb_vector_idx[code];
nnz = cb_idx >> 12;
nzt = cb_idx >> 8;
}
}
return 0;
-
-err_cb_overflow:
- av_log(ac->avctx, AV_LOG_ERROR,
- "Read beyond end of ff_aac_codebook_vectors[%d][]. index %d >= %d\n",
- band_type[idx], err_idx, ff_aac_spectral_sizes[band_type[idx]]);
- return -1;
}
static av_always_inline float flt16_round(float pf)
return pun.f;
}
-static av_always_inline void predict(AACContext *ac, PredictorState *ps, float *coef,
+static av_always_inline void predict(PredictorState *ps, float *coef,
+ float sf_scale, float inv_sf_scale,
int output_enable)
{
const float a = 0.953125; // 61.0 / 64
float e0, e1;
float pv;
float k1, k2;
+ float r0 = ps->r0, r1 = ps->r1;
+ float cor0 = ps->cor0, cor1 = ps->cor1;
+ float var0 = ps->var0, var1 = ps->var1;
- k1 = ps->var0 > 1 ? ps->cor0 * flt16_even(a / ps->var0) : 0;
- k2 = ps->var1 > 1 ? ps->cor1 * flt16_even(a / ps->var1) : 0;
+ k1 = var0 > 1 ? cor0 * flt16_even(a / var0) : 0;
+ k2 = var1 > 1 ? cor1 * flt16_even(a / var1) : 0;
- pv = flt16_round(k1 * ps->r0 + k2 * ps->r1);
+ pv = flt16_round(k1 * r0 + k2 * r1);
if (output_enable)
- *coef += pv * ac->sf_scale;
+ *coef += pv * sf_scale;
- e0 = *coef / ac->sf_scale;
- e1 = e0 - k1 * ps->r0;
+ e0 = *coef * inv_sf_scale;
+ e1 = e0 - k1 * r0;
- ps->cor1 = flt16_trunc(alpha * ps->cor1 + ps->r1 * e1);
- ps->var1 = flt16_trunc(alpha * ps->var1 + 0.5 * (ps->r1 * ps->r1 + e1 * e1));
- ps->cor0 = flt16_trunc(alpha * ps->cor0 + ps->r0 * e0);
- ps->var0 = flt16_trunc(alpha * ps->var0 + 0.5 * (ps->r0 * ps->r0 + e0 * e0));
+ ps->cor1 = flt16_trunc(alpha * cor1 + r1 * e1);
+ ps->var1 = flt16_trunc(alpha * var1 + 0.5f * (r1 * r1 + e1 * e1));
+ ps->cor0 = flt16_trunc(alpha * cor0 + r0 * e0);
+ ps->var0 = flt16_trunc(alpha * var0 + 0.5f * (r0 * r0 + e0 * e0));
- ps->r1 = flt16_trunc(a * (ps->r0 - k1 * e0));
+ ps->r1 = flt16_trunc(a * (r0 - k1 * e0));
ps->r0 = flt16_trunc(a * e0);
}
static void apply_prediction(AACContext *ac, SingleChannelElement *sce)
{
int sfb, k;
+ float sf_scale = ac->sf_scale, inv_sf_scale = 1 / ac->sf_scale;
if (!sce->ics.predictor_initialized) {
reset_all_predictors(sce->predictor_state);
if (sce->ics.window_sequence[0] != EIGHT_SHORT_SEQUENCE) {
for (sfb = 0; sfb < ff_aac_pred_sfb_max[ac->m4ac.sampling_index]; sfb++) {
for (k = sce->ics.swb_offset[sfb]; k < sce->ics.swb_offset[sfb + 1]; k++) {
- predict(ac, &sce->predictor_state[k], &sce->coeffs[k],
+ predict(&sce->predictor_state[k], &sce->coeffs[k],
+ sf_scale, inv_sf_scale,
sce->ics.predictor_present && sce->ics.prediction_used[sfb]);
}
}
/**
* Decode a channel_pair_element; reference: table 4.4.
*
- * @param elem_id Identifies the instance of a syntax element.
- *
* @return Returns error status. 0 - OK, !0 - error
*/
static int decode_cpe(AACContext *ac, GetBitContext *gb, ChannelElement *cpe)
return 0;
}
+static const float cce_scale[] = {
+ 1.09050773266525765921, //2^(1/8)
+ 1.18920711500272106672, //2^(1/4)
+ M_SQRT2,
+ 2,
+};
+
/**
* Decode coupling_channel_element; reference: table 4.8.
*
- * @param elem_id Identifies the instance of a syntax element.
- *
* @return Returns error status. 0 - OK, !0 - error
*/
static int decode_cce(AACContext *ac, GetBitContext *gb, ChannelElement *che)
coup->coupling_point += get_bits1(gb) || (coup->coupling_point >> 1);
sign = get_bits(gb, 1);
- scale = pow(2., pow(2., (int)get_bits(gb, 2) - 3));
+ scale = cce_scale[get_bits(gb, 2)];
if ((ret = decode_ics(ac, sce, gb, 0, 0)))
return ret;
if (c) {
cge = coup->coupling_point == AFTER_IMDCT ? 1 : get_bits1(gb);
gain = cge ? get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60: 0;
- gain_cache = pow(scale, -gain);
+ gain_cache = powf(scale, -gain);
}
if (coup->coupling_point == AFTER_IMDCT) {
coup->gain[c][0] = gain_cache;
s -= 2 * (t & 0x1);
t >>= 1;
}
- gain_cache = pow(scale, -t) * s;
+ gain_cache = powf(scale, -t) * s;
}
}
coup->gain[c][idx] = gain_cache;
// imdct
if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
- if (ics->window_sequence[1] == ONLY_LONG_SEQUENCE || ics->window_sequence[1] == LONG_STOP_SEQUENCE)
- av_log(ac->avctx, AV_LOG_WARNING,
- "Transition from an ONLY_LONG or LONG_STOP to an EIGHT_SHORT sequence detected. "
- "If you heard an audible artifact, please submit the sample to the FFmpeg developers.\n");
for (i = 0; i < 1024; i += 128)
ff_imdct_half(&ac->mdct_small, buf + i, in + i);
} else
/**
* channel coupling transformation interface
*
- * @param index index into coupling gain array
* @param apply_coupling_method pointer to (in)dependent coupling function
*/
static void apply_channel_coupling(AACContext *ac, ChannelElement *cc,
}
}
- memset(ac->tags_seen_this_frame, 0, sizeof(ac->tags_seen_this_frame));
+ ac->tags_mapped = 0;
// parse
while ((elem_type = get_bits(&gb, 3)) != TYPE_END) {
elem_id = get_bits(&gb, 4);
- if (elem_type < TYPE_DSE && !(che=get_che(ac, elem_type, elem_id))) {
- av_log(ac->avctx, AV_LOG_ERROR, "channel element %d.%d is not allocated\n", elem_type, elem_id);
- return -1;
- }
-
- if (elem_type < TYPE_DSE)
+ if (elem_type < TYPE_DSE) {
+ if (!(che=get_che(ac, elem_type, elem_id))) {
+ av_log(ac->avctx, AV_LOG_ERROR, "channel element %d.%d is not allocated\n",
+ elem_type, elem_id);
+ return -1;
+ }
samples = 1024;
+ }
switch (elem_type) {
*data_size = data_size_tmp;
if (samples)
- ac->dsp.float_to_int16_interleave(data, (const float **)ac->output_data, samples, avctx->channels);
+ ac->dsp.float_to_int16_interleave(data, (const float **)ac->output_data, samples, avctx->channels);
if (ac->output_configured)
ac->output_configured = OC_LOCKED;