Commit 0289f812 authored by nu774's avatar nu774 Committed by Luca Barbato

aac: Correctly map multichannel ADTS AAC with non-zero channel_config + PCE

The decoder assigns channels using default channel configuration
for 5.1ch when it parses an ADTS frame header using consecutive
channel ids.

When a PCE comes, it reassigns channels using PCE configuration
using directly the ids provided. They can be arbitrary.

Always use consecutive channel ids to avoid decoding glitches due
spurious reconfigurations due the channel ids mismatch between the
two otherwise-identical channel maps.
Signed-off-by: 's avatarLuca Barbato <lu_zero@gentoo.org>
parent 7f596368
...@@ -443,12 +443,18 @@ static int output_configure(AACContext *ac, ...@@ -443,12 +443,18 @@ static int output_configure(AACContext *ac,
AVCodecContext *avctx = ac->avctx; AVCodecContext *avctx = ac->avctx;
int i, channels = 0, ret; int i, channels = 0, ret;
uint64_t layout = 0; uint64_t layout = 0;
uint8_t id_map[TYPE_END][MAX_ELEM_ID] = {{ 0 }};
uint8_t type_counts[TYPE_END] = { 0 };
if (ac->oc[1].layout_map != layout_map) { if (ac->oc[1].layout_map != layout_map) {
memcpy(ac->oc[1].layout_map, layout_map, tags * sizeof(layout_map[0])); memcpy(ac->oc[1].layout_map, layout_map, tags * sizeof(layout_map[0]));
ac->oc[1].layout_map_tags = tags; ac->oc[1].layout_map_tags = tags;
} }
for (i = 0; i < tags; i++) {
int type = layout_map[i][0];
int id = layout_map[i][1];
id_map[type][id] = type_counts[type]++;
}
// Try to sniff a reasonable channel order, otherwise output the // Try to sniff a reasonable channel order, otherwise output the
// channels in the order the PCE declared them. // channels in the order the PCE declared them.
if (avctx->request_channel_layout != AV_CH_LAYOUT_NATIVE) if (avctx->request_channel_layout != AV_CH_LAYOUT_NATIVE)
...@@ -456,12 +462,14 @@ static int output_configure(AACContext *ac, ...@@ -456,12 +462,14 @@ static int output_configure(AACContext *ac,
for (i = 0; i < tags; i++) { for (i = 0; i < tags; i++) {
int type = layout_map[i][0]; int type = layout_map[i][0];
int id = layout_map[i][1]; int id = layout_map[i][1];
int iid = id_map[type][id];
int position = layout_map[i][2]; int position = layout_map[i][2];
// Allocate or free elements depending on if they are in the // Allocate or free elements depending on if they are in the
// current program configuration. // current program configuration.
ret = che_configure(ac, position, type, id, &channels); ret = che_configure(ac, position, type, iid, &channels);
if (ret < 0) if (ret < 0)
return ret; return ret;
ac->tag_che_map[type][id] = ac->che[type][iid];
} }
if (ac->oc[1].m4ac.ps == 1 && channels == 2) { if (ac->oc[1].m4ac.ps == 1 && channels == 2) {
if (layout == AV_CH_FRONT_CENTER) { if (layout == AV_CH_FRONT_CENTER) {
...@@ -471,7 +479,6 @@ static int output_configure(AACContext *ac, ...@@ -471,7 +479,6 @@ static int output_configure(AACContext *ac,
} }
} }
memcpy(ac->tag_che_map, ac->che, 4 * MAX_ELEM_ID * sizeof(ac->che[0][0]));
avctx->channel_layout = ac->oc[1].channel_layout = layout; avctx->channel_layout = ac->oc[1].channel_layout = layout;
avctx->channels = ac->oc[1].channels = channels; avctx->channels = ac->oc[1].channels = channels;
ac->oc[1].status = oc_type; ac->oc[1].status = oc_type;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment