[FFmpeg-cvslog] aac: Correctly map multichannel ADTS AAC with non-zero channel_config + PCE

nu774 git at videolan.org
Wed Jun 3 20:13:34 CEST 2015


ffmpeg | branch: master | nu774 <honeycomb77 at gmail.com> | Wed Jun  3 14:01:32 2015 +0900| [0289f81241e720452b5a77713488d54d3ec252d7] | committer: 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: Luca Barbato <lu_zero at gentoo.org>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=0289f81241e720452b5a77713488d54d3ec252d7
---

 libavcodec/aacdec.c |   13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c
index 7b306c9..0c7e2c4 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;



More information about the ffmpeg-cvslog mailing list