PR #23418 opened by Niklas Haas (haasn)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23418
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23418.patch
PCE is not compatible with all downstream sources. Firefox, for example, will
refuse to play an AAC file with a PCE channel layout, and presumably other
browsers do the same. So there is a legitimate use case for encoding non-PCE
files if required.
However, due to the historical work-around where FFmpeg produced out-of-spec
files that mislabelled 7.1 as 7.1(wide), we should gate this behind -strict 1
(which also disables the equivalent work-around in aacdec).
This way, a user who really knows what they're doing can use
-af aformat=7.1(wide) and -strict 1 to force producing a spec-compliant
non-PCE AAC file.
The channel IDs were taken by comparing the AAC bitstream channel order:
FC, FLC, FRC, FL, FR, BL, BR, LFE
Aginst the FFmpeg channel order for 7POINT1_WIDE_BACK:
0=FL 1=FR 2=FC 3=LFE 4=BL 5=BR 6=FLC 7=FRC
This gives us {2, 6, 7, 0, 1, 4, 5, 3}.
Sponsored-by: nxtedition AB
Signed-off-by: Niklas Haas <[email protected]>
>From 75f30788945722d21cc653000ec68e2dc60b9e5c Mon Sep 17 00:00:00 2001
From: Niklas Haas <[email protected]>
Date: Tue, 9 Jun 2026 17:13:27 +0200
Subject: [PATCH] avcodec/aacenc: allow encoding non-PCE 7.1(wide) under
-strict 1
PCE is not compatible with all downstream sources. Firefox, for example, will
refuse to play an AAC file with a PCE channel layout, and presumably other
browsers do the same. So there is a legitimate use case for encoding non-PCE
files if required.
However, due to the historical work-around where FFmpeg produced out-of-spec
files that mislabelled 7.1 as 7.1(wide), we should gate this behind -strict 1
(which also disables the equivalent work-around in aacdec).
This way, a user who really knows what they're doing can use
-af aformat=7.1(wide) and -strict 1 to force producing a spec-compliant
non-PCE AAC file.
The channel IDs were taken by comparing the AAC bitstream channel order:
FC, FLC, FRC, FL, FR, BL, BR, LFE
Aginst the FFmpeg channel order for 7POINT1_WIDE_BACK:
0=FL 1=FR 2=FC 3=LFE 4=BL 5=BR 6=FLC 7=FRC
This gives us {2, 6, 7, 0, 1, 4, 5, 3}.
Sponsored-by: nxtedition AB
Signed-off-by: Niklas Haas <[email protected]>
---
libavcodec/aacenc.c | 16 ++++++++++++++++
libavcodec/aacenctab.h | 6 +++---
2 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/libavcodec/aacenc.c b/libavcodec/aacenc.c
index 0d0dcb5126..7ac8acfa57 100644
--- a/libavcodec/aacenc.c
+++ b/libavcodec/aacenc.c
@@ -1176,6 +1176,22 @@ static av_cold int aac_encode_init(AVCodecContext *avctx)
}
}
+ if (avctx->strict_std_compliance < FF_COMPLIANCE_STRICT &&
+ !s->needs_pce && chcfg == 7 /* 7.1(wide) */)
+ {
+ /**
+ * FFmpeg used to produce out-of-spec AAC files that mistagged 7.1
+ * as 7.1(wide), and this wark-around is still enabled by default in
+ * aacdec.c, so avoid producing such files in the rare case that the
+ * user correctly passed 7.1(wide) channel layout content.
+ */
+ av_log(avctx, AV_LOG_INFO, "Forcing the use of PCE to encode 7.1(wide)
"
+ "channel layout to avoid ambiguity. Set -strict %d to override "
+ "this behavior and force the use of spec-compliant channel "
+ "configuration ID.\n", FF_COMPLIANCE_STRICT);
+ s->needs_pce = 1;
+ }
+
if (s->needs_pce) {
char buf[64];
for (i = 0; i < FF_ARRAY_ELEMS(aac_pce_configs); i++)
diff --git a/libavcodec/aacenctab.h b/libavcodec/aacenctab.h
index addab63885..556b2e6dbd 100644
--- a/libavcodec/aacenctab.h
+++ b/libavcodec/aacenctab.h
@@ -52,7 +52,7 @@ static const AVChannelLayout aac_normal_chan_layouts[15] = {
AV_CHANNEL_LAYOUT_4POINT0,
AV_CHANNEL_LAYOUT_5POINT0_BACK,
AV_CHANNEL_LAYOUT_5POINT1_BACK,
- { 0 }, // AV_CHANNEL_LAYOUT_7POINT1_WIDE_BACK, disabled in favor or PCE
configuration
+ AV_CHANNEL_LAYOUT_7POINT1_WIDE_BACK,
{ 0 },
{ 0 },
{ 0 },
@@ -70,7 +70,7 @@ static const uint8_t aac_chan_configs[14][6] = {
{3, TYPE_SCE, TYPE_CPE, TYPE_SCE}, // 4 channels -
front center + stereo + back center
{3, TYPE_SCE, TYPE_CPE, TYPE_CPE}, // 5 channels -
front center + stereo + back stereo
{4, TYPE_SCE, TYPE_CPE, TYPE_CPE, TYPE_LFE}, // 6 channels -
front center + stereo + back stereo + LFE
- {0},
+ {5, TYPE_SCE, TYPE_CPE, TYPE_CPE, TYPE_CPE, TYPE_LFE}, // 8 channels -
front center + front stereo + front center stereo + back stereo + LFE
{0},
{0},
{0},
@@ -90,7 +90,7 @@ static const uint8_t aac_chan_maps[14][AAC_MAX_CHANNELS] = {
{ 2, 0, 1, 3 },
{ 2, 0, 1, 3, 4 },
{ 2, 0, 1, 4, 5, 3 },
- { 0 },
+ { 2, 6, 7, 0, 1, 4, 5, 3 },
{ 0 },
{ 0 },
{ 0 },
--
2.52.0
_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]