PR #20936 opened by Lynne
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20936
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20936.patch

This commit implements support for decoding of MPEG Surround data 
(USAC-flavoured).

I'm raising funds and resources to build a rocket capable of striking the 
fraunhofer building in wherever.  Come join me, if we don't get enough we'll 
throw bricks at them.


>From 9050bd59491654b1dbfa29e15c6a26c1283b9fe8 Mon Sep 17 00:00:00 2001
From: Lynne <[email protected]>
Date: Thu, 13 Nov 2025 15:57:55 +0100
Subject: [PATCH 1/3] aacdec_tab: split up tables init

---
 libavcodec/aac/aacdec_tab.c | 39 ++++++++++++++++++++++++-------------
 1 file changed, 25 insertions(+), 14 deletions(-)

diff --git a/libavcodec/aac/aacdec_tab.c b/libavcodec/aac/aacdec_tab.c
index 45a84a9a72..dce1ebb39e 100644
--- a/libavcodec/aac/aacdec_tab.c
+++ b/libavcodec/aac/aacdec_tab.c
@@ -258,17 +258,33 @@ static const int8_t sbr_vlc_offsets[10] = {
     -60, -60, -24, -24, -31, -31, -12, -12, -31, -12
 };
 
+
 const VLCElem *ff_aac_sbr_vlc[10];
 
-static av_cold void aacdec_common_init(void)
+static av_cold void init_sbr_tables(void)
 {
-    static VLCElem vlc_buf[(304 + 270 + 550 + 300 + 328 +
-                            294 + 306 + 268 + 510 + 366 + 462) +
-                           (1098 + 1092 + 768 + 1026 + 1058 +
+    static VLCElem vlc_buf[(1098 + 1092 + 768 + 1026 + 1058 +
                             1052 +  544 + 544 +  592 + 512)];
     VLCInitState state = VLC_INIT_STATE(vlc_buf);
     const uint8_t (*tab)[2] = sbr_huffman_tab;
 
+    // SBR VLC table initialization
+    for (int i = 0; i < FF_ARRAY_ELEMS(ff_aac_sbr_vlc); i++) {
+        ff_aac_sbr_vlc[i] =
+            ff_vlc_init_tables_from_lengths(&state, 9, sbr_huffman_nb_codes[i],
+                                            &tab[0][1], 2,
+                                            &tab[0][0], 2, 1,
+                                            sbr_vlc_offsets[i], 0);
+        tab += sbr_huffman_nb_codes[i];
+    }
+}
+
+static av_cold void init_base_tables(void)
+{
+    static VLCElem vlc_buf[(304 + 270 + 550 + 300 + 328 +
+                            294 + 306 + 268 + 510 + 366 + 462)];
+    VLCInitState state = VLC_INIT_STATE(vlc_buf);
+
     for (unsigned i = 0; i < 11; i++) {
 #define TAB_WRAP_SIZE(name) name[i], sizeof(name[i][0]), sizeof(name[i][0])
         ff_vlc_spectral[i] =
@@ -287,17 +303,12 @@ static av_cold void aacdec_common_init(void)
                           ff_aac_scalefactor_code,
                           sizeof(ff_aac_scalefactor_code[0]),
                           sizeof(ff_aac_scalefactor_code[0]), 0);
+}
 
-    // SBR VLC table initialization
-    for (int i = 0; i < FF_ARRAY_ELEMS(ff_aac_sbr_vlc); i++) {
-        ff_aac_sbr_vlc[i] =
-            ff_vlc_init_tables_from_lengths(&state, 9, sbr_huffman_nb_codes[i],
-                                            &tab[0][1], 2,
-                                            &tab[0][0], 2, 1,
-                                            sbr_vlc_offsets[i], 0);
-        tab += sbr_huffman_nb_codes[i];
-    }
-
+static av_cold void aacdec_common_init(void)
+{
+    init_base_tables();
+    init_sbr_tables();
     ff_ps_init_common();
 }
 
-- 
2.49.1


>From b4ec61e91bd52a561e337600fd1a618bede714cf Mon Sep 17 00:00:00 2001
From: Lynne <[email protected]>
Date: Thu, 13 Nov 2025 15:58:16 +0100
Subject: [PATCH 2/3] aacdec_tab: add Mps212 tables

To be used in the following commit.
---
 libavcodec/aac/aacdec_tab.c | 466 ++++++++++++++++++++++++++++++++++++
 libavcodec/aac/aacdec_tab.h |  27 +++
 2 files changed, 493 insertions(+)

diff --git a/libavcodec/aac/aacdec_tab.c b/libavcodec/aac/aacdec_tab.c
index dce1ebb39e..a78230e3f8 100644
--- a/libavcodec/aac/aacdec_tab.c
+++ b/libavcodec/aac/aacdec_tab.c
@@ -279,6 +279,472 @@ static av_cold void init_sbr_tables(void)
     }
 }
 
