[FFmpeg-devel] [PATCH/RFC] avcodec/aacdec: default to non-wide 7.1 in non-strict mode

Anssi Hannula anssi.hannula at iki.fi
Tue Dec 17 22:04:31 CET 2013


AAC specification has 7.1(wide) as a default layout for 8-channel
streams (channel config 7). However, at least Nero AAC encoder encodes
non-wide 7.1 streams using the default channel config 7, mapping the
side channels of the original audio stream to the second
AAC_CHANNEL_FRONT pair in the AAC stream. Similarly, e.g. FAAD decodes
the second AAC_CHANNEL_FRONT pair as side channels, therefore decoding
the incorrect streams as if they were correct (and as the encoder
intended).

FFmpeg currently decodes such files by-the-spec, i.e. after decoding the
original front pair will be in AV_CH_FRONT_x_OF_CENTER and the original
side pair will be in AV_CH_FRONT_x.

As actual intended 7.1(wide) streams are very rare while misencoded 7.1
files actually exist in the wild, default to assuming a 7.1 layout was
intended unless in strict mode.

Fixes playback of e.g. 8_Channel_ID.m4a in samples.

Signed-off-by: Anssi Hannula <anssi.hannula at iki.fi>
---

In my opinion this is something we should do, since I didn't find any
AAC 7.1(wide) files in-the-wild that weren't actually misencoded 7.1
streams, and since they are unfortunately "correctly" decoded by FAAD
(and therefore e.g. VLC). Also, most non-wide AAC 7.1 files in the wild
seem to be misencoded like this instead of correctly encoded with a
custom channel config (due to the free Nero AAC encoder I guess).

Of course, there are downsides to this patch:
- spec-conforming 7.1(wide) will have their wide channels incorrectly
  decoded as side channels (though I did not find any such file with a
  quick look), and
- more people will think their incorrect AAC7.1 files are actually fine
  (though they already seem fine in e.g. VLC).

Some user reports of the issue:
http://trac.xbmc.org/ticket/13758
https://trac.ffmpeg.org/ticket/2153

WDYT?

 libavcodec/aacdec.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c
index 1fb9185..1e15cb4 100644
--- a/libavcodec/aacdec.c
+++ b/libavcodec/aacdec.c
@@ -534,6 +534,25 @@ static int set_default_channel_config(AVCodecContext *avctx,
     *tags = tags_per_config[channel_config];
     memcpy(layout_map, aac_channel_layout_map[channel_config - 1],
            *tags * sizeof(*layout_map));
+
+    /*
+     * AAC specification has 7.1(wide) as a default layout for 8-channel streams.
+     * However, at least Nero AAC encoder encodes 7.1 streams using the default
+     * channel config 7, mapping the side channels of the original audio stream
+     * to the second AAC_CHANNEL_FRONT pair in the AAC stream. Similarly, e.g. FAAD
+     * decodes the second AAC_CHANNEL_FRONT pair as side channels, therefore decoding
+     * the incorrect streams as if they were correct (and as the encoder intended).
+     *
+     * As actual intended 7.1(wide) streams are very rare, default to assuming a
+     * 7.1 layout was intended.
+     */
+    if (channel_config == 7 && avctx->strict_std_compliance < FF_COMPLIANCE_STRICT) {
+        av_log(avctx, AV_LOG_INFO, "Assuming an incorrectly encoded 7.1 channel layout"
+               " instead of a spec-compliant 7.1(wide) layout, use -strict %d to decode"
+               " according to the specification instead.\n", FF_COMPLIANCE_STRICT);
+        layout_map[2][2] = AAC_CHANNEL_SIDE;
+    }
+
     return 0;
 }
 
-- 
1.8.1.5



More information about the ffmpeg-devel mailing list