Newer
Older
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;
}
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
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
/**
* 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
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
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;
DECLARE_ALIGNED(16, float, temp[128]);
// 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
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
/**
* Apply dependent channel coupling (applied before IMDCT).
*
* @param index index into coupling gain array
*/
static void apply_dependent_coupling(AACContext * ac, SingleChannelElement * sce, ChannelElement * cc, int index) {
IndividualChannelStream * ics = &cc->ch[0].ics;
const uint16_t * offsets = ics->swb_offset;
float * dest = sce->coeffs;
const float * src = cc->ch[0].coeffs;
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 (cc->ch[0].band_type[idx] != ZERO_BT) {
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] += cc->coup.gain[index][idx] * 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 * sce, ChannelElement * cc, int index) {
int i;
for (i = 0; i < 1024; i++)
sce->ret[i] += cc->coup.gain[index][0] * (cc->ch[0].ret[i] - ac->add_bias);
Robert Swain
committed
}
1266
1267
1268
1269
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
/**
* 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,
void (*apply_coupling_method)(AACContext * ac, SingleChannelElement * sce, ChannelElement * cc, int index))
{
int c;
int index = 0;
ChannelCoupling * coup = &cc->coup;
for (c = 0; c <= coup->num_coupled; c++) {
if (ac->che[coup->type[c]][coup->id_select[c]]) {
if (coup->ch_select[c] != 2) {
apply_coupling_method(ac, &ac->che[coup->type[c]][coup->id_select[c]]->ch[0], cc, index);
if (coup->ch_select[c] != 0)
index++;
}
if (coup->ch_select[c] != 1)
apply_coupling_method(ac, &ac->che[coup->type[c]][coup->id_select[c]]->ch[1], cc, index++);
} else {
av_log(ac->avccontext, AV_LOG_ERROR,
"coupling target %sE[%d] not available\n",
coup->type[c] == TYPE_CPE ? "CP" : "SC", coup->id_select[c]);
break;
}
}
}
/**
* Convert spectral data to float samples, applying all supported tools as appropriate.
*/
static void spectral_to_sample(AACContext * ac) {
int i, type;
for (i = 0; i < MAX_ELEM_ID; i++) {
for(type = 0; type < 4; type++) {
ChannelElement *che = ac->che[type][i];
if(che) {
if(che->coup.coupling_point == BEFORE_TNS)
apply_channel_coupling(ac, che, 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(che->coup.coupling_point == BETWEEN_TNS_AND_IMDCT)
apply_channel_coupling(ac, che, apply_dependent_coupling);
imdct_and_windowing(ac, &che->ch[0]);
if(type == TYPE_CPE)
imdct_and_windowing(ac, &che->ch[1]);
if(che->coup.coupling_point == AFTER_IMDCT)
apply_channel_coupling(ac, che, apply_independent_coupling);
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
}
}
}
}
static int aac_decode_frame(AVCodecContext * avccontext, void * data, int * data_size, const uint8_t * buf, int buf_size) {
AACContext * ac = avccontext->priv_data;
GetBitContext gb;
enum RawDataBlockType elem_type;
int err, elem_id, data_size_tmp;
init_get_bits(&gb, buf, buf_size*8);
// parse
while ((elem_type = get_bits(&gb, 3)) != TYPE_END) {
elem_id = get_bits(&gb, 4);
err = -1;
if(elem_type == TYPE_SCE && elem_id == 1 &&
!ac->che[TYPE_SCE][elem_id] && ac->che[TYPE_LFE][0]) {
/* Some streams incorrectly code 5.1 audio as SCE[0] CPE[0] CPE[1] SCE[1]
instead of SCE[0] CPE[0] CPE[0] LFE[0]. If we seem to have
encountered such a stream, transfer the LFE[0] element to SCE[1] */
ac->che[TYPE_SCE][elem_id] = ac->che[TYPE_LFE][0];
ac->che[TYPE_LFE][0] = NULL;
}
if(elem_type < TYPE_DSE) {
if(!ac->che[elem_type][elem_id])
return -1;
if(elem_type != TYPE_CCE)
ac->che[elem_type][elem_id]->coup.coupling_point = 4;
}
switch (elem_type) {
case TYPE_SCE:
err = decode_ics(ac, &ac->che[TYPE_SCE][elem_id]->ch[0], &gb, 0, 0);
break;
case TYPE_CPE:
err = decode_cpe(ac, &gb, elem_id);
break;
case TYPE_CCE:
err = decode_cce(ac, &gb, ac->che[TYPE_CCE][elem_id]);
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
break;
case TYPE_LFE:
err = decode_ics(ac, &ac->che[TYPE_LFE][elem_id]->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);
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},