mbox series

[FFmpeg-devel,0/7,v3] 22.2 channel layout support for AAC decoding

Message ID 20200801110730.30642-1-jeebjp@gmail.com
Headers show
Series 22.2 channel layout support for AAC decoding | expand

Message

Jan Ekström Aug. 1, 2020, 11:07 a.m. UTC
The decoding parts of this patch set have not changed from v2.
I have now added changes so that 22.2 gets properly handled as
5.1 (for which it has backwards compatibility) until it gets a
proper remix matrix defined in swresample. So
 -channel_layout "5.1"` now has been verified to just re-utilize
the six first channels as-is, and stereo output gets downmixed
from these known six channels. 

Now that we actually have sample(s) for channel_config 13, it was possible
to see at which various points the AAC decoder fails attempting to parse
the bit stream.

As the feature `-request_channel_layout 9223372036854775808` (AV_CH_LAYOUT_NATIVE)
seems to work, the channel order has been validated both visually with
Audacity, as well as by logging the post-reorder element ordering:

(what specific CPE/SCE/LFE elements mean is documented in the
`avcodec/aacdectab: add mapping for 22.2` commit):

Setting layout map list after reorder...
tag 0 = { pos: (null) (3), syn_elem: CPE, elem_id: 1 }
tag 1 = { pos: FC (4), syn_elem: SCE, elem_id: 0 }
tag 2 = { pos: LFE (8), syn_elem: LFE, elem_id: 0 }
tag 3 = { pos: (null) (30), syn_elem: CPE, elem_id: 3 }
tag 4 = { pos: (null) (c0), syn_elem: CPE, elem_id: 0 }
tag 5 = { pos: BC (100), syn_elem: SCE, elem_id: 1 }
tag 6 = { pos: LFE2 (800000000), syn_elem: LFE, elem_id: 1 }
tag 7 = { pos: (null) (600), syn_elem: CPE, elem_id: 2 }
tag 8 = { pos: (null) (5000), syn_elem: CPE, elem_id: 4 }
tag 9 = { pos: TFC (2000), syn_elem: SCE, elem_id: 2 }
tag 10 = { pos: TC (800), syn_elem: SCE, elem_id: 3 }
tag 11 = { pos: (null) (28000), syn_elem: CPE, elem_id: 6 }
tag 12 = { pos: (null) (3000000000), syn_elem: CPE, elem_id: 5 }
tag 13 = { pos: TBC (10000), syn_elem: SCE, elem_id: 4 }
tag 14 = { pos: BFC (8000000000), syn_elem: SCE, elem_id: 5 }
tag 15 = { pos: (null) (14000000000), syn_elem: CPE, elem_id: 7 }

Jan Ekström (7):
  avutil/channel_layout: add 22.2 layout
  swresample/matrix: switch internal clean_layout function to not drop
    high bits
  swresample/rematrix: treat 22.2 as 5.1 (back) when mixing
  avcodec/mpeg4audio: add newer channel_coding mappings
  avcodec/aacdectab: add mapping for 22.2
  avcodec/aacdec_template: mark second LFE element as LFE2
  avcodec/aacdec_template: add support for 22.2 / channel_config 13

 doc/APIchanges               |  5 ++
 libavcodec/aacdec_template.c | 98 ++++++++++++++++++++++++++++++++----
 libavcodec/aacdectab.h       | 23 ++++++++-
 libavcodec/mpeg4audio.c      | 17 ++++++-
 libavcodec/mpeg4audio.h      |  2 +-
 libavutil/channel_layout.c   |  6 +++
 libavutil/channel_layout.h   |  6 +++
 libavutil/version.h          |  2 +-
 libswresample/rematrix.c     | 12 ++++-
 9 files changed, 153 insertions(+), 18 deletions(-)

Comments

Jan Ekström Aug. 3, 2020, 9:40 p.m. UTC | #1
On Sat, Aug 1, 2020 at 2:07 PM Jan Ekström <jeebjp@gmail.com> wrote:
>
> The decoding parts of this patch set have not changed from v2.
> I have now added changes so that 22.2 gets properly handled as
> 5.1 (for which it has backwards compatibility) until it gets a
> proper remix matrix defined in swresample. So
>  -channel_layout "5.1"` now has been verified to just re-utilize
> the six first channels as-is, and stereo output gets downmixed
> from these known six channels.
>
> Now that we actually have sample(s) for channel_config 13, it was possible
> to see at which various points the AAC decoder fails attempting to parse
> the bit stream.
>
> As the feature `-request_channel_layout 9223372036854775808` (AV_CH_LAYOUT_NATIVE)
> seems to work, the channel order has been validated both visually with
> Audacity, as well as by logging the post-reorder element ordering:
>
> (what specific CPE/SCE/LFE elements mean is documented in the
> `avcodec/aacdectab: add mapping for 22.2` commit):
>
> Setting layout map list after reorder...
> tag 0 = { pos: (null) (3), syn_elem: CPE, elem_id: 1 }
> tag 1 = { pos: FC (4), syn_elem: SCE, elem_id: 0 }
> tag 2 = { pos: LFE (8), syn_elem: LFE, elem_id: 0 }
> tag 3 = { pos: (null) (30), syn_elem: CPE, elem_id: 3 }
> tag 4 = { pos: (null) (c0), syn_elem: CPE, elem_id: 0 }
> tag 5 = { pos: BC (100), syn_elem: SCE, elem_id: 1 }
> tag 6 = { pos: LFE2 (800000000), syn_elem: LFE, elem_id: 1 }
> tag 7 = { pos: (null) (600), syn_elem: CPE, elem_id: 2 }
> tag 8 = { pos: (null) (5000), syn_elem: CPE, elem_id: 4 }
> tag 9 = { pos: TFC (2000), syn_elem: SCE, elem_id: 2 }
> tag 10 = { pos: TC (800), syn_elem: SCE, elem_id: 3 }
> tag 11 = { pos: (null) (28000), syn_elem: CPE, elem_id: 6 }
> tag 12 = { pos: (null) (3000000000), syn_elem: CPE, elem_id: 5 }
> tag 13 = { pos: TBC (10000), syn_elem: SCE, elem_id: 4 }
> tag 14 = { pos: BFC (8000000000), syn_elem: SCE, elem_id: 5 }
> tag 15 = { pos: (null) (14000000000), syn_elem: CPE, elem_id: 7 }
>
> Jan Ekström (7):
>   avutil/channel_layout: add 22.2 layout
>   swresample/matrix: switch internal clean_layout function to not drop
>     high bits
>   swresample/rematrix: treat 22.2 as 5.1 (back) when mixing
>   avcodec/mpeg4audio: add newer channel_coding mappings
>   avcodec/aacdectab: add mapping for 22.2
>   avcodec/aacdec_template: mark second LFE element as LFE2
>   avcodec/aacdec_template: add support for 22.2 / channel_config 13
>
>  doc/APIchanges               |  5 ++
>  libavcodec/aacdec_template.c | 98 ++++++++++++++++++++++++++++++++----
>  libavcodec/aacdectab.h       | 23 ++++++++-
>  libavcodec/mpeg4audio.c      | 17 ++++++-
>  libavcodec/mpeg4audio.h      |  2 +-
>  libavutil/channel_layout.c   |  6 +++
>  libavutil/channel_layout.h   |  6 +++
>  libavutil/version.h          |  2 +-
>  libswresample/rematrix.c     | 12 ++++-
>  9 files changed, 153 insertions(+), 18 deletions(-)
>
> --
> 2.26.2
>

