#include "internal.h"
#include "get_bits.h"
#include "fft.h"
-#include "fmtconvert.h"
+#include "imdct15.h"
#include "lpc.h"
#include "kbdwin.h"
#include "sinewin.h"
enum ChannelPosition che_pos,
int type, int id, int *channels)
{
- if (*channels >= MAX_CHANNELS)
- return AVERROR_INVALIDDATA;
if (che_pos) {
if (!ac->che[type][id]) {
if (!(ac->che[type][id] = av_mallocz(sizeof(ChannelElement))))
ff_aac_sbr_ctx_init(ac, &ac->che[type][id]->sbr);
}
if (type != TYPE_CCE) {
+ if (*channels >= MAX_CHANNELS - 2)
+ return AVERROR_INVALIDDATA;
ac->output_element[(*channels)++] = &ac->che[type][id]->ch[0];
if (type == TYPE_CPE ||
(type == TYPE_SCE && ac->oc[1].m4ac.ps == 1)) {
case AAC_CHANNEL_LFE:
syn_ele = TYPE_LFE;
break;
+ default:
+ // AAC_CHANNEL_OFF has no channel map
+ return;
}
layout_map[0][0] = syn_ele;
layout_map[0][1] = get_bits(gb, 4);
avpriv_request_sample(avctx, "960/120 MDCT window");
return AVERROR_PATCHWELCOME;
}
+ m4ac->frame_length_short = 0;
if (get_bits1(gb)) // dependsOnCoreCoder
skip_bits(gb, 14); // coreCoderDelay
m4ac->ps = 0;
m4ac->sbr = 0;
- if (get_bits1(gb)) { // frameLengthFlag
- avpriv_request_sample(avctx, "960/120 MDCT window");
- return AVERROR_PATCHWELCOME;
- }
-
+ m4ac->frame_length_short = get_bits1(gb);
res_flags = get_bits(gb, 3);
if (res_flags) {
avpriv_report_missing_feature(avctx,
if (len == 15 + 255)
len += get_bits(gb, 16);
if (get_bits_left(gb) < len * 8 + 4) {
- av_log(ac->avctx, AV_LOG_ERROR, overread_err);
+ av_log(avctx, AV_LOG_ERROR, overread_err);
return AVERROR_INVALIDDATA;
}
skip_bits_long(gb, 8 * len);
GetBitContext gb;
int i, ret;
- av_dlog(avctx, "extradata size %d\n", avctx->extradata_size);
+ ff_dlog(avctx, "extradata size %d\n", avctx->extradata_size);
for (i = 0; i < avctx->extradata_size; i++)
- av_dlog(avctx, "%02x ", avctx->extradata[i]);
- av_dlog(avctx, "\n");
+ ff_dlog(avctx, "%02x ", avctx->extradata[i]);
+ ff_dlog(avctx, "\n");
if ((ret = init_get_bits(&gb, data, bit_size)) < 0)
return ret;
return AVERROR(ENOSYS);
}
- av_dlog(avctx,
+ ff_dlog(avctx,
"AOT %d chan config %d sampling index %d (%d) SBR %d PS %d\n",
m4ac->object_type, m4ac->chan_config, m4ac->sampling_index,
m4ac->sample_rate, m4ac->sbr,
ff_aac_sbr_init();
- ff_fmt_convert_init(&ac->fmt_conv, avctx);
avpriv_float_dsp_init(&ac->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
ac->random_state = 0x1f2e3d4c;
ff_mdct_init(&ac->mdct_ld, 10, 1, 1.0 / (32768.0 * 512.0));
ff_mdct_init(&ac->mdct_small, 8, 1, 1.0 / (32768.0 * 128.0));
ff_mdct_init(&ac->mdct_ltp, 11, 0, -2.0 * 32768.0);
+ ret = ff_imdct15_init(&ac->mdct480, 5);
+ if (ret < 0)
+ return ret;
+
// window initialization
ff_kbd_window_init(ff_aac_kbd_long_1024, 4.0, 1024);
- ff_kbd_window_init(ff_aac_kbd_long_512, 4.0, 512);
ff_kbd_window_init(ff_aac_kbd_short_128, 6.0, 128);
ff_init_ff_sine_windows(10);
ff_init_ff_sine_windows( 9);
static int decode_ics_info(AACContext *ac, IndividualChannelStream *ics,
GetBitContext *gb)
{
- int aot = ac->oc[1].m4ac.object_type;
+ const MPEG4AudioConfig *const m4ac = &ac->oc[1].m4ac;
+ const int aot = m4ac->object_type;
+ const int sampling_index = m4ac->sampling_index;
if (aot != AOT_ER_AAC_ELD) {
if (get_bits1(gb)) {
av_log(ac->avctx, AV_LOG_ERROR, "Reserved bit set.\n");
- return AVERROR_INVALIDDATA;
+ if (ac->avctx->err_recognition & AV_EF_BITSTREAM)
+ return AVERROR_INVALIDDATA;
}
ics->window_sequence[1] = ics->window_sequence[0];
ics->window_sequence[0] = get_bits(gb, 2);
}
}
ics->num_windows = 8;
- ics->swb_offset = ff_swb_offset_128[ac->oc[1].m4ac.sampling_index];
- ics->num_swb = ff_aac_num_swb_128[ac->oc[1].m4ac.sampling_index];
- ics->tns_max_bands = ff_tns_max_bands_128[ac->oc[1].m4ac.sampling_index];
+ ics->swb_offset = ff_swb_offset_128[sampling_index];
+ ics->num_swb = ff_aac_num_swb_128[sampling_index];
+ ics->tns_max_bands = ff_tns_max_bands_128[sampling_index];
ics->predictor_present = 0;
} else {
- ics->max_sfb = get_bits(gb, 6);
- ics->num_windows = 1;
+ ics->max_sfb = get_bits(gb, 6);
+ ics->num_windows = 1;
if (aot == AOT_ER_AAC_LD || aot == AOT_ER_AAC_ELD) {
- ics->swb_offset = ff_swb_offset_512[ac->oc[1].m4ac.sampling_index];
- ics->num_swb = ff_aac_num_swb_512[ac->oc[1].m4ac.sampling_index];
+ if (m4ac->frame_length_short) {
+ ics->swb_offset = ff_swb_offset_480[sampling_index];
+ ics->num_swb = ff_aac_num_swb_480[sampling_index];
+ ics->tns_max_bands = ff_tns_max_bands_480[sampling_index];
+ } else {
+ ics->swb_offset = ff_swb_offset_512[sampling_index];
+ ics->num_swb = ff_aac_num_swb_512[sampling_index];
+ ics->tns_max_bands = ff_tns_max_bands_512[sampling_index];
+ }
if (!ics->num_swb || !ics->swb_offset)
return AVERROR_BUG;
} else {
- ics->swb_offset = ff_swb_offset_1024[ac->oc[1].m4ac.sampling_index];
- ics->num_swb = ff_aac_num_swb_1024[ac->oc[1].m4ac.sampling_index];
+ ics->swb_offset = ff_swb_offset_1024[sampling_index];
+ ics->num_swb = ff_aac_num_swb_1024[sampling_index];
+ ics->tns_max_bands = ff_tns_max_bands_1024[sampling_index];
}
- ics->tns_max_bands = ff_tns_max_bands_1024[ac->oc[1].m4ac.sampling_index];
if (aot != AOT_ER_AAC_ELD) {
ics->predictor_present = get_bits1(gb);
ics->predictor_reset_group = 0;
int ms_present)
{
int idx;
+ int max_idx = cpe->ch[0].ics.num_window_groups * cpe->ch[0].ics.max_sfb;
if (ms_present == 1) {
- for (idx = 0;
- idx < cpe->ch[0].ics.num_window_groups * cpe->ch[0].ics.max_sfb;
- idx++)
+ for (idx = 0; idx < max_idx; idx++)
cpe->ms_mask[idx] = get_bits1(gb);
} else if (ms_present == 2) {
- memset(cpe->ms_mask, 1, cpe->ch[0].ics.num_window_groups * cpe->ch[0].ics.max_sfb * sizeof(cpe->ms_mask[0]));
+ memset(cpe->ms_mask, 1, max_idx * sizeof(cpe->ms_mask[0]));
}
}
float *in = sce->coeffs;
float *out = sce->ret;
float *saved = sce->saved;
- const float *lwindow_prev = ics->use_kb_window[1] ? ff_aac_kbd_long_512 : ff_sine_512;
float *buf = ac->buf_mdct;
// imdct
ac->mdct.imdct_half(&ac->mdct_ld, buf, in);
// window overlapping
- ac->fdsp.vector_fmul_window(out, saved, buf, lwindow_prev, 256);
+ if (ics->use_kb_window[1]) {
+ // AAC LD uses a low overlap sine window instead of a KBD window
+ memcpy(out, saved, 192 * sizeof(float));
+ ac->fdsp.vector_fmul_window(out + 192, saved + 192, buf, ff_sine_128, 64);
+ memcpy( out + 320, buf + 64, 192 * sizeof(float));
+ } else {
+ ac->fdsp.vector_fmul_window(out, saved, buf, ff_sine_512, 256);
+ }
// buffer update
memcpy(saved, buf + 256, 256 * sizeof(float));
float *in = sce->coeffs;
float *out = sce->ret;
float *saved = sce->saved;
- const float *const window = ff_aac_eld_window;
float *buf = ac->buf_mdct;
int i;
- const int n = 512;
+ const int n = ac->oc[1].m4ac.frame_length_short ? 480 : 512;
const int n2 = n >> 1;
const int n4 = n >> 2;
+ const float *const window = n == 480 ? ff_aac_eld_window_480 :
+ ff_aac_eld_window_512;
// Inverse transform, mapped to the conventional IMDCT by
// Chivukula, R.K.; Reznik, Y.A.; Devarajan, V.,
temp = in[i ]; in[i ] = -in[n - 1 - i]; in[n - 1 - i] = temp;
temp = -in[i + 1]; in[i + 1] = in[n - 2 - i]; in[n - 2 - i] = temp;
}
- ac->mdct.imdct_half(&ac->mdct_ld, buf, in);
+ if (n == 480)
+ ac->mdct480->imdct_half(ac->mdct480, buf, in, 1, -1.f/(16*1024*960));
+ else
+ ac->mdct.imdct_half(&ac->mdct_ld, buf, in);
for (i = 0; i < n; i+=2) {
buf[i] = -buf[i];
}
const float gain = cce->coup.gain[index][idx];
for (group = 0; group < ics->group_len[g]; group++) {
for (k = offsets[i]; k < offsets[i + 1]; k++) {
- // XXX dsputil-ize
+ // FIXME: SIMDify
dest[group * 128 + k] += gain * src[group * 128 + k];
}
}
ac->oc[1].m4ac.sample_rate = hdr_info.sample_rate;
ac->oc[1].m4ac.sampling_index = hdr_info.sampling_index;
ac->oc[1].m4ac.object_type = hdr_info.object_type;
+ ac->oc[1].m4ac.frame_length_short = 0;
if (ac->oc[0].status != OC_LOCKED ||
ac->oc[0].m4ac.chan_config != hdr_info.chan_config ||
ac->oc[0].m4ac.sample_rate != hdr_info.sample_rate) {
int *got_frame_ptr, GetBitContext *gb)
{
AACContext *ac = avctx->priv_data;
+ const MPEG4AudioConfig *const m4ac = &ac->oc[1].m4ac;
ChannelElement *che;
int err, i;
- int samples = 1024;
- int chan_config = ac->oc[1].m4ac.chan_config;
- int aot = ac->oc[1].m4ac.object_type;
+ int samples = m4ac->frame_length_short ? 960 : 1024;
+ int chan_config = m4ac->chan_config;
+ int aot = m4ac->object_type;
if (aot == AOT_ER_AAC_LD || aot == AOT_ER_AAC_ELD)
samples >>= 1;
// The FF_PROFILE_AAC_* defines are all object_type - 1
// This may lead to an undefined profile being signaled
- ac->avctx->profile = ac->oc[1].m4ac.object_type - 1;
+ ac->avctx->profile = aot - 1;
ac->tags_mapped = 0;
if (chan_config < 0 || chan_config >= 8) {
avpriv_request_sample(avctx, "Unknown ER channel configuration %d",
- ac->oc[1].m4ac.chan_config);
+ chan_config);
return AVERROR_INVALIDDATA;
}
for (i = 0; i < tags_per_config[chan_config]; i++) {
spectral_to_sample(ac);
ac->frame->nb_samples = samples;
+ ac->frame->sample_rate = avctx->sample_rate;
*got_frame_ptr = 1;
skip_bits_long(gb, get_bits_left(gb));
multiplier = (ac->oc[1].m4ac.sbr == 1) ? ac->oc[1].m4ac.ext_sample_rate > ac->oc[1].m4ac.sample_rate : 0;
samples <<= multiplier;
- if (samples)
- ac->frame->nb_samples = samples;
- *got_frame_ptr = !!samples;
-
if (ac->oc[1].status && audio_found) {
avctx->sample_rate = ac->oc[1].m4ac.sample_rate << multiplier;
avctx->frame_size = samples;
ac->oc[1].status = OC_LOCKED;
}
+ if (samples) {
+ ac->frame->nb_samples = samples;
+ ac->frame->sample_rate = avctx->sample_rate;
+ }
+ *got_frame_ptr = !!samples;
+
return 0;
fail:
pop_output_configuration(ac);
ff_mdct_end(&ac->mdct_small);
ff_mdct_end(&ac->mdct_ld);
ff_mdct_end(&ac->mdct_ltp);
+ ff_imdct15_uninit(&ac->mdct480);
return 0;
}
if (bits_consumed < 0)
return AVERROR_INVALIDDATA;
- if (ac->oc[1].m4ac.sample_rate != m4ac.sample_rate ||
+ if (!latmctx->initialized ||
+ ac->oc[1].m4ac.sample_rate != m4ac.sample_rate ||
ac->oc[1].m4ac.chan_config != m4ac.chan_config) {
av_log(avctx, AV_LOG_INFO, "audio config changed\n");
return AVERROR_INVALIDDATA;
}
- if ((err = aac_decode_frame_int(avctx, out, got_frame_ptr, &gb)) < 0)
+ switch (latmctx->aac_ctx.oc[1].m4ac.object_type) {
+ case AOT_ER_AAC_LC:
+ case AOT_ER_AAC_LTP:
+ case AOT_ER_AAC_LD:
+ case AOT_ER_AAC_ELD:
+ err = aac_decode_er_frame(avctx, out, got_frame_ptr, &gb);
+ break;
+ default:
+ err = aac_decode_frame_int(avctx, out, got_frame_ptr, &gb);
+ }
+ if (err < 0)
return err;
return muxlength;