aboutsummaryrefslogtreecommitdiff
path: root/libavcodec/aacdec.c
diff options
context:
space:
mode:
authornu7742015-06-03 14:01:32 +0900
committerLuca Barbato2015-06-03 14:40:10 +0200
commit0289f81241e720452b5a77713488d54d3ec252d7 (patch)
treeeeb0a879794cc7a670d3566bc3b1811a0e1f1cd8 /libavcodec/aacdec.c
parent7f596368a404363d72b1be6d16c51420a71bc523 (diff)
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: Luca Barbato <lu_zero@gentoo.org>
Diffstat (limited to 'libavcodec/aacdec.c')
-rw-r--r--libavcodec/aacdec.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c
index 7b306c9c41..0c7e2c4d39 100644
--- a/libavcodec/aacdec.c
+++ b/libavcodec/aacdec.c
@@ -443,12 +443,18 @@ static int output_configure(AACContext *ac,
AVCodecContext *avctx = ac->avctx;
int i, channels = 0, ret;
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) {
memcpy(ac->oc[1].layout_map, layout_map, tags * sizeof(layout_map[0]));
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
// channels in the order the PCE declared them.
if (avctx->request_channel_layout != AV_CH_LAYOUT_NATIVE)
@@ -456,12 +462,14 @@ static int output_configure(AACContext *ac,
for (i = 0; i < tags; i++) {
int type = layout_map[i][0];
int id = layout_map[i][1];
+ int iid = id_map[type][id];
int position = layout_map[i][2];
// Allocate or free elements depending on if they are in the
// current program configuration.
- ret = che_configure(ac, position, type, id, &channels);
+ ret = che_configure(ac, position, type, iid, &channels);
if (ret < 0)
return ret;
+ ac->tag_che_map[type][id] = ac->che[type][iid];
}
if (ac->oc[1].m4ac.ps == 1 && channels == 2) {
if (layout == AV_CH_FRONT_CENTER) {
@@ -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->channels = ac->oc[1].channels = channels;
ac->oc[1].status = oc_type;