aac: Correctly map multichannel ADTS AAC with non-zero channel_config + PCE
[ffmpeg.git] / libavcodec / aacdec.c
index c4234e7..0c7e2c4 100644 (file)
@@ -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;
@@ -819,7 +826,7 @@ static int decode_eld_specific_config(AACContext *ac, AVCodecContext *avctx,
         if (len == 15 + 255)
             len += get_bits(gb, 16);
         if (get_bits_left(gb) < len * 8 + 4) {
-            av_log(ac->avctx, AV_LOG_ERROR, overread_err);
+            av_log(avctx, AV_LOG_ERROR, overread_err);
             return AVERROR_INVALIDDATA;
         }
         skip_bits_long(gb, 8 * len);
@@ -862,10 +869,10 @@ static int decode_audio_specific_config(AACContext *ac,
     GetBitContext gb;
     int i, ret;
 
-    av_dlog(avctx, "extradata size %d\n", avctx->extradata_size);
+    ff_dlog(avctx, "extradata size %d\n", avctx->extradata_size);
     for (i = 0; i < avctx->extradata_size; i++)
-        av_dlog(avctx, "%02x ", avctx->extradata[i]);
-    av_dlog(avctx, "\n");
+        ff_dlog(avctx, "%02x ", avctx->extradata[i]);
+    ff_dlog(avctx, "\n");
 
     if ((ret = init_get_bits(&gb, data, bit_size)) < 0)
         return ret;
@@ -912,7 +919,7 @@ static int decode_audio_specific_config(AACContext *ac,
         return AVERROR(ENOSYS);
     }
 
-    av_dlog(avctx,
+    ff_dlog(avctx,
             "AOT %d chan config %d sampling index %d (%d) SBR %d PS %d\n",
             m4ac->object_type, m4ac->chan_config, m4ac->sampling_index,
             m4ac->sample_rate, m4ac->sbr,
@@ -1143,7 +1150,8 @@ static int decode_ics_info(AACContext *ac, IndividualChannelStream *ics,
     if (aot != AOT_ER_AAC_ELD) {
         if (get_bits1(gb)) {
             av_log(ac->avctx, AV_LOG_ERROR, "Reserved bit set.\n");
-            return AVERROR_INVALIDDATA;
+            if (ac->avctx->err_recognition & AV_EF_BITSTREAM)
+                return AVERROR_INVALIDDATA;
         }
         ics->window_sequence[1] = ics->window_sequence[0];
         ics->window_sequence[0] = get_bits(gb, 2);