}
}
+/**
+ * Check for the channel element in the current channel position configuration.
+ * If it exists, make sure the appropriate element is allocated and map the
+ * channel order to match the internal FFmpeg channel layout.
+ *
+ * @param che_pos current channel position configuration
+ * @param type channel element type
+ * @param id channel element id
+ * @param channels count of the number of channels in the configuration
+ *
+ * @return Returns error status. 0 - OK, !0 - error
+ */
+static int che_configure(AACContext *ac,
+ enum ChannelPosition che_pos[4][MAX_ELEM_ID],
+ int type, int id,
+ int *channels)
+{
+ if (che_pos[type][id]) {
+ if (!ac->che[type][id] && !(ac->che[type][id] = av_mallocz(sizeof(ChannelElement))))
+ return AVERROR(ENOMEM);
+ if (type != TYPE_CCE) {
+ ac->output_data[(*channels)++] = ac->che[type][id]->ch[0].ret;
+ if (type == TYPE_CPE) {
+ ac->output_data[(*channels)++] = ac->che[type][id]->ch[1].ret;
+ }
+ }
+ } else
+ av_freep(&ac->che[type][id]);
+ return 0;
+}
+
/**
* Configure output channel order based on the current program configuration element.
*
static int output_configure(AACContext *ac,
enum ChannelPosition che_pos[4][MAX_ELEM_ID],
enum ChannelPosition new_che_pos[4][MAX_ELEM_ID],
- int channel_config)
+ int channel_config, enum OCStatus oc_type)
{
AVCodecContext *avctx = ac->avccontext;
- int i, type, channels = 0;
+ int i, type, channels = 0, ret;
memcpy(che_pos, new_che_pos, 4 * MAX_ELEM_ID * sizeof(new_che_pos[0][0]));
if (channel_config) {
for (i = 0; i < tags_per_config[channel_config]; i++) {
- const int id = aac_channel_layout_map[channel_config - 1][i][1];
- type = aac_channel_layout_map[channel_config - 1][i][0];
-
- if (!ac->che[type][id] && !(ac->che[type][id] = av_mallocz(sizeof(ChannelElement))))
- return AVERROR(ENOMEM);
-
- if (type != TYPE_CCE) {
- ac->output_data[channels++] = ac->che[type][id]->ch[0].ret;
- if (type == TYPE_CPE)
- ac->output_data[channels++] = ac->che[type][id]->ch[1].ret;
- }
+ if ((ret = che_configure(ac, che_pos,
+ aac_channel_layout_map[channel_config - 1][i][0],
+ aac_channel_layout_map[channel_config - 1][i][1],
+ &channels)))
+ return ret;
}
memset(ac->tag_che_map, 0, 4 * MAX_ELEM_ID * sizeof(ac->che[0][0]));
for (i = 0; i < MAX_ELEM_ID; i++) {
for (type = 0; type < 4; type++) {
- if (che_pos[type][i]) {
- if (!ac->che[type][i] && !(ac->che[type][i] = av_mallocz(sizeof(ChannelElement))))
- return AVERROR(ENOMEM);
- if (type != TYPE_CCE) {
- ac->output_data[channels++] = ac->che[type][i]->ch[0].ret;
- if (type == TYPE_CPE) {
- ac->output_data[channels++] = ac->che[type][i]->ch[1].ret;
- }
- }
- } else
- av_freep(&ac->che[type][i]);
+ if ((ret = che_configure(ac, che_pos, type, i, &channels)))
+ return ret;
}
}
avctx->channels = channels;
- ac->output_configured = 1;
+ ac->output_configured = oc_type;
return 0;
}
if ((ret = set_default_channel_config(ac, new_che_pos, channel_config)))
return ret;
}
- if ((ret = output_configure(ac, ac->che_pos, new_che_pos, channel_config)))
+ if ((ret = output_configure(ac, ac->che_pos, new_che_pos, channel_config, OC_GLOBAL_HDR)))
return ret;
if (extension_flag) {
// 32768 - Required to scale values to the correct range for the bias method
// for float to int16 conversion.
- if (ac->dsp.float_to_int16 == ff_float_to_int16_c) {
+ if (ac->dsp.float_to_int16_interleave == ff_float_to_int16_interleave_c) {
ac->add_bias = 385.0f;
ac->sf_scale = 1. / (-1024. * 32768.);
ac->sf_offset = 0;
for (g = 0; g < ics->num_window_groups; g++) {
int k = 0;
while (k < ics->max_sfb) {
- uint8_t sect_len = k;
+ uint8_t sect_end = k;
int sect_len_incr;
int sect_band_type = get_bits(gb, 4);
if (sect_band_type == 12) {
return -1;
}
while ((sect_len_incr = get_bits(gb, bits)) == (1 << bits) - 1)
- sect_len += sect_len_incr;
- sect_len += sect_len_incr;
- if (sect_len > ics->max_sfb) {
+ sect_end += sect_len_incr;
+ sect_end += sect_len_incr;
+ if (sect_end > ics->max_sfb) {
av_log(ac->avccontext, AV_LOG_ERROR,
"Number of bands (%d) exceeds limit (%d).\n",
- sect_len, ics->max_sfb);
+ sect_end, ics->max_sfb);
return -1;
}
- for (; k < sect_len; k++) {
+ for (; k < sect_end; k++) {
band_type [idx] = sect_band_type;
- band_type_run_end[idx++] = sect_len;
+ band_type_run_end[idx++] = sect_end;
}
}
}
size = ff_aac_parse_header(gb, &hdr_info);
if (size > 0) {
- if (!ac->output_configured && hdr_info.chan_config) {
+ if (ac->output_configured != OC_LOCKED && hdr_info.chan_config) {
enum ChannelPosition new_che_pos[4][MAX_ELEM_ID];
memset(new_che_pos, 0, 4 * MAX_ELEM_ID * sizeof(new_che_pos[0][0]));
ac->m4ac.chan_config = hdr_info.chan_config;
if (set_default_channel_config(ac, new_che_pos, hdr_info.chan_config))
return -7;
- if (output_configure(ac, ac->che_pos, new_che_pos, 1))
+ if (output_configure(ac, ac->che_pos, new_che_pos, hdr_info.chan_config, OC_TRIAL_FRAME))
return -7;
+ } else if (ac->output_configured != OC_LOCKED) {
+ ac->output_configured = OC_NONE;
}
+ if (ac->output_configured != OC_LOCKED)
+ ac->m4ac.sbr = -1;
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 (!ac->avccontext->sample_rate)
+ ac->avccontext->sample_rate = hdr_info.sample_rate;
if (hdr_info.num_aac_frames == 1) {
if (!hdr_info.crc_absent)
skip_bits(gb, 16);
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;
- if (ac->output_configured)
+ if (ac->output_configured > OC_TRIAL_PCE)
av_log(avccontext, AV_LOG_ERROR,
"Not evaluating a further program_config_element as this construct is dubious at best.\n");
else
- err = output_configure(ac, ac->che_pos, new_che_pos, 0);
+ err = output_configure(ac, ac->che_pos, new_che_pos, 0, OC_TRIAL_PCE);
break;
}
ac->dsp.float_to_int16_interleave(data, (const float **)ac->output_data, 1024, avccontext->channels);
+ if (ac->output_configured)
+ ac->output_configured = OC_LOCKED;
+
return buf_size;
}