int blk, ch, err, offset, ret;
int got_independent_frame = 0;
const uint8_t *channel_map;
- uint8_t extended_channel_map[AC3_MAX_CHANNELS * 2];
+ uint8_t extended_channel_map[EAC3_MAX_CHANNELS];
const SHORTFLOAT *output[AC3_MAX_CHANNELS];
enum AVMatrixEncoding matrix_encoding;
AVDownmixInfo *downmix_info;
avctx->bit_rate = s->bit_rate + s->prev_bit_rate;
}
- for (ch = 0; ch < 16; ch++)
+ for (ch = 0; ch < EAC3_MAX_CHANNELS; ch++)
extended_channel_map[ch] = ch;
if (s->frame_type == EAC3_FRAME_TYPE_DEPENDENT) {
uint64_t ich_layout = avpriv_ac3_channel_layout_tab[s->prev_output_mode & ~AC3_OUTPUT_LFEON];
+ int channel_map_size = ff_ac3_channels_tab[s->output_mode & ~AC3_OUTPUT_LFEON] + s->lfe_on;
uint64_t channel_layout;
int extend = 0;
channel_layout = ich_layout;
for (ch = 0; ch < 16; ch++) {
- if (s->channel_map & (1 << (15 - ch))) {
+ if (s->channel_map & (1 << (EAC3_MAX_CHANNELS - ch - 1))) {
channel_layout |= custom_channel_map_locations[ch][1];
}
}
+ if (av_get_channel_layout_nb_channels(channel_layout) > EAC3_MAX_CHANNELS) {
+ av_log(avctx, AV_LOG_ERROR, "Too many channels (%d) coded\n",
+ av_get_channel_layout_nb_channels(channel_layout));
+ return AVERROR_INVALIDDATA;
+ }
avctx->channel_layout = channel_layout;
avctx->channels = av_get_channel_layout_nb_channels(channel_layout);
- for (ch = 0; ch < 16; ch++) {
- if (s->channel_map & (1 << (15 - ch))) {
+ for (ch = 0; ch < EAC3_MAX_CHANNELS; ch++) {
+ if (s->channel_map & (1 << (EAC3_MAX_CHANNELS - ch - 1))) {
if (custom_channel_map_locations[ch][0]) {
int index = av_get_channel_layout_channel_index(channel_layout,
custom_channel_map_locations[ch][1]);
if (index < 0)
return AVERROR_INVALIDDATA;
+ if (extend >= channel_map_size)
+ return AVERROR_INVALIDDATA;
+
extended_channel_map[index] = offset + channel_map[extend++];
} else {
int i;
1LL << i);
if (index < 0)
return AVERROR_INVALIDDATA;
+ if (extend >= channel_map_size)
+ return AVERROR_INVALIDDATA;
+
extended_channel_map[index] = offset + channel_map[extend++];
}
}
for (ch = 0; ch < avctx->channels; ch++) {
int map = extended_channel_map[ch];
- memcpy((SHORTFLOAT *)frame->data[ch], s->output_buffer[map],
+ av_assert0(ch>=AV_NUM_DATA_POINTERS || frame->extended_data[ch] == frame->data[ch]);
+ memcpy((SHORTFLOAT *)frame->extended_data[ch],
+ s->output_buffer[map],
s->num_blocks * AC3_BLOCK_SIZE * sizeof(SHORTFLOAT));
}
*got_frame_ptr = 1;
+ if (!s->superframe_size)
+ return FFMIN(full_buf_size, s->frame_size);
+
return FFMIN(full_buf_size, s->superframe_size);
}