Newer
Older
*
* @return Returns error status. 0 - OK, !0 - error
*/
static int decode_ics(AACContext * ac, SingleChannelElement * sce, GetBitContext * gb, int common_window, int scale_flag) {
Pulse pulse;
TemporalNoiseShaping * tns = &sce->tns;
IndividualChannelStream * ics = &sce->ics;
float * out = sce->coeffs;
int global_gain, pulse_present = 0;
/* This assignment is to silence a GCC warning about the variable being used
* uninitialized when in fact it always is.
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
*/
pulse.num_pulse = 0;
global_gain = get_bits(gb, 8);
if (!common_window && !scale_flag) {
if (decode_ics_info(ac, ics, gb, 0) < 0)
return -1;
}
if (decode_band_types(ac, sce->band_type, sce->band_type_run_end, gb, ics) < 0)
return -1;
if (decode_scalefactors(ac, sce->sf, gb, global_gain, ics, sce->band_type, sce->band_type_run_end) < 0)
return -1;
pulse_present = 0;
if (!scale_flag) {
if ((pulse_present = get_bits1(gb))) {
if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
av_log(ac->avccontext, AV_LOG_ERROR, "Pulse tool not allowed in eight short sequence.\n");
return -1;
}
Alex Converse
committed
if (decode_pulses(&pulse, gb, ics->swb_offset, ics->num_swb)) {
av_log(ac->avccontext, AV_LOG_ERROR, "Pulse data corrupt or invalid.\n");
return -1;
}
}
if ((tns->present = get_bits1(gb)) && decode_tns(ac, tns, gb, ics))
return -1;
if (get_bits1(gb)) {
av_log_missing_feature(ac->avccontext, "SSR", 1);
return -1;
}
}
if (decode_spectrum_and_dequant(ac, out, gb, sce->sf, pulse_present, &pulse, ics, sce->band_type) < 0)
if(ac->m4ac.object_type == AOT_AAC_MAIN && !common_window)
apply_prediction(ac, sce);
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
/**
* Mid/Side stereo decoding; reference: 4.6.8.1.3.
*/
static void apply_mid_side_stereo(ChannelElement * cpe) {
const IndividualChannelStream * ics = &cpe->ch[0].ics;
float *ch0 = cpe->ch[0].coeffs;
float *ch1 = cpe->ch[1].coeffs;
int g, i, k, 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++) {
if (cpe->ms_mask[idx] &&
cpe->ch[0].band_type[idx] < NOISE_BT && cpe->ch[1].band_type[idx] < NOISE_BT) {
for (group = 0; group < ics->group_len[g]; group++) {
for (k = offsets[i]; k < offsets[i+1]; k++) {
float tmp = ch0[group*128 + k] - ch1[group*128 + k];
ch0[group*128 + k] += ch1[group*128 + k];
ch1[group*128 + k] = tmp;
}
}
}
}
ch0 += ics->group_len[g]*128;
ch1 += ics->group_len[g]*128;
}
}
/**
* intensity stereo decoding; reference: 4.6.8.2.3
*
* @param ms_present Indicates mid/side stereo presence. [0] mask is all 0s;
* [1] mask is decoded from bitstream; [2] mask is all 1s;
* [3] reserved for scalable AAC
*/
static void apply_intensity_stereo(ChannelElement * cpe, int ms_present) {
const IndividualChannelStream * ics = &cpe->ch[1].ics;
SingleChannelElement * sce1 = &cpe->ch[1];
float *coef0 = cpe->ch[0].coeffs, *coef1 = cpe->ch[1].coeffs;
const uint16_t * offsets = ics->swb_offset;
int g, group, i, k, idx = 0;
int c;
float scale;
for (g = 0; g < ics->num_window_groups; g++) {
for (i = 0; i < ics->max_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->sf[idx];
for (group = 0; group < ics->group_len[g]; group++)
for (k = offsets[i]; k < offsets[i+1]; k++)
coef1[group*128 + k] = scale * coef0[group*128 + k];
}
} 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;
coef1 += ics->group_len[g]*128;
}
}
/**
* 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
*/
Alex Converse
committed
static int decode_cpe(AACContext * ac, GetBitContext * gb, ChannelElement * cpe) {
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
int i, ret, common_window, ms_present = 0;
common_window = get_bits1(gb);
if (common_window) {
if (decode_ics_info(ac, &cpe->ch[0].ics, gb, 1))
return -1;
i = cpe->ch[1].ics.use_kb_window[0];
cpe->ch[1].ics = cpe->ch[0].ics;
cpe->ch[1].ics.use_kb_window[1] = i;
ms_present = get_bits(gb, 2);
if(ms_present == 3) {
av_log(ac->avccontext, AV_LOG_ERROR, "ms_present = 3 is reserved.\n");
return -1;
} else if(ms_present)
decode_mid_side_stereo(cpe, gb, ms_present);
}
if ((ret = decode_ics(ac, &cpe->ch[0], gb, common_window, 0)))
return ret;
if ((ret = decode_ics(ac, &cpe->ch[1], gb, common_window, 0)))
return ret;
if (common_window) {
if (ms_present)
if (ac->m4ac.object_type == AOT_AAC_MAIN) {
apply_prediction(ac, &cpe->ch[0]);
apply_prediction(ac, &cpe->ch[1]);
}
}
apply_intensity_stereo(cpe, ms_present);
/**
* 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) {
int num_gain = 0;
Robert Swain
committed
int c, g, sfb, ret;
int sign;
float scale;
SingleChannelElement * sce = &che->ch[0];
ChannelCoupling * coup = &che->coup;
coup->coupling_point = 2*get_bits1(gb);
coup->num_coupled = get_bits(gb, 3);
for (c = 0; c <= coup->num_coupled; c++) {
num_gain++;
coup->type[c] = get_bits1(gb) ? TYPE_CPE : TYPE_SCE;
coup->id_select[c] = get_bits(gb, 4);
if (coup->type[c] == TYPE_CPE) {
coup->ch_select[c] = get_bits(gb, 2);
if (coup->ch_select[c] == 3)
num_gain++;
} else
coup->ch_select[c] = 2;
coup->coupling_point += get_bits1(gb) || (coup->coupling_point>>1);
Alex Converse
committed
scale = pow(2., pow(2., (int)get_bits(gb, 2) - 3));
if ((ret = decode_ics(ac, sce, gb, 0, 0)))
return ret;
for (c = 0; c < num_gain; c++) {
Robert Swain
committed
int idx = 0;
int cge = 1;
int gain = 0;
float gain_cache = 1.;
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);
Alex Converse
committed
if (coup->coupling_point == AFTER_IMDCT) {
coup->gain[c][0] = gain_cache;
} else {
for (g = 0; g < sce->ics.num_window_groups; g++) {
for (sfb = 0; sfb < sce->ics.max_sfb; sfb++, idx++) {
if (sce->band_type[idx] != ZERO_BT) {
if (!cge) {
int t = get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60;
if (t) {
int s = 1;
t = gain += t;
if (sign) {
s -= 2 * (t & 0x1);
t >>= 1;
}
gain_cache = pow(scale, -t) * s;
/**
* Decode Spectral Band Replication extension data; reference: table 4.55.
Robert Swain
committed
*
* @param crc flag indicating the presence of CRC checksum
* @param cnt length of TYPE_FIL syntactic element in bytes
Robert Swain
committed
* @return Returns number of bytes consumed from the TYPE_FIL element.
*/
static int decode_sbr_extension(AACContext * ac, GetBitContext * gb, int crc, int cnt) {
// TODO : sbr_extension implementation
av_log_missing_feature(ac->avccontext, "SBR", 0);
Robert Swain
committed
skip_bits_long(gb, 8*cnt - 4); // -4 due to reading extension type
return cnt;
}
/**
* Parse whether channels are to be excluded from Dynamic Range Compression; reference: table 4.53.
*
* @return Returns number of bytes consumed.
*/
static int decode_drc_channel_exclusions(DynamicRangeControl *che_drc, GetBitContext * gb) {
int i;
int num_excl_chan = 0;
do {
for (i = 0; i < 7; i++)
che_drc->exclude_mask[num_excl_chan++] = get_bits1(gb);
} while (num_excl_chan < MAX_CHANNELS - 7 && get_bits1(gb));
return num_excl_chan / 7;
}
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
/**
* Decode dynamic range information; reference: table 4.52.
*
* @param cnt length of TYPE_FIL syntactic element in bytes
*
* @return Returns number of bytes consumed.
*/
static int decode_dynamic_range(DynamicRangeControl *che_drc, GetBitContext * gb, int cnt) {
int n = 1;
int drc_num_bands = 1;
int i;
/* pce_tag_present? */
if(get_bits1(gb)) {
che_drc->pce_instance_tag = get_bits(gb, 4);
skip_bits(gb, 4); // tag_reserved_bits
n++;
}
/* excluded_chns_present? */
if(get_bits1(gb)) {
n += decode_drc_channel_exclusions(che_drc, gb);
}
/* drc_bands_present? */
if (get_bits1(gb)) {
che_drc->band_incr = get_bits(gb, 4);
che_drc->interpolation_scheme = get_bits(gb, 4);
n++;
drc_num_bands += che_drc->band_incr;
for (i = 0; i < drc_num_bands; i++) {
che_drc->band_top[i] = get_bits(gb, 8);
n++;
}
}
/* prog_ref_level_present? */
if (get_bits1(gb)) {
che_drc->prog_ref_level = get_bits(gb, 7);
skip_bits1(gb); // prog_ref_level_reserved_bits
n++;
}
for (i = 0; i < drc_num_bands; i++) {
che_drc->dyn_rng_sgn[i] = get_bits1(gb);
che_drc->dyn_rng_ctl[i] = get_bits(gb, 7);
n++;
}
return n;
}
/**
* Decode extension data (incomplete); reference: table 4.51.
*
* @param cnt length of TYPE_FIL syntactic element in bytes
*
* @return Returns number of bytes consumed
*/
static int decode_extension_payload(AACContext * ac, GetBitContext * gb, int cnt) {
Robert Swain
committed
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
int crc_flag = 0;
int res = cnt;
switch (get_bits(gb, 4)) { // extension type
case EXT_SBR_DATA_CRC:
crc_flag++;
case EXT_SBR_DATA:
res = decode_sbr_extension(ac, gb, crc_flag, cnt);
break;
case EXT_DYNAMIC_RANGE:
res = decode_dynamic_range(&ac->che_drc, gb, cnt);
break;
case EXT_FILL:
case EXT_FILL_DATA:
case EXT_DATA_ELEMENT:
default:
skip_bits_long(gb, 8*cnt - 4);
break;
};
return res;
}
Robert Swain
committed
/**
* 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(float coef[1024], TemporalNoiseShaping * tns, IndividualChannelStream * ics, int decode) {
const int mmm = FFMIN(ics->tns_max_bands, ics->max_sfb);
Robert Swain
committed
int bottom, top, order, start, end, size, inc;
float lpc[TNS_MAX_ORDER];
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;
Vitor Sessak
committed
// tns_decode_coef
compute_lpc_coefs(tns->coef[w][filt], order, lpc, 0, 0, 0);
Robert Swain
committed
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;
// ar filter
for (m = 0; m < size; m++, start += inc)
for (i = 1; i <= FFMIN(m, order); i++)
Robert Swain
committed
coef[start] -= coef[start - i*inc] * lpc[i-1];
/**
* Conduct IMDCT and windowing.
*/
static void imdct_and_windowing(AACContext * ac, SingleChannelElement * sce) {
IndividualChannelStream * ics = &sce->ics;
float * in = sce->coeffs;
float * out = sce->ret;
float * saved = sce->saved;
const float * swindow = ics->use_kb_window[0] ? ff_aac_kbd_short_128 : ff_sine_128;
const float * lwindow_prev = ics->use_kb_window[1] ? ff_aac_kbd_long_1024 : ff_sine_1024;
const float * swindow_prev = ics->use_kb_window[1] ? ff_aac_kbd_short_128 : ff_sine_128;
float * temp = ac->temp;
// 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->avccontext, 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
ff_imdct_half(&ac->mdct, buf, in);
/* window overlapping
* NOTE: To simplify the overlapping code, all 'meaningless' short to long
* and long to short transitions are considered to be short to short
* transitions. This leaves just two cases (long to long and short to short)
* with a little special sauce for EIGHT_SHORT_SEQUENCE.
*/
if ((ics->window_sequence[1] == ONLY_LONG_SEQUENCE || ics->window_sequence[1] == LONG_STOP_SEQUENCE) &&
(ics->window_sequence[0] == ONLY_LONG_SEQUENCE || ics->window_sequence[0] == LONG_START_SEQUENCE)) {
ac->dsp.vector_fmul_window( out, saved, buf, lwindow_prev, ac->add_bias, 512);
} else {
for (i = 0; i < 448; i++)
out[i] = saved[i] + ac->add_bias;
if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
ac->dsp.vector_fmul_window(out + 448 + 0*128, saved + 448, buf + 0*128, swindow_prev, ac->add_bias, 64);
ac->dsp.vector_fmul_window(out + 448 + 1*128, buf + 0*128 + 64, buf + 1*128, swindow, ac->add_bias, 64);
ac->dsp.vector_fmul_window(out + 448 + 2*128, buf + 1*128 + 64, buf + 2*128, swindow, ac->add_bias, 64);
ac->dsp.vector_fmul_window(out + 448 + 3*128, buf + 2*128 + 64, buf + 3*128, swindow, ac->add_bias, 64);
ac->dsp.vector_fmul_window(temp, buf + 3*128 + 64, buf + 4*128, swindow, ac->add_bias, 64);
memcpy( out + 448 + 4*128, temp, 64 * sizeof(float));
} else {
ac->dsp.vector_fmul_window(out + 448, saved + 448, buf, swindow_prev, ac->add_bias, 64);
out[i] = buf[i-512] + ac->add_bias;
}
}
// buffer update
if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
for (i = 0; i < 64; i++)
saved[i] = temp[64 + i] - ac->add_bias;
ac->dsp.vector_fmul_window(saved + 64, buf + 4*128 + 64, buf + 5*128, swindow, 0, 64);
ac->dsp.vector_fmul_window(saved + 192, buf + 5*128 + 64, buf + 6*128, swindow, 0, 64);
ac->dsp.vector_fmul_window(saved + 320, buf + 6*128 + 64, buf + 7*128, swindow, 0, 64);
memcpy( saved + 448, buf + 7*128 + 64, 64 * sizeof(float));
} else if (ics->window_sequence[0] == LONG_START_SEQUENCE) {
memcpy( saved, buf + 512, 448 * sizeof(float));
memcpy( saved + 448, buf + 7*128 + 64, 64 * sizeof(float));
} else { // LONG_STOP or ONLY_LONG
memcpy( saved, buf + 512, 512 * sizeof(float));
Robert Swain
committed
/**
* Apply dependent channel coupling (applied before IMDCT).
*
* @param index index into coupling gain array
*/
static void apply_dependent_coupling(AACContext * ac, SingleChannelElement * target, ChannelElement * cce, int index) {
IndividualChannelStream * ics = &cce->ch[0].ics;
Robert Swain
committed
const uint16_t * offsets = ics->swb_offset;
float * dest = target->coeffs;
const float * src = cce->ch[0].coeffs;
Robert Swain
committed
int g, i, group, k, idx = 0;
if(ac->m4ac.object_type == AOT_AAC_LTP) {
av_log(ac->avccontext, AV_LOG_ERROR,
"Dependent coupling is not supported together with LTP\n");
return;
}
for (g = 0; g < ics->num_window_groups; g++) {
for (i = 0; i < ics->max_sfb; i++, idx++) {
if (cce->ch[0].band_type[idx] != ZERO_BT) {
const float gain = cce->coup.gain[index][idx];
Robert Swain
committed
for (group = 0; group < ics->group_len[g]; group++) {
for (k = offsets[i]; k < offsets[i+1]; k++) {
// XXX dsputil-ize
dest[group*128+k] += gain * src[group*128+k];
Robert Swain
committed
}
}
}
}
dest += ics->group_len[g]*128;
src += ics->group_len[g]*128;
}
}
/**
* Apply independent channel coupling (applied after IMDCT).
*
* @param index index into coupling gain array
*/
static void apply_independent_coupling(AACContext * ac, SingleChannelElement * target, ChannelElement * cce, int index) {
Robert Swain
committed
int i;
Alex Converse
committed
const float gain = cce->coup.gain[index][0];
const float bias = ac->add_bias;
const float* src = cce->ch[0].ret;
float* dest = target->ret;
Robert Swain
committed
for (i = 0; i < 1024; i++)
Alex Converse
committed
dest[i] += gain * (src[i] - bias);
Robert Swain
committed
}
/**
* 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,
enum RawDataBlockType type, int elem_id, enum CouplingPoint coupling_point,
void (*apply_coupling_method)(AACContext * ac, SingleChannelElement * target, ChannelElement * cce, int index))
int i, c;
for (i = 0; i < MAX_ELEM_ID; i++) {
ChannelElement *cce = ac->che[TYPE_CCE][i];
int index = 0;
if (cce && cce->coup.coupling_point == coupling_point) {
ChannelCoupling * coup = &cce->coup;
for (c = 0; c <= coup->num_coupled; c++) {
if (coup->type[c] == type && coup->id_select[c] == elem_id) {
if (coup->ch_select[c] != 1) {
apply_coupling_method(ac, &cc->ch[0], cce, index);
if (coup->ch_select[c] != 0)
index++;
}
if (coup->ch_select[c] != 2)
apply_coupling_method(ac, &cc->ch[1], cce, index++);
} else
index += 1 + (coup->ch_select[c] == 3);
}
}
}
}
/**
* Convert spectral data to float samples, applying all supported tools as appropriate.
*/
static void spectral_to_sample(AACContext * ac) {
for(type = 3; type >= 0; type--) {
for (i = 0; i < MAX_ELEM_ID; i++) {
ChannelElement *che = ac->che[type][i];
if(che) {
if(type <= TYPE_CPE)
apply_channel_coupling(ac, che, type, i, BEFORE_TNS, apply_dependent_coupling);
if(che->ch[0].tns.present)
apply_tns(che->ch[0].coeffs, &che->ch[0].tns, &che->ch[0].ics, 1);
if(che->ch[1].tns.present)
apply_tns(che->ch[1].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, apply_dependent_coupling);
if(type != TYPE_CCE || che->coup.coupling_point == AFTER_IMDCT)
imdct_and_windowing(ac, &che->ch[0]);
if(type == TYPE_CPE)
imdct_and_windowing(ac, &che->ch[1]);
if(type <= TYPE_CCE)
apply_channel_coupling(ac, che, type, i, AFTER_IMDCT, apply_independent_coupling);
Robert Swain
committed
static int parse_adts_frame_header(AACContext * ac, GetBitContext * gb) {
int size;
AACADTSHeaderInfo hdr_info;
size = ff_aac_parse_header(gb, &hdr_info);
if (size > 0) {
if (hdr_info.chan_config)
ac->m4ac.chan_config = hdr_info.chan_config;
ac->m4ac.sample_rate = hdr_info.sample_rate;
ac->m4ac.sampling_index = hdr_info.sampling_index;
ac->m4ac.object_type = hdr_info.object_type;
if (hdr_info.num_aac_frames == 1) {
if (!hdr_info.crc_absent)
skip_bits(gb, 16);
} else {
av_log_missing_feature(ac->avccontext, "More than one AAC RDB per ADTS frame is", 0);
Alex Converse
committed
}
Robert Swain
committed
return size;
}
Thilo Borgmann
committed
static int aac_decode_frame(AVCodecContext * avccontext, void * data, int * data_size, AVPacket *avpkt) {
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
AACContext * ac = avccontext->priv_data;
ChannelElement * che = NULL;
GetBitContext gb;
enum RawDataBlockType elem_type;
int err, elem_id, data_size_tmp;
init_get_bits(&gb, buf, buf_size*8);
Robert Swain
committed
if (show_bits(&gb, 12) == 0xfff) {
if (parse_adts_frame_header(ac, &gb) < 0) {
Robert Swain
committed
av_log(avccontext, AV_LOG_ERROR, "Error decoding AAC frame header.\n");
return -1;
}
if (ac->m4ac.sampling_index > 12) {
av_log(ac->avccontext, AV_LOG_ERROR, "invalid sampling rate index %d\n", ac->m4ac.sampling_index);
return -1;
}
Robert Swain
committed
}
// 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->avccontext, AV_LOG_ERROR, "channel element %d.%d is not allocated\n", elem_type, elem_id);
return -1;
}
switch (elem_type) {
case TYPE_SCE:
err = decode_ics(ac, &che->ch[0], &gb, 0, 0);
err = decode_cpe(ac, &gb, che);
err = decode_cce(ac, &gb, che);
err = decode_ics(ac, &che->ch[0], &gb, 0, 0);
break;
case TYPE_DSE:
skip_data_stream_element(&gb);
err = 0;
break;
case TYPE_PCE:
{
enum ChannelPosition new_che_pos[4][MAX_ELEM_ID];
memset(new_che_pos, 0, 4 * MAX_ELEM_ID * sizeof(new_che_pos[0][0]));
if((err = decode_pce(ac, new_che_pos, &gb)))
break;
err = output_configure(ac, ac->che_pos, new_che_pos, 0);
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
break;
}
case TYPE_FIL:
if (elem_id == 15)
elem_id += get_bits(&gb, 8) - 1;
while (elem_id > 0)
elem_id -= decode_extension_payload(ac, &gb, elem_id);
err = 0; /* FIXME */
break;
default:
err = -1; /* should not happen, but keeps compiler happy */
break;
}
if(err)
return err;
}
spectral_to_sample(ac);
if (!ac->is_saved) {
ac->is_saved = 1;
*data_size = 0;
}
data_size_tmp = 1024 * avccontext->channels * sizeof(int16_t);
if(*data_size < data_size_tmp) {
av_log(avccontext, AV_LOG_ERROR,
"Output buffer too small (%d) or trying to output too many samples (%d) for this frame.\n",
*data_size, data_size_tmp);
return -1;
}
*data_size = data_size_tmp;
ac->dsp.float_to_int16_interleave(data, (const float **)ac->output_data, 1024, avccontext->channels);
return buf_size;
}
static av_cold int aac_decode_close(AVCodecContext * avccontext) {
AACContext * ac = avccontext->priv_data;
Robert Swain
committed
for (i = 0; i < MAX_ELEM_ID; i++) {
for(type = 0; type < 4; type++)
av_freep(&ac->che[type][i]);
}
ff_mdct_end(&ac->mdct);
ff_mdct_end(&ac->mdct_small);
return 0 ;
}
AVCodec aac_decoder = {
"aac",
CODEC_TYPE_AUDIO,
CODEC_ID_AAC,
sizeof(AACContext),
aac_decode_init,
NULL,
aac_decode_close,
aac_decode_frame,
.long_name = NULL_IF_CONFIG_SMALL("Advanced Audio Coding"),
Robert Swain
committed
.sample_fmts = (enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE},