summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornu774 <honeycomb77@gmail.com>2015-06-03 14:01:32 +0900
committerLuca Barbato <lu_zero@gentoo.org>2015-06-03 14:40:10 +0200
commit0289f81241e720452b5a77713488d54d3ec252d7 (patch)
treeeeb0a879794cc7a670d3566bc3b1811a0e1f1cd8
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>
-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;