+const int16_t ff_aac_hcod_firstband_CLD[30][2] = {
+    {   2,   1 }, {   4,   3 }, {   6,   5 }, {   8,   7 }, {  10,   9 },
+    {  12,  11 }, {  14,  13 }, {  -8,  15 }, {  -9,  16 }, { -10,  17 },
+    { -18,  18 }, { -17, -19 }, { -16,  19 }, { -11, -20 }, { -15, -21 },
+    {  -7,  20 }, { -22,  21 }, { -12, -14 }, { -13, -23 }, {  23,  22 },
+    { -24, -31 }, {  -6,  24 }, { -25, -26 }, {  26,  25 }, {  -5, -27 },
+    { -28,  27 }, {  -4,  28 }, { -29,  29 }, {  -1, -30 }, {  -2,  -3 },
+};
+
+const int16_t ff_aac_hcod1D_CLD[2 /* DT/DF */][30][2] = {
+    { {  -1,   1 }, {  -2,   2 }, {  -3,   3 }, {  -4,   4 }, {  -5,   5 },
+      {  -6,   6 }, {  -7,   7 }, {   9,   8 }, {  -8,  10 }, {  -9,  11 },
+      { -10,  12 }, { -11,  13 }, { -12,  14 }, { -13,  15 }, { -14,  16 },
+      { -15,  17 }, { -16,  18 }, { -17,  19 }, { -18,  20 }, { -19, -20 },
+      { -21,  21 }, { -22,  22 }, { -23,  23 }, {  25,  24 }, { -24,  26 },
+      { -25,  27 }, {  29,  28 }, { -26, -31 }, { -29, -30 }, { -27, -28 }, },
+    { {  -1,   1 }, {  -2,   2 }, {  -3,   3 }, {  -4,   4 }, {  -5,   5 },
+      {  -6,   6 }, {  -7,   7 }, {  -8,   8 }, {  -9,   9 }, { -10,  10 },
+      { -11,  11 }, { -12,  12 }, { -13,  13 }, {  15,  14 }, { -14,  16 },
+      { -15,  17 }, { -16,  18 }, { -17,  19 }, { -18,  20 }, { -19,  21 },
+      { -20, -21 }, { -23,  22 }, { -22,  23 }, { -24,  24 }, { -25,  25 },
+      {  27,  26 }, {  29,  28 }, { -30, -31 }, { -28, -29 }, { -26, -27 }, },
+};
+
+const int16_t ff_aac_hcod2D_CLD_03[2 /* _TP/_FP */ ][2 /* DT_/DF_ */ ][15][2] 
= {
+    { { {  -1,   1 }, { -52,   2 }, {   4,   3 }, {  -2,   5 }, { -17,   6 },
+        { -18,   7 }, { -36, -51 }, {   9,   8 }, { -35,  10 }, { -34,  11 },
+        { -19, -33 }, {  -3,  12 }, { -20,  13 }, { -50,  14 }, {  -4, -49 }, 
},
+      { {  -1,   1 }, { -52,   2 }, { -17,   3 }, {   5,   4 }, { -36,   6 },
+        { -33,   7 }, {  -2, -18 }, { -20,   8 }, {  10,   9 }, { -34, -49 },
+        { -51,  11 }, { -35,  12 }, { -19,  13 }, {  -3,  14 }, {  -4, -50 }, 
}, },
+    { { {  -1,   1 }, { -52,   2 }, { -17,   3 }, {   5,   4 }, {  -2, -36 },
+        { -18,   6 }, {   8,   7 }, { -51,   9 }, { -33,  10 }, { -34,  11 },
+        { -20, -35 }, { -19,  12 }, {  -3,  13 }, { -49,  14 }, {  -4, -50 }, 
},
+      { {   2,   1 }, {  -1, -52 }, {   4,   3 }, {  -2,   5 }, { -51,   6 },
+        { -17, -18 }, {   8,   7 }, {  10,   9 }, {  -3, -36 }, { -19,  11 },
+        { -35, -50 }, { -34,  12 }, {  -4,  13 }, { -33,  14 }, { -20, -49 }, 
}, },
+};
+
+const int16_t ff_aac_hcod2D_CLD_05[2 /* _TP/_FP */ ][2 /* DT_/DF_ */ ][35][2] 
= {
+    { { {   2,   1 }, { -86,   3 }, {   5,   4 }, {  -1,   6 }, {   8,   7 },
+        { -17, -18 }, {  -2,   9 }, { -70,  10 }, { -85,  11 }, {  13,  12 },
+        { -69,  14 }, { -34,  15 }, {  17,  16 }, { -19,  18 }, { -33, -35 },
+        { -54,  19 }, { -53,  20 }, {  -3,  21 }, { -68,  22 }, { -84,  23 },
+        { -50,  24 }, { -52,  25 }, { -51,  26 }, { -20, -36 }, { -49,  27 },
+        { -38,  28 }, { -37,  29 }, {  -4, -83 }, { -67,  30 }, { -66,  31 },
+        { -21,  32 }, { -22, -65 }, {  -5,  33 }, { -82,  34 }, {  -6, -81 }, 
},
+    { {   2,   1 }, {   4,   3 }, { -86,   5 }, {  -1,   6 }, { -17,   7 },
+        { -70,   8 }, {  10,   9 }, { -18,  11 }, { -33,  12 }, { -54,  13 },
+        {  -2,  14 }, { -34,  15 }, { -38,  16 }, { -49,  17 }, { -85,  18 },
+        { -50,  19 }, { -69,  20 }, { -53, -65 }, { -22,  21 }, { -66,  22 },
+        { -19,  23 }, { -37,  24 }, { -35, -81 }, {  -3,  25 }, { -51,  26 },
+        { -68, -84 }, { -52,  27 }, {  29,  28 }, { -20,  30 }, {  -4, -36 },
+        { -83,  31 }, { -67,  32 }, { -21,  33 }, {  -5,  34 }, {  -6, -82 }, 
}, },
+    { { {   2,   1 }, { -86,   3 }, {  -1,   4 }, { -17,   5 }, {   7,   6 },
+        { -70,   8 }, {  -2, -18 }, {  10,   9 }, {  12,  11 }, { -85,  13 },
+        { -33,  14 }, { -34, -54 }, {  16,  15 }, { -69,  17 }, {  19,  18 },
+        { -50, -53 }, { -19,  20 }, { -38,  21 }, { -35, -49 }, {  -3,  22 },
+        {  24,  23 }, { -68,  25 }, { -84,  26 }, { -65,  27 }, { -51, -66 },
+        { -22, -37 }, { -52,  28 }, { -20,  29 }, { -36,  30 }, { -81,  31 },
+        {  -4, -83 }, { -67,  32 }, { -21,  33 }, {  -5,  34 }, {  -6, -82 }, 
},
+      { {   2,   1 }, {   4,   3 }, { -86,   5 }, {   7,   6 }, {   9,   8 },
+        {  -1,  -2 }, { -85,  10 }, { -18,  11 }, { -17,  12 }, {  14,  13 },
+        { -70,  15 }, {  17,  16 }, { -19, -69 }, { -84,  18 }, {  -3,  19 },
+        {  21,  20 }, { -34, -68 }, { -20,  22 }, { -35,  23 }, { -83,  24 },
+        { -33,  25 }, {  -4,  26 }, { -53,  27 }, { -54, -67 }, { -36,  28 },
+        { -21, -52 }, { -82,  29 }, {  -5, -50 }, { -51,  30 }, { -38,  31 },
+        { -37, -49 }, {  -6,  32 }, { -66,  33 }, { -65,  34 }, { -22, -81 }, 
}, },
+};
+
+const int16_t ff_aac_hcod2D_CLD_07[2 /* _TP/_FP */ ][2 /* DT_/DF_ */ ][63][2] 
= {
+    { { {   2,   1 }, {   4,   3 }, {-120,   5 }, {   7,   6 }, {   9,   8 },
+        {  -1,  10 }, { -18,  11 }, { -17,  12 }, {  -2,-104 }, {-119,  13 },
+        {  15,  14 }, {-103,  16 }, {  18,  17 }, { -34,  19 }, { -19,  20 },
+        {  22,  21 }, { -35,  23 }, { -33,  24 }, { -88,  25 }, { -87,  26 },
+        {  28,  27 }, {  -3,-102 }, { -86,  29 }, { -52,-118 }, {  31,  30 },
+        { -50,  32 }, { -51,  33 }, { -70,  34 }, { -36,  35 }, { -85,  36 },
+        { -20,  37 }, {  39,  38 }, { -69, -71 }, { -72,  40 }, { -49, -67 },
+        {  42,  41 }, { -68,  43 }, {  -4,-101 }, { -53,-117 }, { -37,  44 },
+        { -66,  45 }, { -55,  46 }, {  48,  47 }, { -54,  49 }, { -21,  50 },
+        { -84,-100 }, { -56, -65 }, {  52,  51 }, { -82, -83 }, {  54,  53 },
+        {  -5,-116 }, { -22,  55 }, { -38,  56 }, { -39, -40 }, {  58,  57 },
+        { -81,-115 }, { -98, -99 }, {  -6,  59 }, { -23,  60 }, { -24,  61 },
+        {  -7, -97 }, {-114,  62 }, {  -8,-113 }, },
+    { {   2,   1 }, {   4,   3 }, {   6,   5 }, {-120,   7 }, { -17,   8 },
+        {  -1,-104 }, {  10,   9 }, {  12,  11 }, { -18,  13 }, { -33, -88 },
+        {  15,  14 }, {  17,  16 }, {  -2,  18 }, { -34,  19 }, { -72,  20 },
+        { -49,  21 }, {-119,  22 }, { -50,  23 }, {-103,  24 }, { -56,  25 },
+        { -65,  26 }, {  28,  27 }, { -40, -87 }, { -66,  29 }, { -82,  30 },
+        {  32,  31 }, { -19, -81 }, { -71,  33 }, { -97,  34 }, { -35, -55 },
+        { -24,  35 }, {  37,  36 }, {  -3, -98 }, { -51,  38 }, { -67,  39 },
+        { -39,-118 }, {-113,  40 }, {-102,  41 }, { -86,  42 }, { -70, -83 },
+        {  44,  43 }, { -20, -54 }, { -52,  45 }, { -36,  46 }, {  -4,  47 },
+        { -68,  48 }, { -85,  49 }, {-101,-117 }, { -69,  50 }, {  52,  51 },
+        { -21, -37 }, { -53,  53 }, {  55,  54 }, {  -5,-100 }, {-116,  56 },
+        { -84,  57 }, { -38,  58 }, { -22, -99 }, {-115,  59 }, {  -6,  60 },
+        { -23,  61 }, {  -7,  62 }, {-114,   0 }, }, },
+    { { {   2,   1 }, {-120,   3 }, {  -1,   4 }, {   6,   5 }, { -17,   7 },
+        {-104,   8 }, { -18,   9 }, {  -2,  10 }, {  12,  11 }, {  14,  13 },
+        {-119,  15 }, { -33,  16 }, { -34, -88 }, {-103,  17 }, {  19,  18 },
+        {  21,  20 }, {  23,  22 }, {  25,  24 }, { -19, -72 }, { -50,  26 },
+        { -49,  27 }, { -87,  28 }, {  30,  29 }, {  32,  31 }, {  -3, -35 },
+        {  34,  33 }, { -56,  35 }, { -65, -66 }, { -40,  36 }, { -82,-118 },
+        { -71,  37 }, { -55,  38 }, { -67,-102 }, { -51,  39 }, { -70,  40 },
+        {  42,  41 }, { -81,  43 }, { -86,  44 }, { -52, -97 }, { -98,  45 },
+        { -24, -39 }, { -20,  46 }, { -54, -83 }, { -36,  47 }, { -85,  48 },
+        { -68,  49 }, {  -4,  50 }, { -69,-113 }, {-117,  51 }, { -37,-101 },
+        { -53,  52 }, { -21,  53 }, {  55,  54 }, { -84,-100 }, {  -5,  56 },
+        {-116,  57 }, { -22,  58 }, { -38,-115 }, {  60,  59 }, {  -6, -99 },
+        { -23,  61 }, {-114,  62 }, {  -7,  -8 }, },
+      { {   2,   1 }, {   4,   3 }, {-120,   5 }, {   7,   6 }, {   9,   8 },
+        {  11,  10 }, {  -1,  12 }, { -18,-119 }, {  -2,  13 }, {  15,  14 },
+        { -17,  16 }, {-104,  17 }, {  19,  18 }, { -19,  20 }, {-103,  21 },
+        {-118,  22 }, {  24,  23 }, {  -3,  25 }, {  27,  26 }, { -34,  28 },
+        {-102,  29 }, { -20,  30 }, { -35,  31 }, {  33,  32 }, {-117,  34 },
+        { -33,  35 }, { -88,  36 }, {  -4,  37 }, { -87,  38 }, {  40,  39 },
+        { -36,-101 }, { -86,  41 }, { -21, -37 }, { -85,-100 }, { -52,  42 },
+        { -22,  43 }, {-116,  44 }, { -50 , 45 }, {  47,  46 }, {  -5, -51 },
+        {-115,  48 }, { -70,  49 }, { -84,  50 }, { -38, -49 }, { -72, -99 },
+        { -53,  51 }, { -69, -71 }, { -23,  52 }, {  -6, -67 }, {-114,  53 },
+        {  -7,  54 }, { -66, -68 }, { -55,  55 }, {  57,  56 }, { -54, -65 },
+        {  -8, -56 }, { -82, -83 }, {  59,  58 }, { -39, -40 }, { -81,  60 },
+        { -98,  61 }, { -97,  62 }, { -24,-113 }, }, },
+};
+
+const int16_t ff_aac_hcod2D_CLD_09[2 /* _TP/_FP */ ][2 /* DT_/DF_ */ ][99][2] 
= {
+    { { {   2,   1 }, {   4,   3 }, {-154,   5 }, {   7,   6 }, {   9,   8 },
+        {  11,  10 }, {  -1,  12 }, { -18,  13 }, { -17,  14 }, {  -2,-138 },
+        {  16,  15 }, {-153,  17 }, {-137,  18 }, {  20,  19 }, {  22,  21 },
+        { -34,  23 }, { -19,  24 }, { -35,  25 }, {  27,  26 }, {  29,  28 },
+        {-121,  30 }, {-120,  31 }, {-136,  32 }, { -33,-122 }, {  34,  33 },
+        {-152,  35 }, {  -3,  36 }, { -51,  37 }, { -52,  38 }, { -69,  39 },
+        { -36,  40 }, { -50,  41 }, {  43,  42 }, { -20,  44 }, {-104,  45 },
+        {-103,  46 }, { -87,  47 }, {-119,  48 }, {-105,  49 }, { -86,  50 },
+        {-102,  51 }, {-106,  52 }, { -49,-135 }, { -68,  53 }, {  55,  54 },
+        { -53,  56 }, { -67,-151 }, {  -4,  57 }, { -84,  58 }, { -85,  59 },
+        { -66,  60 }, { -37,  61 }, { -70,  62 }, { -54, -88 }, { -21,  63 },
+        {  65,  64 }, { -89,  66 }, {-118,  67 }, { -72,  68 }, { -90,  69 },
+        { -71,  70 }, { -65,-134 }, {-150,  71 }, { -83,  72 }, {  -5,  73 },
+        {-101,-117 }, { -82,  74 }, {  76,  75 }, { -99,  77 }, { -38,  78 },
+        {-100,  79 }, { -22,  80 }, { -73,  81 }, { -39, -74 }, {  83,  82 },
+        { -55, -81 }, { -57,  84 }, {-133,-149 }, { -56,  85 }, {  -6,  86 },
+        { -98,  87 }, {-132,  88 }, { -23,  89 }, {-114,  90 }, {-116,  91 },
+        { -58,-115 }, { -24,  92 }, { -97,-148 }, { -40, -41 }, {  -7, -42 },
+        {-147,  93 }, {  95,  94 }, {-131,  96 }, {  -8,-130 }, { -25,-113 },
+        {  -9,  97 }, { -26,-129 }, {-146,  98 }, { -10,-145 }, },
+      { {   2,   1 }, {   4,   3 }, {   6,   5 }, {-154,   7 }, {   9,   8 },
+        { -17,  10 }, {-138,  11 }, {  -1,  12 }, {  14,  13 }, {  16,  15 },
+        { -33,-122 }, { -18,  17 }, {  19,  18 }, { -34,  20 }, {  -2,  21 },
+        {-106,  22 }, { -49,  23 }, {  25,  24 }, { -50,  26 }, {-153,  27 },
+        { -90,  28 }, {-137,  29 }, { -65,  30 }, {  32,  31 }, { -66,  33 },
+        {-121,  34 }, { -74,  35 }, { -81,  36 }, {  38,  37 }, { -42,  39 },
+        { -82,  40 }, {-105,  41 }, { -19,-114 }, { -58,  42 }, { -35,  43 },
+        { -97,  44 }, {  46,  45 }, {-129,  47 }, { -26, -89 }, { -57, -98 },
+        { -51,  48 }, {  -3,  49 }, {-113,  50 }, {-130,  51 }, {-152,  52 },
+        { -67, -73 }, { -99,-136 }, {-145,  53 }, {-120,  54 }, { -41,  55 },
+        { -83,  56 }, { -72,  57 }, {-104,  58 }, {-115,  59 }, { -20,  60 },
+        {  62,  61 }, { -36, -88 }, { -84,  63 }, { -52, -56 }, {  65,  64 },
+        {  -4, -87 }, { -68,  66 }, {-151,  67 }, {-100,-135 }, {  69,  68 },
+        { -69,-119 }, {-103,  70 }, { -71,  71 }, {  73,  72 }, { -21,  74 },
+        { -85,  75 }, { -37, -53 }, { -86,  76 }, {  78,  77 }, {-102,-150 },
+        {  -5,  79 }, {-134,  80 }, {-118,  81 }, { -54,-117 }, {  83,  82 },
+        { -38, -70 }, { -22,  84 }, {  -6,  85 }, {  87,  86 }, { -55,  88 },
+        {-101,  89 }, {-133,-149 }, { -24, -39 }, {  91,  90 }, {-132,  92 },
+        { -23,  93 }, {  -7,  94 }, {-147,-148 }, {-116,-131 }, { -25,  95 },
+        { -40,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, }, },
+    { { {   2,   1 }, {-154,   3 }, {   5,   4 }, {  -1,   6 }, {   8,   7 },
+        { -17,   9 }, {-138,  10 }, { -18,  11 }, {  -2,  12 }, {  14,  13 },
+        {  16,  15 }, {-153,  17 }, { -34,  18 }, { -33,-122 }, {  20,  19 },
+        {  22,  21 }, {-137,  23 }, {  25,  24 }, {  27,  26 }, {-106,  28 },
+        {  30,  29 }, { -50,  31 }, { -19,  32 }, { -49,-121 }, {  34,  33 },
+        {  36,  35 }, { -35,  37 }, { -90,  38 }, { -66,  39 }, {  -3,  40 },
+        {  42,  41 }, { -65,  43 }, {-105,  44 }, {  46,  45 }, { -74,  47 },
+        { -51,  48 }, { -82,-152 }, {-136,  49 }, { -81,  50 }, { -42, -89 },
+        {-114,  51 }, {  53,  52 }, { -57, -58 }, {-120,  54 }, { -98,  55 },
+        { -67,  56 }, { -97,  57 }, {  59,  58 }, { -99,  60 }, { -73,-104 },
+        { -72,  61 }, {-113,  62 }, { -20, -83 }, { -84,-130 }, { -36,  63 },
+        { -26,  64 }, { -41,  65 }, { -52,-129 }, { -87, -88 }, {  67,  66 },
+        {-115,  68 }, { -68,  69 }, { -56, -69 }, {  -4,-100 }, {-151,  70 },
+        {-135,  71 }, {-103,-119 }, {  73,  72 }, { -71,-145 }, {-102,  74 },
+        {  76,  75 }, { -53, -85 }, { -37,  77 }, { -21, -86 }, {  79,  78 },
+        {  -5,  80 }, { -54,-134 }, {-150,  81 }, {-118,  82 }, { -70,  83 },
+        {-117,  84 }, { -22, -38 }, {-101,  85 }, { -55,  86 }, {-149,  87 },
+        { -39,  88 }, {-133,  89 }, {  -6,  90 }, {-116,  91 }, { -24,  92 },
+        {  -7,-132 }, { -23,  93 }, { -40,  94 }, {-131,-148 }, { -25,  95 },
+        {-147,  96 }, {-146,  97 }, {  -8,   0 }, {   0,   0 }, },
+      { {   2,   1 }, {   4,   3 }, {   6,   5 }, {-154,   7 }, {   9,   8 },
+        {  11,  10 }, {  13,  12 }, {  15,  14 }, { -18,  16 }, {-153,  17 },
+        {  -1,  -2 }, {  19,  18 }, {-138,  20 }, { -17,  21 }, {  23,  22 },
+        {  25,  24 }, { -19,-137 }, {  27,  26 }, {-152,  28 }, {  30,  29 },
+        {  -3, -34 }, {  32,  31 }, {  34,  33 }, {  36,  35 }, {-136,  37 },
+        { -35,  38 }, { -20,  39 }, {-122,  40 }, {-151,  41 }, { -33,  42 },
+        {-121,  43 }, {  45,  44 }, {  47,  46 }, {  -4,  48 }, { -36,-120 },
+        {-135,  49 }, {  51,  50 }, { -21,  52 }, {  54,  53 }, {  56,  55 },
+        { -50,-150 }, {  58,  57 }, { -51,  59 }, {  61,  60 }, {-119,  62 },
+        { -52,  63 }, {  -5,  64 }, { -37,  65 }, {-117,-134 }, { -39, -54 },
+        { -22,  66 }, {-106,  67 }, { -69,-102 }, {-132,  68 }, {-105,  69 },
+        { -49,  70 }, {-149,  71 }, { -24,-104 }, {  73,  72 }, { -53,  74 },
+        { -38,-118 }, {-103,  75 }, {  -6,  76 }, { -66, -87 }, {-133,-147 },
+        { -23,  77 }, { -67,  78 }, { -68, -86 }, { -70,-101 }, { -40,-148 },
+        {-116,  79 }, { -55,  80 }, { -84,-131 }, {  82,  81 }, { -89, -90 },
+        {  -7, -25 }, { -85, -88 }, { -65,  83 }, { -72,-146 }, {  85,  84 },
+        {  -9, -71 }, { -83,  86 }, { -82,  87 }, {  -8,  88 }, {-100,  89 },
+        { -74, -99 }, { -73,  90 }, { -10, -81 }, { -56,  91 }, { -57, -98 },
+        {  93,  92 }, { -58,-114 }, { -97,-115 }, {  95,  94 }, { -41,  96 },
+        { -42,  97 }, { -26,-129 }, {-113,  98 }, {-130,-145 }, },
+    },
+};
+
+const int16_t ff_aac_hcod_firstband_ICC[7][2] = {
+    {   2,   1 }, {  -5,   3 }, {  -4,  -6 }, {  -3,   4 }, {  -2,   5 },
+    {  -1,   6 }, {  -7,  -8 },
+};
+
+const int16_t ff_aac_hcod1D_ICC[7][2] = {
+    {  -1,   1 }, {  -2,   2 }, {  -3,   3 }, {  -4,   4 }, {  -5,   5 },
+    {  -6,   6 }, {  -7,  -8 },
+};
+
+const int16_t ff_aac_hcod2D_ICC_01[2 /* _TP/_FP */ ][2 /* DT_/DF_ */ ][3][2] = 
{
+    { { {  -1,   1 }, { -18,   2 }, {  -2, -17 }, },
+      { {  -1,   1 }, { -18,   2 }, {  -2, -17 }, }, },
+    { { {  -1,   1 }, { -18,   2 }, {  -2, -17 }, },
+      { {  -1,   1 }, { -18,   2 }, {  -2, -17 }, }, },
+};
+
+const int16_t ff_aac_hcod2D_ICC_03[2 /* _TP/_FP */ ][2 /* DT_/DF_ */ ][15][2] 
= {
+    { { { -52,   1 }, {  -1,   2 }, {   4,   3 }, {  -2,   5 }, { -17, -18 },
+        { -51,   6 }, { -36,   7 }, {   9,   8 }, { -35,  10 }, {  -3,  11 },
+        { -19, -34 }, { -33,  12 }, { -50,  13 }, { -20,  14 }, {  -4, -49 }, 
},
+      { {   2,   1 }, {  -1, -52 }, { -17,   3 }, {   5,   4 }, { -36,   6 },
+        {  -2,   7 }, { -18, -33 }, {   9,   8 }, { -20,  10 }, { -34, -51 },
+        { -49,  11 }, { -35,  12 }, { -19,  13 }, {  -3,  14 }, {  -4, -50 }, 
}, },
+    { { { -52,   1 }, {  -1,   2 }, {   4,   3 }, {  -2, -17 }, { -18,   5 },
+        { -36,   6 }, { -51,   7 }, {   9,   8 }, { -33,  10 }, { -34,  11 },
+        { -35,  12 }, { -19, -20 }, {  -3,  13 }, { -49,  14 }, {  -4, -50 }, 
},
+      { {   2,   1 }, {  -1, -52 }, {  -2,   3 }, {   5,   4 }, { -51,   6 },
+        { -18,   7 }, { -17,   8 }, {  -3,   9 }, { -36,  10 }, { -19, -50 },
+        { -35,  11 }, {  -4,  12 }, { -34,  13 }, { -33,  14 }, { -20, -49 }, 
},},
+};
+
+const int16_t ff_aac_hcod2D_ICC_05[2 /* _TP/_FP */ ][2 /* DT_/DF_ */ ][35][2] 
= {
+    { { {   2,   1 }, { -86,   3 }, {  -1,   4 }, {   6,   5 }, { -18,   7 },
+        {  -2, -17 }, {   9,   8 }, { -70,  10 }, { -69, -85 }, { -35,  11 },
+        {  13,  12 }, { -34,  14 }, { -19,  15 }, { -53,  16 }, { -68,  17 },
+        { -33,  18 }, {  -3, -52 }, {  20,  19 }, { -54,  21 }, { -84,  22 },
+        { -50,  23 }, { -20, -51 }, { -36,  24 }, {  26,  25 }, { -83,  27 },
+        {  -4, -38 }, { -49,  28 }, { -37,  29 }, { -67,  30 }, {  -5,  31 },
+        { -21,  32 }, { -65, -66 }, { -82,  33 }, { -22,  34 }, {  -6, -81 }, 
},
+      { {   2,   1 }, { -86,   3 }, {  -1,   4 }, { -17,   5 }, {   7,   6 },
+        { -70,   8 }, { -33,   9 }, { -18,  10 }, {  -2,  11 }, { -54,  12 },
+        { -49,  13 }, { -38,  14 }, { -34, -65 }, { -85,  15 }, { -50,  16 },
+        { -69,  17 }, { -22,  18 }, { -53,  19 }, {  21,  20 }, { -19, -81 },
+        { -66,  22 }, {  -3, -35 }, {  24,  23 }, { -37,  25 }, { -68, -84 },
+        { -51,  26 }, {  28,  27 }, { -20, -52 }, {  30,  29 }, {  -4, -36 },
+        { -83,  31 }, { -67,  32 }, { -82,  33 }, { -21,  34 }, {  -5,  -6 }, 
}, },
+    { { {  -1,   1 }, { -86,   2 }, {   4,   3 }, { -17,   5 }, {  -2,   6 },
+        { -18,   7 }, { -70,   8 }, { -85,   9 }, {  11,  10 }, {  13,  12 },
+        { -33,  14 }, {  16,  15 }, { -34, -54 }, { -69,  17 }, { -38,  18 },
+        { -50,  19 }, { -35, -53 }, { -49,  20 }, { -19,  21 }, {  -3,  22 },
+        { -65,  23 }, { -68,  24 }, { -22,  25 }, { -81, -84 }, { -66,  26 },
+        { -37,  27 }, { -20, -51 }, {  29,  28 }, { -52,  30 }, {  -4, -83 },
+        { -36,  31 }, { -67,  32 }, {  -5,  33 }, { -82,  34 }, { -21,   0 }, 
},
+      { {   2,   1 }, { -86,   3 }, {  -1,   4 }, {   6,   5 }, {  -2,   7 },
+        { -85,   8 }, { -18,   9 }, {  11,  10 }, { -17,  12 }, {  14,  13 },
+        { -70,  15 }, {  -3, -19 }, { -69,  16 }, { -84,  17 }, { -68,  18 },
+        { -20, -35 }, { -34, -83 }, {  20,  19 }, {  -4,  21 }, { -33,  22 },
+        {  -5,  23 }, { -53,  24 }, { -36, -52 }, { -67,  25 }, { -21, -82 },
+        { -54,  26 }, {  -6,  27 }, { -51,  28 }, { -50,  29 }, { -49,  30 },
+        { -37,  31 }, { -38,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, 
}, },
+};
+
+const int16_t ff_aac_hcod2D_ICC_07[2 /* _TP/_FP */ ][2 /* DT_/DF_ */ ][63][2] 
= {
+    { { {   2,   1 }, {  -1,-120 }, {   4,   3 }, {   6,   5 }, { -18,   7 },
+        {   9,   8 }, { -17,  10 }, {  -2,  11 }, {-103,  12 }, { -52,  13 },
+        { -35,-104 }, {-119,  14 }, {  16,  15 }, { -69, -86 }, {  18,  17 },
+        { -34,  19 }, { -19,  20 }, {  22,  21 }, { -70,  23 }, { -87,  24 },
+        {-102,  25 }, { -85,  26 }, { -33,  27 }, { -36,  28 }, {  -3,  29 },
+        { -88,  30 }, { -51,  31 }, {-118,  32 }, {  34,  33 }, { -68,  35 },
+        { -53,  36 }, { -67,  37 }, { -20,  38 }, {-101,  39 }, { -50,  40 },
+        {  42,  41 }, { -37,  43 }, {-116,  44 }, {-117,  45 }, { -49,  46 },
+        { -21,-100 }, {  48,  47 }, { -55, -71 }, {  -4,  49 }, { -22, -84 },
+        {-115,  50 }, { -66, -82 }, { -72,  51 }, {  -5,  -6 }, { -54,  52 },
+        { -38,  53 }, { -83,  54 }, { -40,  55 }, { -39,  56 }, { -99,  57 },
+        { -23, -56 }, {  -7,  58 }, { -65, -97 }, {  -8,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, },
+      { {   2,   1 }, {   4,   3 }, {  -1,-120 }, {   6,   5 }, {   8,   7 },
+        { -18,   9 }, {  -2,  10 }, {  12,  11 }, {  14,  13 }, { -17,-119 },
+        {  16,  15 }, {-103,  17 }, {-104,  18 }, { -52,  19 }, {  21,  20 },
+        { -69,  22 }, {  24,  23 }, {  -3, -35 }, { -19,  25 }, { -34, -85 },
+        {  27,  26 }, { -86,  28 }, {-118,  29 }, { -37,  30 }, {  32,  31 },
+        {-102,  33 }, { -20, -22 }, {  -4,-117 }, { -87,  34 }, {-100,  35 },
+        { -33, -36 }, {  37,  36 }, { -70, -88 }, {-101,  38 }, {  -5,  39 },
+        { -51, -53 }, { -50,  40 }, {-115,  41 }, { -21,  42 }, {-116,  43 },
+        { -38,  44 }, { -23, -84 }, { -49, -99 }, {  46,  45 }, {  -6,-114 },
+        {  -7, -72 }, { -71,  47 }, {  -8,   0 }, {   0,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, }, },
+    { { {  -1,   1 }, {-120,   2 }, {   4,   3 }, { -17,   5 }, {  -2,   6 },
+        {   8,   7 }, { -18,   9 }, {-104,  10 }, {  12,  11 }, {  14,  13 },
+        {  16,  15 }, {-119,  17 }, { -81,  18 }, {  20,  19 }, { -33,  21 },
+        { -88,  22 }, {-103,  23 }, { -34,  24 }, { -56,  25 }, { -72,  26 },
+        { -49,  27 }, { -82,  28 }, { -50,  29 }, { -65,  30 }, { -55, -87 },
+        { -19,  31 }, { -67,  32 }, { -35, -40 }, {  34,  33 }, { -52, -71 },
+        { -66,  35 }, { -70,  36 }, {  38,  37 }, { -51, -97 }, { -86,-102 },
+        {  -3,  39 }, {-118,  40 }, {  42,  41 }, { -24, -85 }, { -54,  43 },
+        { -39,  44 }, { -98,-113 }, { -36, -37 }, { -20, -69 }, {  -4,  45 },
+        {  -5,  46 }, { -21,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, },
+      { {   2,   1 }, {   4,   3 }, {  -1,-120 }, {   6,   5 }, {   8,   7 },
+        { -18,   9 }, {  -2,  10 }, {  12,  11 }, {  14,  13 }, { -17,-119 },
+        {  16,  15 }, {-103,  17 }, {-104,  18 }, { -52,  19 }, {  21,  20 },
+        { -69,  22 }, {  24,  23 }, {  -3, -35 }, { -19,  25 }, { -34, -85 },
+        {  27,  26 }, { -86,  28 }, {-118,  29 }, { -37,  30 }, {  32,  31 },
+        {-102,  33 }, { -20, -22 }, {  -4,-117 }, { -87,  34 }, {-100,  35 },
+        { -33, -36 }, {  37,  36 }, { -70, -88 }, {-101,  38 }, {  -5,  39 },
+        { -51, -53 }, { -50,  40 }, {-115,  41 }, { -21,  42 }, {-116,  43 },
+        { -38,  44 }, { -23, -84 }, { -49, -99 }, {  46,  45 }, {  -6,-114 },
+        {  -7, -72 }, { -71,  47 }, {  -8,   0 }, {   0,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, }, },
+};
+
+const int16_t ff_aac_hcod_firstband_IPD[7][2] = {
+    {  -1,   1 }, {  -8,   2 }, {  -2,   3 }, {   5,   4 }, {  -7,   6 },
+    {  -3,  -5 }, {  -4,  -6 },
+};
+
+const int16_t ff_aac_hcod1D_IPD[2 /* DT, DF */ ][7][2] = {
+    { {  -1,   1 }, {  -2,   2 }, {  -8,   3 }, {  -3,   4 }, {  -7,   5 },
+      {  -4,   6 }, {  -5,  -6 }, }, /* DT */
+    { {  -1,   1 }, {  -8,   2 }, {  -2,   3 }, {   5,   4 }, {  -3,  -7 },
+      {  -6,   6 }, {  -4,  -5 }, }, /* DF */
+};
+
+const int16_t ff_aac_hcod2D_IPD_01[2 /* _TP/_FP */ ][2 /* DT_/DF_ */ ][3][2] = 
{
+    { { {  -1,   1 }, { -18,   2 }, { -17,   0 }, },
+      { {  -1,   1 }, { -18,   2 }, { -17,   0 }, }, },
+    { { {  -1,   1 }, { -18,   2 }, { -17,   0 }, },
+      { {  -1,   1 }, { -18,   2 }, { -17,   0 }, }, },
+};
+
+const int16_t ff_aac_hcod2D_IPD_03[2 /* _TP/_FP */ ][2 /* DT_/DF_ */ ][15][2] 
= {
+    { { {  -1,   1 }, {   3,   2 }, { -18,   4 }, { -52,   5 }, { -34, -36 },
+        { -35,   6 }, { -17,   7 }, { -33,   8 }, { -20,   9 }, { -49,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, 
},
+      { {  -1,   1 }, { -36,   2 }, { -18,   3 }, { -35,   4 }, { -52,   5 },
+        {   7,   6 }, { -34,   8 }, { -33, -49 }, { -20,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, 
}, },
+    { { {  -1,   1 }, {   3,   2 }, { -18,   4 }, { -52,   5 }, { -34, -36 },
+        { -35,   6 }, { -17,   7 }, { -33,   8 }, { -20,   9 }, { -49,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, 
},
+      { {  -1,   1 }, { -36,   2 }, { -18,   3 }, { -35,   4 }, { -52,   5 },
+        {   7,   6 }, { -34,   8 }, { -33, -49 }, { -20,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, 
}, },
+};
+
+const int16_t ff_aac_hcod2D_IPD_05[2 /* _TP/_FP */ ][2 /* DT_/DF_ */ ][35][2] 
= {
+    { { {  -1,   1 }, {   3,   2 }, { -52,   4 }, { -86,   5 }, { -35,   6 },
+        { -53,   7 }, { -70,   8 }, { -17,   9 }, { -37,  10 }, {  12,  11 },
+        { -38, -66 }, { -18,  13 }, { -51,  14 }, {  16,  15 }, { -34, -69 },
+        {  18,  17 }, { -54, -65 }, { -50,  19 }, { -33, -49 }, { -22,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, 
},
+      { {  -1,   1 }, {   3,   2 }, {   5,   4 }, { -86,   6 }, { -66,   7 },
+        {   9,   8 }, {  11,  10 }, { -18,  12 }, { -51,  13 }, { -37, -52 },
+        { -69,  14 }, { -38,  15 }, { -53,  16 }, { -35,  17 }, { -50, -70 },
+        { -22, -49 }, { -33,  18 }, { -17,  19 }, { -34, -65 }, { -81,  20 },
+        { -54,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, 
}, },
+    { { {  -1,   1 }, {   3,   2 }, { -52,   4 }, { -86,   5 }, { -35,   6 },
+        { -53,   7 }, { -70,   8 }, { -17,   9 }, { -37,  10 }, {  12,  11 },
+        { -38, -66 }, { -18,  13 }, { -51,  14 }, {  16,  15 }, { -34, -69 },
+        {  18,  17 }, { -54, -65 }, { -50,  19 }, { -33, -49 }, { -22,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, 
},
+      { {  -1,   1 }, {   3,   2 }, {   5,   4 }, { -86,   6 }, { -66,   7 },
+        {   9,   8 }, {  11,  10 }, { -18,  12 }, { -51,  13 }, { -37, -52 },
+        { -69,  14 }, { -38,  15 }, { -53,  16 }, { -35,  17 }, { -50, -70 },
+        { -22, -49 }, { -33,  18 }, { -17,  19 }, { -34, -65 }, { -81,  20 },
+        { -54,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, 
}, },
+};
+
+const int16_t ff_aac_hcod2D_IPD_07[2 /* _TP/_FP */ ][2 /* DT_/DF_ */ ][63][2] 
= {
+    { { {  -1,   1 }, { -69,   2 }, {   4,   3 }, {-120,   5 }, {   7,   6 },
+        {-113,   8 }, { -68,   9 }, {  11,  10 }, { -17,  12 }, { -52,  13 },
+        { -24,  14 }, { -18,  15 }, {  17,  16 }, {-104,  18 }, {  20,  19 },
+        { -54, -70 }, {  22,  21 }, {  24,  23 }, { -86, -97 }, {-103,  25 },
+        { -83,  26 }, { -35,  27 }, { -34, -98 }, { -40,  28 }, { -39, -67 },
+        {  30,  29 }, { -33, -51 }, { -87,  31 }, { -88,  32 }, { -82,  33 },
+        { -55, -81 }, { -56, -71 }, { -72,  34 }, { -50, -66 }, { -65,  35 },
+        { -49,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, },
+      { {   2,   1 }, {   4,   3 }, {  -1,   5 }, { -69,   6 }, {-120,   7 },
+        { -68,   8 }, {  10,   9 }, {  12,  11 }, {  14,  13 }, { -52, -54 },
+        { -18,  15 }, { -70,  16 }, { -67,  17 }, {  19,  18 }, { -17,  20 },
+        {-113,  21 }, {  23,  22 }, { -83,  24 }, { -24,  25 }, {-103,-104 },
+        { -51, -55 }, {  27,  26 }, { -71,  28 }, { -86,  29 }, { -35,  30 },
+        { -66,  31 }, { -39, -50 }, { -82, -98 }, { -72,  32 }, { -56, -87 },
+        { -34,  33 }, { -33, -88 }, { -40, -97 }, { -65,  34 }, { -49,  35 },
+        { -81,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, }, },
+    { { {  -1,   1 }, { -69,   2 }, {   4,   3 }, {-120,   5 }, {   7,   6 },
+        {-113,   8 }, { -68,   9 }, {  11,  10 }, { -17,  12 }, { -52,  13 },
+        { -24,  14 }, { -18,  15 }, {  17,  16 }, {-104,  18 }, {  20,  19 },
+        { -54, -70 }, {  22,  21 }, {  24,  23 }, { -86, -97 }, {-103,  25 },
+        { -83,  26 }, { -35,  27 }, { -34, -98 }, { -40,  28 }, { -39, -67 },
+        {  30,  29 }, { -33, -51 }, { -87,  31 }, { -88,  32 }, { -82,  33 },
+        { -55, -81 }, { -56, -71 }, { -72,  34 }, { -50, -66 }, { -65,  35 },
+        { -49,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, },
+      { {   2,   1 }, {   4,   3 }, {  -1,   5 }, { -69,   6 }, {-120,   7 },
+        { -68,   8 }, {  10,   9 }, {  12,  11 }, {  14,  13 }, { -52, -54 },
+        { -18,  15 }, { -70,  16 }, { -67,  17 }, {  19,  18 }, { -17,  20 },
+        {-113,  21 }, {  23,  22 }, { -83,  24 }, { -24,  25 }, {-103,-104 },
+        { -51, -55 }, {  27,  26 }, { -71,  28 }, { -86,  29 }, { -35,  30 },
+        { -66,  31 }, { -39, -50 }, { -82, -98 }, { -72,  32 }, { -56, -87 },
+        { -34,  33 }, { -33, -88 }, { -40, -97 }, { -65,  34 }, { -49,  35 },
+        { -81,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 }, {   0,   0 },
+        {   0,   0 }, {   0,   0 }, {   0,   0 }, }, },
+};
+
+const int16_t ff_aac_hcod_lav_idx[3][2] = {
+    {  -1,   1 }, {  -2,   2 }, {  -3,  -4 },
+};
+
+const int16_t ff_aac_hcod2D_reshape[39][2] = {
+    {   2,   1 }, {   4,   3 }, {   6,   5 }, { -33,   7 }, { -17,   8 },
+    { -49,   9 }, { -34,  10 }, {  12,  11 }, { -18, -35 }, { -50,  13 },
+    {  15,  14 }, { -40,  16 }, { -36,  17 }, { -19,  18 }, {  -1, -37 },
+    { -51,  19 }, {  21,  20 }, { -38, -65 }, {  -2, -39 }, { -20,  22 },
+    { -52,  23 }, {  25,  24 }, { -21,  26 }, { -66,  27 }, { -53,  28 },
+    {  -3,  29 }, {  31,  30 }, { -22,  32 }, { -54,  33 }, {  -4,  34 },
+    { -56,  35 }, { -24, -67 }, { -23, -55 }, {  -8, -72 }, {  -5,  36 },
+    { -68,  37 }, {  -6,  38 }, {  -7, -69 }, { -70, -71 },
+};
+
+const uint8_t ff_aac_lav_tab_XXX[3][4] = {
+    { 3, 5, 7, 9 }, { 1, 3, 5, 7 }, { 7, 1, 3, 5 }
+};
+
 static av_cold void init_base_tables(void)
 {
     static VLCElem vlc_buf[(304 + 270 + 550 + 300 + 328 +
diff --git a/libavcodec/aac/aacdec_tab.h b/libavcodec/aac/aacdec_tab.h
index 70e49af202..e4b57527a1 100644
--- a/libavcodec/aac/aacdec_tab.h
+++ b/libavcodec/aac/aacdec_tab.h
@@ -50,6 +50,33 @@ extern const uint8_t ff_aac_channel_layout_map[16][16][3];
 extern const int16_t ff_aac_channel_map[3][4][6];
 
 extern const AVChannelLayout ff_aac_ch_layout[];
+
+extern const int16_t ff_aac_hcod_firstband_CLD[30][2];
+extern const int16_t ff_aac_hcod1D_CLD[2 /* DT_/DF_ */][30][2];
+extern const int16_t ff_aac_hcod2D_CLD_03[2 /* _TP/_FP */ ][2 /* DT_/DF_ */ 
][15][2];
+extern const int16_t ff_aac_hcod2D_CLD_05[2 /* _TP/_FP */ ][2 /* DT_/DF_ */ 
][35][2];
+extern const int16_t ff_aac_hcod2D_CLD_07[2 /* _TP/_FP */ ][2 /* DT_/DF_ */ 
][63][2];
+extern const int16_t ff_aac_hcod2D_CLD_09[2 /* _TP/_FP */ ][2 /* DT_/DF_ */ 
][99][2];
+
+extern const int16_t ff_aac_hcod_firstband_ICC[7][2];
+extern const int16_t ff_aac_hcod1D_ICC[7][2];
+extern const int16_t ff_aac_hcod2D_ICC_01[2 /* _TP/_FP */ ][2 /* DT_/DF_ */ 
][3][2];
+extern const int16_t ff_aac_hcod2D_ICC_03[2 /* _TP/_FP */ ][2 /* DT_/DF_ */ 
][15][2];
+extern const int16_t ff_aac_hcod2D_ICC_05[2 /* _TP/_FP */ ][2 /* DT_/DF_ */ 
][35][2];
+extern const int16_t ff_aac_hcod2D_ICC_07[2 /* _TP/_FP */ ][2 /* DT_/DF_ */ 
][63][2];
+
+extern const int16_t ff_aac_hcod_firstband_IPD[7][2];
+extern const int16_t ff_aac_hcod1D_IPD[2 /* DF, DT */ ][7][2];
+extern const int16_t ff_aac_hcod2D_IPD_01[2 /* _TP/_FP */ ][2 /* DT_/DF_ */ 
][3][2];
+extern const int16_t ff_aac_hcod2D_IPD_03[2 /* _TP/_FP */ ][2 /* DT_/DF_ */ 
][15][2];
+extern const int16_t ff_aac_hcod2D_IPD_05[2 /* _TP/_FP */ ][2 /* DT_/DF_ */ 
][35][2];
+extern const int16_t ff_aac_hcod2D_IPD_07[2 /* _TP/_FP */ ][2 /* DT_/DF_ */ 
][63][2];
+
+extern const int16_t ff_aac_hcod_lav_idx[3][2];
+
+extern const int16_t ff_aac_hcod2D_reshape[39][2];
+
+extern const uint8_t ff_aac_lav_tab_XXX[3][4];
 FF_VISIBILITY_POP_HIDDEN
 
 #endif /* AVCODEC_AAC_AACDEC_TAB_H */
-- 
2.49.1


>From 46f5373fe4f58e0c94ba8170efd4a7f41557ff7b Mon Sep 17 00:00:00 2001
From: Lynne <[email protected]>
Date: Mon, 17 Nov 2025 06:29:19 +0100
Subject: [PATCH 3/3] aacdec_usac: add support for decoding MPEG Surround
 (USAC-flavoured)

---
 libavcodec/aac/Makefile             |   3 +-
 libavcodec/aac/aacdec_usac.c        |   4 +-
 libavcodec/aac/aacdec_usac_mps212.c | 537 ++++++++++++++++++++++++++++
 libavcodec/aac/aacdec_usac_mps212.h |  41 +++
 4 files changed, 582 insertions(+), 3 deletions(-)
 create mode 100644 libavcodec/aac/aacdec_usac_mps212.c
 create mode 100644 libavcodec/aac/aacdec_usac_mps212.h

diff --git a/libavcodec/aac/Makefile b/libavcodec/aac/Makefile
index 70b1dca274..b1ec21b188 100644
--- a/libavcodec/aac/Makefile
+++ b/libavcodec/aac/Makefile
@@ -3,6 +3,7 @@ clean::
 
 OBJS-$(CONFIG_AAC_DECODER)          +=  aac/aacdec.o aac/aacdec_tab.o \
                                         aac/aacdec_float.o aac/aacdec_usac.o \
-                                        aac/aacdec_ac.o aac/aacdec_lpd.o
+                                        aac/aacdec_ac.o aac/aacdec_lpd.o \
+                                        aac/aacdec_usac_mps212.o
 OBJS-$(CONFIG_AAC_FIXED_DECODER)    +=  aac/aacdec.o aac/aacdec_tab.o \
                                         aac/aacdec_fixed.o
diff --git a/libavcodec/aac/aacdec_usac.c b/libavcodec/aac/aacdec_usac.c
index c4b821bbba..66b7088031 100644
--- a/libavcodec/aac/aacdec_usac.c
+++ b/libavcodec/aac/aacdec_usac.c
@@ -31,6 +31,8 @@
 #include "libavutil/mem.h"
 #include "libavutil/refstruct.h"
 
+#include "aacdec_usac_mps212.h"
+
 /* Number of scalefactor bands per complex prediction band, equal to 2. */
 #define SFB_PER_PRED_BAND 2
 
@@ -1483,8 +1485,6 @@ static int decode_usac_core_coder(AACDecContext *ac, 
AACUSACConfig *usac,
     }
 
     if (ec->stereo_config_index) {
-        avpriv_report_missing_feature(ac->avctx, "AAC USAC Mps212");
-        return AVERROR_PATCHWELCOME;
     }
 
     spectrum_decode(ac, usac, che, core_nb_channels);
diff --git a/libavcodec/aac/aacdec_usac_mps212.c 
b/libavcodec/aac/aacdec_usac_mps212.c
new file mode 100644
index 0000000000..f1ad4ad15c
--- /dev/null
+++ b/libavcodec/aac/aacdec_usac_mps212.c
@@ -0,0 +1,537 @@
+/*
+ * Copyright (c) 2025 Lynne <[email protected]>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "aacdec_tab.h"
+#include "libavcodec/get_bits.h"
+#include "libavutil/macros.h"
+
+#include "aacdec_usac_mps212.h"
+
+static int huff_dec_1D(GetBitContext *gb, const int16_t (*tab)[2])
+{
+    int16_t idx = 0;
+    do {
+        /* Overreads are not possible here, the array forms a closed set */
+        idx = tab[idx][get_bits1(gb)];
+    } while (idx > 0);
+    return idx;
+}
+
+static int huff_dec_2D(GetBitContext *gb, const int16_t (*tab)[2], int16_t 
ret[2])
+{
+    int idx = huff_dec_1D(gb, tab);
+    if (!idx) { /* Escape */
+        ret[0] = 0;
+        ret[1] = 1;
+        return 1;
+    }
+
+    idx = -(idx + 1);
+    ret[0] = idx >> 4;
+    ret[1] = idx & 0xf;
+    return 0;
+}
+
+static int huff_data_1d(GetBitContext *gb, int16_t *data, int data_bands,
+                        enum MPSDataType data_type, int diff_freq, int p0_flag)
+{
+    const int16_t (*hcod_first_band)[2];
+    const int16_t (*hcod1D)[2];
+    switch (data_type) {
+    case MPS_CLD:
+        hcod_first_band = ff_aac_hcod_firstband_CLD;
+        hcod1D = ff_aac_hcod1D_CLD[diff_freq];
+        break;
+    case MPS_ICC:
+        hcod_first_band = ff_aac_hcod_firstband_ICC;
+        hcod1D = ff_aac_hcod1D_ICC;
+        break;
+    case MPS_IPD:
+        hcod_first_band = ff_aac_hcod_firstband_IPD;
+        hcod1D = ff_aac_hcod1D_IPD[diff_freq];
+        break;
+    }
+
+    if (p0_flag)
+        data[0] = -(huff_dec_1D(gb, hcod_first_band) + 1);
+
+    for (int off = diff_freq; off < data_bands; off++) {
+        int16_t val = -(huff_dec_1D(gb, hcod1D) + 1);
+        if (val && data_type != MPS_IPD)
+            val = get_bits1(gb) ? -val : val;
+        data[off] = val;
+    }
+
+    return 0;
+}
+
+static void symmetry_data(GetBitContext *gb, int16_t data[2],
+                          uint8_t lav, enum MPSDataType data_type)
+{
+    int16_t sum = data[0] + data[1];
+    int16_t diff = data[0] - data[1];
+
+    if (sum > lav) {
+        data[0] = -sum + (2*lav + 1);
+        data[1] = -diff;
+    } else {
+        data[0] = sum;
+        data[1] = diff;
+    }
+
+    if ((data_type != MPS_IPD) && (data[0] + data[1])) {
+        int sym = get_bits1(gb) ? -1 : 1;
+        data[0] *= sym;
+        data[1] *= sym;
+    }
+
+    if (data[0] - data[1]) {
+        if (get_bits1(gb))
+            FFSWAP(int16_t, data[0], data[1]);
+    }
+}
+
+static void pcm_decode(GetBitContext *gb, int16_t *data0, int16_t *data1,
+                       int16_t offset, int nb_pcm_data_bands,
+                       int nb_quant_steps, int nb_levels)
+{
+    int max_group_len;
+    switch (nb_levels) {
+    case  3: max_group_len = 5; break;
+    case  7: max_group_len = 6; break;
+    case 11: max_group_len = 2; break;
+    case 13: max_group_len = 4; break;
+    case 19: max_group_len = 4; break;
+    case 25: max_group_len = 3; break;
+    case 51: max_group_len = 4; break;
+    case  4: case  8: case 15: case 16: case 26: case 31:
+        max_group_len = 1;
+        break;
+    default:
+        return;
+    };
+
+    for (int i = 0; i < nb_pcm_data_bands; i+= max_group_len) {
+        int group_len = FFMIN(max_group_len, nb_pcm_data_bands - i);
+        int nb_bits = ceilf(group_len*log2f(nb_quant_steps));
+        int pcm = get_bits(gb, nb_bits);
+        for (int j = 0; j < group_len; j++) {
+            int idx = i + (group_len - 1) - j;
+            int val = pcm % nb_quant_steps;
+            if (data0 && data1) {
+                if (idx % 2)
+                    data1[idx / 2] = val - offset;
+                else
+                    data0[idx / 2] = val - offset;
+            } else if (!data1) {
+                data0[idx] = val - offset;
+            } else if (!data0) {
+                data1[idx] = val - offset;
+            }
+            pcm = (pcm - val) / nb_quant_steps;
+        }
+    }
+}
+
+static void huff_data_2d(GetBitContext *gb, int16_t *part0_data[2], int16_t 
(*data)[2],
+                         int data_bands, int stride, enum MPSDataType 
data_type,
+                         int diff_freq, int freq_pair)
+{
+    int16_t lav_idx = huff_dec_1D(gb, ff_aac_hcod_lav_idx);
+    uint8_t lav = ff_aac_lav_tab_XXX[data_type][-(lav_idx + 1)];
+
+    const int16_t (*hcod1D)[2];
+    const int16_t (*hcod2D)[2];
+    switch (data_type) {
+    case MPS_CLD:
+        hcod1D = ff_aac_hcod1D_CLD[diff_freq];
+        switch (lav) {
+        case 3: hcod2D = ff_aac_hcod2D_CLD_03[freq_pair][diff_freq]; break;
+        case 5: hcod2D = ff_aac_hcod2D_CLD_05[freq_pair][diff_freq]; break;
+        case 7: hcod2D = ff_aac_hcod2D_CLD_07[freq_pair][diff_freq]; break;
+        case 9: hcod2D = ff_aac_hcod2D_CLD_09[freq_pair][diff_freq]; break;
+        }
+        break;
+    case MPS_ICC:
+        hcod1D = ff_aac_hcod1D_ICC;
+        switch (lav) {
+        case 1: hcod2D = ff_aac_hcod2D_ICC_01[freq_pair][diff_freq]; break;
+        case 3: hcod2D = ff_aac_hcod2D_ICC_03[freq_pair][diff_freq]; break;
+        case 5: hcod2D = ff_aac_hcod2D_ICC_05[freq_pair][diff_freq]; break;
+        case 7: hcod2D = ff_aac_hcod2D_ICC_07[freq_pair][diff_freq]; break;
+        }
+        break;
+    case MPS_IPD:
+        hcod1D = ff_aac_hcod1D_IPD[diff_freq];
+        switch (lav) {
+        case 1: hcod2D = ff_aac_hcod2D_IPD_01[freq_pair][diff_freq]; break;
+        case 3: hcod2D = ff_aac_hcod2D_IPD_03[freq_pair][diff_freq]; break;
+        case 5: hcod2D = ff_aac_hcod2D_IPD_05[freq_pair][diff_freq]; break;
+        case 7: hcod2D = ff_aac_hcod2D_IPD_07[freq_pair][diff_freq]; break;
+        }
+        break;
+    }
+
+    if (part0_data[0])
+        part0_data[0][0] = -(huff_dec_1D(gb, hcod1D) + 1);
+    if (part0_data[1])
+        part0_data[1][0] = -(huff_dec_1D(gb, hcod1D) + 1);
+
+    int i = 0;
+    int esc_cnt = 0;
+    int16_t esc_data[2][28];
+    int esc_idx[28];
+    for (; i < data_bands; i += stride) {
+        if (huff_dec_2D(gb, hcod2D, data[i]))
+            esc_idx[esc_cnt++] = i; /* Escape */
+        else
+            symmetry_data(gb, data[i], lav, data_type);
+    }
+
+    if (esc_cnt) {
+        pcm_decode(gb, esc_data[0], esc_data[1],
+                   0, 2*esc_cnt, 0, (2*lav + 1));
+        for (i = 0; i < esc_cnt; i++) {
+            data[esc_idx[i]][0] = esc_data[0][i] - lav;
+            data[esc_idx[i]][0] = esc_data[0][i] - lav;
+        }
+    }
+}
+
+static int huff_decode(GetBitContext *gb, int16_t *data[2],
+                       enum MPSDataType data_type, int diff_freq[2],
+                       int num_val, int *time_pair, int ldMode)
+{
+    int16_t pair_vec[28][2];
+    int num_val_ch[2] = { num_val, num_val };
+    int16_t *p0_data[2][2] = { 0 };
+    int df_rest_flag[2] = { 0, 0 };
+
+    /* Coding scheme */
+    if (get_bits1(gb)) { /* 2D */
+        *time_pair = 0;
+        if (data[0] && data[1] && !ldMode)
+            *time_pair = get_bits1(gb);
+
+        if (time_pair) {
+            if (diff_freq[0] || diff_freq[1]) {
+                p0_data[0][0] = data[0];
+                p0_data[0][1] = data[1];
+
+                data[0] += 1;
+                data[1] += 1;
+
+                num_val_ch[0] -= 1;
+            }
+
+            int diff_mode = 1;
+            if (!diff_freq[0] || !diff_freq[1])
+                diff_mode = 0; // time
+
+            huff_data_2d(gb, p0_data[0], pair_vec, num_val_ch[0], 1, data_type,
+                         diff_mode, 0);
+
+            for (int i = 0; i < num_val_ch[0]; i++) {
+                data[0][i] = pair_vec[i][0];
+                data[1][i] = pair_vec[i][1];
+            }
+        } else {
+            if (data[0]) {
+                if (diff_freq[0]) {
+                    p0_data[0][0] = data[0];
+                    p0_data[0][1] = NULL;
+
+                    num_val_ch[0] -= 1;
+                    data[0]++;
+                }
+                df_rest_flag[0] = num_val_ch[0] % 2;
+                if (df_rest_flag[0])
+                    num_val_ch[0] -= 1;
+                if (num_val_ch[0] < 0)
+                    return AVERROR(EINVAL);
+            }
+
+            if (data[1]) {
+                if (diff_freq[1]) {
+                    p0_data[1][0] = NULL;
+                    p0_data[1][1] = data[1];
+
+                    num_val_ch[1] -= 1;
+                    data[1]++;
+                }
+                df_rest_flag[1] = num_val_ch[1] % 2;
+                if (df_rest_flag[1])
+                    num_val_ch[1] -= 1;
+                if (num_val_ch[1] < 0)
+                    return AVERROR(EINVAL);
+            }
+
+            if (data[0]) {
+                huff_data_2d(gb, p0_data[0], pair_vec, num_val_ch[0], 2, 
data_type,
+                             diff_freq[0], 1);
+                if (df_rest_flag[0])
+                    huff_data_1d(gb, data[0] + num_val_ch[0], 1,
+                                 data_type, diff_freq[0], 0);
+            }
+
+            if (data[1]) {
+                huff_data_2d(gb, p0_data[1], pair_vec + 1, num_val_ch[1], 2, 
data_type,
+                             diff_freq[1], 1);
+                if (df_rest_flag[1])
+                    huff_data_1d(gb, data[1] + num_val_ch[1], 1,
+                                 data_type, diff_freq[1], 0);
+            }
+        }
+    } else { /* 1D */
+        if (data[0])
+            huff_data_1d(gb, data[0], num_val, data_type, diff_freq[0], 
diff_freq[0]);
+        if (data[1])
+            huff_data_1d(gb, data[1], num_val, data_type, diff_freq[1], 
diff_freq[0]);
+    }
+
+    return 0;
+}
+
+static void diff_freq_decode(const int16_t *diff, int16_t *out, int nb_val)
+{
+    int i = 0;
+    out[0] = diff[0];
+    for (i = 1; i < nb_val; i++)
+        out[i] = out[i - 1] + diff[i];
+}
+
+static void diff_time_decode_backwards(const int16_t *prev, const int16_t 
*diff,
+                                       int16_t *out, const int mixed_diff_type,
+                                       const int nb_val)
+{
+    if (mixed_diff_type)
+        out[0] = diff[0];
+    for (int i = mixed_diff_type; i < nb_val; i++)
+        out[i] = prev[i] + diff[i];
+}
+
+static void diff_time_decode_forwards(const int16_t *prev, const int16_t *diff,
+                                      int16_t *out, const int mixed_diff_type,
+                                      const int nb_val)
+{
+    if (mixed_diff_type)
+        out[0] = diff[0];
+    for (int i = mixed_diff_type; i < nb_val; i++)
+        out[i] = prev[i] - diff[i];
+}
+
+static void attach_lsb(GetBitContext *gb, int16_t *data_msb,
+                       int offset, int nb_lsb, int nb_val,
+                       int16_t *data)
+{
+    for (int i = 0; i < nb_val; i++) {
+        int msb = data_msb[i];
+        if (nb_lsb > 0) {
+            uint32_t lsb = get_bits(gb, nb_lsb);
+            data[i] = ((msb << nb_lsb) | lsb) - offset;
+        } else {
+            data[i] = msb - offset;
+        }
+    }
+}
+
+int ff_aac_ec_pair_dec(GetBitContext *gb,
+                       int *data[2], int16_t *last,
+                       enum MPSDataType data_type, int start_band, int 
nb_bands,
+                       int pair, int coarse,
+                       int allowDiffTimeBack_flag)
+{
+    int attach_lsb_flag = 0;
+    int quant_levels = 0;
+    int quant_offset = 0;
+
+    switch (data_type) {
+    case MPS_CLD:
+        if (coarse) {
+            attach_lsb_flag = 0;
+            quant_levels = 15;
+            quant_offset = 7;
+      } else {
+            attach_lsb_flag = 0;
+            quant_levels = 31;
+            quant_offset = 15;
+        }
+        break;
+    case MPS_ICC:
+        if (coarse) {
+            attach_lsb_flag = 0;
+            quant_levels = 4;
+            quant_offset = 0;
+        } else {
+            attach_lsb_flag = 0;
+            quant_levels = 8;
+            quant_offset = 0;
+        }
+        break;
+    case MPS_IPD:
+        if (!coarse) {
+            attach_lsb_flag = 1;
+            quant_levels = 16;
+            quant_offset = 0;
+        } else {
+            attach_lsb_flag = 0;
+            quant_levels = 8;
+            quant_offset = 0;
+        }
+        break;
+    }
+
+    int16_t last_msb[28] = { 0 };
+    int16_t data_pair[2][28] = { 0 };
+    int16_t data_diff[2][28] = { 0 };
+    int16_t *p_data[2];
+    if (get_bits1(gb)) {
+        int nb_pcm_vals;
+        if (pair) {
+            p_data[0] = data_pair[0];
+            p_data[1] = data_pair[1];
+            nb_pcm_vals = 2 * nb_bands;
+        } else {
+            p_data[0] = data_pair[0];
+            p_data[1] = NULL;
+            nb_pcm_vals = nb_bands;
+        }
+
+        int nb_quant_steps;
+        switch (data_type) {
+        case MPS_CLD: nb_quant_steps = coarse ? 15 : 31; break;
+        case MPS_ICC: nb_quant_steps = coarse ?  4 :  8; break;
+        case MPS_IPD: nb_quant_steps = coarse ?  8 : 16; break;
+        }
+        pcm_decode(gb, p_data[0], p_data[1], quant_offset, nb_pcm_vals,
+                   nb_quant_steps, quant_levels);
+
+        memcpy(data + start_band, data_pair[0], 2*nb_bands);
+        if (pair)
+            memcpy(data + start_band, data_pair[1], 2*nb_bands);
+
+        return 0;
+    }
+
+    if (pair) {
+        p_data[0] = data_pair[0];
+        p_data[1] = data_pair[1];
+    } else {
+        p_data[0] = data_pair[0];
+        p_data[1] = NULL;
+    }
+
+    int diff_freq[2] = { 1, 1 };
+    int backwards = 1;
+
+    if (pair || allowDiffTimeBack_flag)
+        diff_freq[0] = !get_bits1(gb);
+
+    if (pair && (diff_freq[0] || allowDiffTimeBack_flag))
+        diff_freq[1] = !get_bits1(gb);
+
+    int time_pair;
+    huff_decode(gb, p_data, data_type, diff_freq,
+                nb_bands, &time_pair, 0 /* 1 if SAOC */);
+
+    /* Differential decoding */
+    if (!diff_freq[0] || !diff_freq[1]) {
+        if (0 /* 1 if SAOC */) {
+            backwards = 1;
+        } else {
+            if (pair) {
+            if (!diff_freq[0] && !allowDiffTimeBack_flag) {
+                backwards = 0;
+            } else if (!diff_freq[1]) {
+                backwards = 1;
+            } else {
+                backwards = !get_bits1(gb);
+            }
+            } else {
+                backwards = 1;
+            }
+        }
+    }
+
+    int mixed_time_pair = (diff_freq[0] != diff_freq[1]) && time_pair;
+
+    if (backwards) {
+        if (diff_freq[0]) {
+            diff_freq_decode(data_diff[0], data_pair[0], nb_bands);
+        } else {
+            for (int i = 0; i < nb_bands; i++) {
+                last_msb[i] = last[i + start_band] + quant_offset;
+                if (attach_lsb_flag) {
+                    last_msb[i] >>= 1;
+                }
+            }
+            diff_time_decode_backwards(last_msb, data_diff[0], data_pair[0],
+                                       mixed_time_pair, nb_bands);
+        }
+
+        if (diff_freq[1])
+            diff_freq_decode(data_diff[1], data_pair[1], nb_bands);
+        else
+            diff_time_decode_backwards(data_pair[0], data_diff[1],
+                                       data_pair[1], mixed_time_pair, 
nb_bands);
+    } else {
+        diff_freq_decode(data_diff[1], data_pair[1], nb_bands);
+
+        if (diff_freq[0])
+          diff_freq_decode(data_diff[0], data_pair[0], nb_bands);
+        else
+          diff_time_decode_forwards(data_pair[1], data_diff[0], data_pair[0],
+                                    mixed_time_pair, nb_bands);
+    }
+
+    /* Decode LSBs */
+    attach_lsb(gb, p_data[0], quant_offset, attach_lsb_flag,
+               nb_bands, p_data[0]);
+    if (pair)
+        attach_lsb(gb, p_data[1], quant_offset, attach_lsb_flag,
+                   nb_bands, p_data[1]);
+
+    memcpy(data + start_band, data_pair[0], 2*nb_bands);
+    if (pair)
+        memcpy(data + start_band, data_pair[1], 2*nb_bands);
+
+    return 0;
+}
+
+int ff_aac_huff_dec_reshape(GetBitContext *gb, int16_t *out_data,
+                            int nb_val)
+{
+    int val, len;
+    int val_received = 0;
+    int16_t rl_data[2] = { 0 };
+
+    while (val_received < nb_val) {
+        huff_dec_2D(gb, ff_aac_hcod2D_reshape, rl_data);
+        val = rl_data[0];
+        len = rl_data[1] + 1;
+        if (val_received + len > nb_val)
+            return AVERROR(EINVAL);
+        for (int i = val_received; i < val_received + len; i++)
+            out_data[i] = val;
+    }
+    val_received += len;
+
+    return 0;
+}
diff --git a/libavcodec/aac/aacdec_usac_mps212.h 
b/libavcodec/aac/aacdec_usac_mps212.h
new file mode 100644
index 0000000000..001cc49b82
--- /dev/null
+++ b/libavcodec/aac/aacdec_usac_mps212.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2025 Lynne <[email protected]>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_AAC_AACDEC_USAC_MPS212_H
+#define AVCODEC_AAC_AACDEC_USAC_MPS212_H
+
+#include "libavcodec/get_bits.h"
+
+enum MPSDataType {
+    MPS_CLD,
+    MPS_ICC,
+    MPS_IPD,
+};
+
+int ff_aac_ec_pair_dec(GetBitContext *gb,
+                       int *data[2], int16_t *last,
+                       enum MPSDataType data_type, int start_band, int 
nb_bands,
+                       int pair, int coarse,
+                       int allowDiffTimeBack_flag);
+
+int ff_aac_huff_dec_reshape(GetBitContext *gb, int16_t *out_data,
+                            int nb_val);
+
+#endif /* AVCODEC_AAC_AACDEC_USAC_MPS212_H */
-- 
2.49.1

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to