Thanks to everyone for reviews, this has now been applied with the
following small changes:
1. AV_CH_BOTTOM_FRONT_CENTER and AV_CH_BOTTOM_FRONT_LEFT were swapped
to match the 22.2 layout (I seem to have originally followed the way
of how the WaveFormatExtensible values were defined for top channels,
but decided after seeing that another channel layout that has bottom
channels also had center as the first one to just make it match the
22.2 ordering).
2. APIchanges was updated.

The diff for these small changes in the first commit was as follows. I
have verified that this had no effect on the decoded result.
diff --git a/doc/APIchanges b/doc/APIchanges
index d839b2c413..a9bf1afd4c 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -15,10 +15,10 @@ libavutil:     2017-10-21

 API changes, most recent first:

-2020-06-16 - xxxxxxxxxx - lavu 56.58.100 - channel_layout.h
+2020-08-04 - xxxxxxxxxx - lavu 56.58.100 - channel_layout.h
   Add AV_CH_LAYOUT_22POINT2 together with its newly required pieces:
-  AV_CH_TOP_SIDE_LEFT, AV_CH_TOP_SIDE_RIGHT, AV_CH_BOTTOM_FRONT_LEFT,
-  AV_CH_BOTTOM_FRONT_CENTER, AV_CH_BOTTOM_FRONT_RIGHT.
+  AV_CH_TOP_SIDE_LEFT, AV_CH_TOP_SIDE_RIGHT, AV_CH_BOTTOM_FRONT_CENTER,
+  AV_CH_BOTTOM_FRONT_LEFT, AV_CH_BOTTOM_FRONT_RIGHT.

 2020-07-xx - xxxxxxxxxx - lavu 56.57.100 - cpu.h
   Add AV_CPU_FLAG_MMI and AV_CPU_FLAG_MSA.
diff --git a/libavutil/channel_layout.c b/libavutil/channel_layout.c
index d6bfc74927..ac773a9e63 100644
--- a/libavutil/channel_layout.c
+++ b/libavutil/channel_layout.c
@@ -64,8 +64,8 @@ static const struct channel_name channel_names[] = {
     [35] = { "LFE2",      "low frequency 2"       },
     [36] = { "TSL",       "top side left"         },
     [37] = { "TSR",       "top side right"        },
-    [38] = { "BFL",       "bottom front left"     },
-    [39] = { "BFC",       "bottom front center"   },
+    [38] = { "BFC",       "bottom front center"   },
+    [39] = { "BFL",       "bottom front left"     },
     [40] = { "BFR",       "bottom front right"    },
 };

diff --git a/libavutil/channel_layout.h b/libavutil/channel_layout.h
index 43297505cb..d39ae1177a 100644
--- a/libavutil/channel_layout.h
+++ b/libavutil/channel_layout.h
@@ -73,8 +73,8 @@
 #define AV_CH_LOW_FREQUENCY_2        0x0000000800000000ULL
 #define AV_CH_TOP_SIDE_LEFT          0x0000001000000000ULL
 #define AV_CH_TOP_SIDE_RIGHT         0x0000002000000000ULL
-#define AV_CH_BOTTOM_FRONT_LEFT      0x0000004000000000ULL
-#define AV_CH_BOTTOM_FRONT_CENTER    0x0000008000000000ULL
+#define AV_CH_BOTTOM_FRONT_CENTER    0x0000004000000000ULL
+#define AV_CH_BOTTOM_FRONT_LEFT      0x0000008000000000ULL
 #define AV_CH_BOTTOM_FRONT_RIGHT     0x0000010000000000ULL

 /** Channel mask value used for AVCodecContext.request_channel_layout