* [FFmpeg-devel] [PATCH v5 07/10] aactab: add tables for the new USAC arithmetic coder
2024-05-30 2:37 [FFmpeg-devel] [PATCH v5 00/10] aacdec: add a native xHE-AAC decoder Lynne via ffmpeg-devel
` (5 preceding siblings ...)
2024-05-30 2:37 ` [FFmpeg-devel] [PATCH v5 06/10] aactab: add deemphasis tables for USAC Lynne via ffmpeg-devel
@ 2024-05-30 2:37 ` Lynne via ffmpeg-devel
2024-05-30 2:37 ` [FFmpeg-devel] [PATCH v5 08/10] aactab: add new scalefactor offset tables for 96/768pt windows Lynne via ffmpeg-devel
` (4 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Lynne via ffmpeg-devel @ 2024-05-30 2:37 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Lynne
---
libavcodec/aactab.c | 376 ++++++++++++++++++++++++++++++++++++++++++++
libavcodec/aactab.h | 6 +
2 files changed, 382 insertions(+)
diff --git a/libavcodec/aactab.c b/libavcodec/aactab.c
index 8ce5e43974..dfb2dfd98d 100644
--- a/libavcodec/aactab.c
+++ b/libavcodec/aactab.c
@@ -1193,6 +1193,382 @@ const uint16_t *const ff_aac_codebook_vector_idx[] = {
codebook_vector10_idx,
};
+const uint16_t ff_aac_ac_msb_cdfs[64][17] = {
+ { 708, 706, 579, 569, 568, 567, 479, 469,
+ 297, 138, 97, 91, 72, 52, 38, 34, 0, },
+ { 7619, 6917, 6519, 6412, 5514, 5003, 4683, 4563,
+ 3907, 3297, 3125, 3060, 2904, 2718, 2631, 2590, 0, },
+ { 7263, 4888, 4810, 4803, 1889, 415, 335, 327,
+ 195, 72, 52, 49, 36, 20, 15, 14, 0, },
+ { 3626, 2197, 2188, 2187, 582, 57, 47, 46,
+ 30, 12, 9, 8, 6, 4, 3, 2, 0, },
+ { 7806, 5541, 5451, 5441, 2720, 834, 691, 674,
+ 487, 243, 179, 167, 139, 98, 77, 70, 0, },
+ { 6684, 4101, 4058, 4055, 1748, 426, 368, 364,
+ 322, 257, 235, 232, 228, 222, 217, 215, 0, },
+ { 9162, 5964, 5831, 5819, 3269, 866, 658, 638,
+ 535, 348, 258, 244, 234, 214, 195, 186, 0, },
+ { 10638, 8491, 8365, 8351, 4418, 2067, 1859, 1834,
+ 1190, 601, 495, 478, 356, 217, 174, 164, 0, },
+ { 13389, 10514, 10032, 9961, 7166, 3488, 2655, 2524,
+ 2015, 1140, 760, 672, 585, 426, 325, 283, 0, },
+ { 14861, 12788, 12115, 11952, 9987, 6657, 5323, 4984,
+ 4324, 3001, 2205, 1943, 1764, 1394, 1115, 978, 0, },
+ { 12876, 10004, 9661, 9610, 7107, 3435, 2711, 2595,
+ 2257, 1508, 1059, 952, 893, 753, 609, 538, 0, },
+ { 15125, 13591, 13049, 12874, 11192, 8543, 7406, 7023,
+ 6291, 4922, 4104, 3769, 3465, 2890, 2486, 2275, 0, },
+ { 14574, 13106, 12731, 12638, 10453, 7947, 7233, 7037,
+ 6031, 4618, 4081, 3906, 3465, 2802, 2476, 2349, 0, },
+ { 15070, 13179, 12517, 12351, 10742, 7657, 6200, 5825,
+ 5264, 3998, 3014, 2662, 2510, 2153, 1799, 1564, 0, },
+ { 15542, 14466, 14007, 13844, 12489, 10409, 9481, 9132,
+ 8305, 6940, 6193, 5867, 5458, 4743, 4291, 4047, 0, },
+ { 15165, 14384, 14084, 13934, 12911, 11485, 10844, 10513,
+ 10002, 8993, 8380, 8051, 7711, 7036, 6514, 6233, 0, },
+ { 15642, 14279, 13625, 13393, 12348, 9971, 8405, 7858,
+ 7335, 6119, 4918, 4376, 4185, 3719, 3231, 2860, 0, },
+ { 13408, 13407, 11471, 11218, 11217, 11216, 9473, 9216,
+ 6480, 3689, 2857, 2690, 2256, 1732, 1405, 1302, 0, },
+ { 16098, 15584, 15191, 14931, 14514, 13578, 12703, 12103,
+ 11830, 11172, 10475, 9867, 9695, 9281, 8825, 8389, 0, },
+ { 15844, 14873, 14277, 13996, 13230, 11535, 10205, 9543,
+ 9107, 8086, 7085, 6419, 6214, 5713, 5195, 4731, 0, },
+ { 16131, 15720, 15443, 15276, 14848, 13971, 13314, 12910,
+ 12591, 11874, 11225, 10788, 10573, 10077, 9585, 9209, 0, },
+ { 16331, 16330, 12283, 11435, 11434, 11433, 8725, 8049,
+ 6065, 4138, 3187, 2842, 2529, 2171, 1907, 1745, 0, },
+ { 16011, 15292, 14782, 14528, 14008, 12767, 11556, 10921,
+ 10591, 9759, 8813, 8043, 7855, 7383, 6863, 6282, 0, },
+ { 16380, 16379, 15159, 14610, 14609, 14608, 12859, 12111,
+ 11046, 9536, 8348, 7713, 7216, 6533, 5964, 5546, 0, },
+ { 16367, 16333, 16294, 16253, 16222, 16143, 16048, 15947,
+ 15915, 15832, 15731, 15619, 15589, 15512, 15416, 15310, 0, },
+ { 15967, 15319, 14937, 14753, 14010, 12638, 11787, 11360,
+ 10805, 9706, 8934, 8515, 8166, 7456, 6911, 6575, 0, },
+ { 4906, 3005, 2985, 2984, 875, 102, 83, 81,
+ 47, 17, 12, 11, 8, 5, 4, 3, 0, },
+ { 7217, 4346, 4269, 4264, 1924, 428, 340, 332,
+ 280, 203, 179, 175, 171, 164, 159, 157, 0, },
+ { 16010, 15415, 15032, 14805, 14228, 13043, 12168, 11634,
+ 11265, 10419, 9645, 9110, 8892, 8378, 7850, 7437, 0, },
+ { 8573, 5218, 5046, 5032, 2787, 771, 555, 533,
+ 443, 286, 218, 205, 197, 181, 168, 162, 0, },
+ { 11474, 8095, 7822, 7796, 4632, 1443, 1046, 1004,
+ 748, 351, 218, 194, 167, 121, 93, 83, 0, },
+ { 16152, 15764, 15463, 15264, 14925, 14189, 13536, 13070,
+ 12846, 12314, 11763, 11277, 11131, 10777, 10383, 10011, 0, },
+ { 14187, 11654, 11043, 10919, 8498, 4885, 3778, 3552,
+ 2947, 1835, 1283, 1134, 998, 749, 585, 514, 0, },
+ { 14162, 11527, 10759, 10557, 8601, 5417, 4105, 3753,
+ 3286, 2353, 1708, 1473, 1370, 1148, 959, 840, 0, },
+ { 16205, 15902, 15669, 15498, 15213, 14601, 14068, 13674,
+ 13463, 12970, 12471, 12061, 11916, 11564, 11183, 10841, 0, },
+ { 15043, 12972, 12092, 11792, 10265, 7446, 5934, 5379,
+ 4883, 3825, 3036, 2647, 2507, 2185, 1901, 1699, 0, },
+ { 15320, 13694, 12782, 12352, 11191, 8936, 7433, 6671,
+ 6255, 5366, 4622, 4158, 4020, 3712, 3420, 3198, 0, },
+ { 16255, 16020, 15768, 15600, 15416, 14963, 14440, 14006,
+ 13875, 13534, 13137, 12697, 12602, 12364, 12084, 11781, 0, },
+ { 15627, 14503, 13906, 13622, 12557, 10527, 9269, 8661,
+ 8117, 6933, 5994, 5474, 5222, 4664, 4166, 3841, 0, },
+ { 16366, 16365, 14547, 14160, 14159, 14158, 11969, 11473,
+ 8735, 6147, 4911, 4530, 3865, 3180, 2710, 2473, 0, },
+ { 16257, 16038, 15871, 15754, 15536, 15071, 14673, 14390,
+ 14230, 13842, 13452, 13136, 13021, 12745, 12434, 12154, 0, },
+ { 15855, 14971, 14338, 13939, 13239, 11782, 10585, 9805,
+ 9444, 8623, 7846, 7254, 7079, 6673, 6262, 5923, 0, },
+ { 9492, 6318, 6197, 6189, 3004, 652, 489, 477,
+ 333, 143, 96, 90, 78, 60, 50, 47, 0, },
+ { 16313, 16191, 16063, 15968, 15851, 15590, 15303, 15082,
+ 14968, 14704, 14427, 14177, 14095, 13899, 13674, 13457, 0, },
+ { 8485, 5473, 5389, 5383, 2411, 494, 386, 377,
+ 278, 150, 117, 112, 103, 89, 81, 78, 0, },
+ { 10497, 7154, 6959, 6943, 3788, 1004, 734, 709,
+ 517, 238, 152, 138, 120, 90, 72, 66, 0, },
+ { 16317, 16226, 16127, 16040, 15955, 15762, 15547, 15345,
+ 15277, 15111, 14922, 14723, 14671, 14546, 14396, 14239, 0, },
+ { 16382, 16381, 15858, 15540, 15539, 15538, 14704, 14168,
+ 13768, 13092, 12452, 11925, 11683, 11268, 10841, 10460, 0, },
+ { 5974, 3798, 3758, 3755, 1275, 205, 166, 162,
+ 95, 35, 26, 24, 18, 11, 8, 7, 0, },
+ { 3532, 2258, 2246, 2244, 731, 135, 118, 115,
+ 87, 45, 36, 34, 29, 21, 17, 16, 0, },
+ { 7466, 4882, 4821, 4811, 2476, 886, 788, 771,
+ 688, 531, 469, 457, 437, 400, 369, 361, 0, },
+ { 9580, 5772, 5291, 5216, 3444, 1496, 1025, 928,
+ 806, 578, 433, 384, 366, 331, 296, 273, 0, },
+ { 10692, 7730, 7543, 7521, 4679, 1746, 1391, 1346,
+ 1128, 692, 495, 458, 424, 353, 291, 268, 0, },
+ { 11040, 7132, 6549, 6452, 4377, 1875, 1253, 1130,
+ 958, 631, 431, 370, 346, 296, 253, 227, 0, },
+ { 12687, 9332, 8701, 8585, 6266, 3093, 2182, 2004,
+ 1683, 1072, 712, 608, 559, 458, 373, 323, 0, },
+ { 13429, 9853, 8860, 8584, 6806, 4039, 2862, 2478,
+ 2239, 1764, 1409, 1224, 1178, 1077, 979, 903, 0, },
+ { 14685, 12163, 11061, 10668, 9101, 6345, 4871, 4263,
+ 3908, 3200, 2668, 2368, 2285, 2106, 1942, 1819, 0, },
+ { 13295, 11302, 10999, 10945, 7947, 5036, 4490, 4385,
+ 3391, 2185, 1836, 1757, 1424, 998, 833, 785, 0, },
+ { 4992, 2993, 2972, 2970, 1269, 575, 552, 549,
+ 530, 505, 497, 495, 493, 489, 486, 485, 0, },
+ { 15419, 13862, 13104, 12819, 11429, 8753, 7220, 6651,
+ 6020, 4667, 3663, 3220, 2995, 2511, 2107, 1871, 0, },
+ { 12468, 9263, 8912, 8873, 5758, 2193, 1625, 1556,
+ 1187, 589, 371, 330, 283, 200, 149, 131, 0, },
+ { 15870, 15076, 14615, 14369, 13586, 12034, 10990, 10423,
+ 9953, 8908, 8031, 7488, 7233, 6648, 6101, 5712, 0, },
+ { 1693, 978, 976, 975, 194, 18, 16, 15,
+ 11, 7, 6, 5, 4, 3, 2, 1, 0, },
+ { 7992, 5218, 5147, 5143, 2152, 366, 282, 276,
+ 173, 59, 38, 35, 27, 16, 11, 10, 0, }
+};
+
+const uint16_t ff_aac_ac_lsb_cdfs[3][4] = {
+ { 12571, 10569, 3696, 0 },
+ { 12661, 5700, 3751, 0 },
+ { 10827, 6884, 2929, 0 }
+};
+
+const uint8_t ff_aac_ac_lookup_m[742] = {
+ 0x01, 0x34, 0x0D, 0x13, 0x12, 0x25, 0x00, 0x3A, 0x05, 0x00, 0x21, 0x13, 0x1F, 0x1A, 0x1D, 0x36,
+ 0x24, 0x2B, 0x1B, 0x33, 0x37, 0x29, 0x1D, 0x33, 0x37, 0x33, 0x37, 0x33, 0x37, 0x33, 0x2C, 0x00,
+ 0x21, 0x13, 0x25, 0x2A, 0x00, 0x21, 0x24, 0x12, 0x2C, 0x1E, 0x37, 0x24, 0x1F, 0x35, 0x37, 0x24,
+ 0x35, 0x37, 0x35, 0x37, 0x38, 0x2D, 0x21, 0x29, 0x1E, 0x21, 0x13, 0x2D, 0x36, 0x38, 0x29, 0x36,
+ 0x37, 0x24, 0x36, 0x38, 0x37, 0x38, 0x00, 0x20, 0x23, 0x20, 0x23, 0x36, 0x38, 0x24, 0x3B, 0x24,
+ 0x26, 0x29, 0x1F, 0x30, 0x2D, 0x0D, 0x12, 0x3F, 0x2D, 0x21, 0x1C, 0x2A, 0x00, 0x21, 0x12, 0x1E,
+ 0x36, 0x38, 0x36, 0x37, 0x3F, 0x1E, 0x0D, 0x1F, 0x2A, 0x1E, 0x21, 0x24, 0x12, 0x2A, 0x3C, 0x21,
+ 0x24, 0x1F, 0x3C, 0x21, 0x29, 0x36, 0x38, 0x36, 0x37, 0x38, 0x21, 0x1E, 0x00, 0x3B, 0x25, 0x1E,
+ 0x20, 0x10, 0x1F, 0x3C, 0x20, 0x23, 0x29, 0x08, 0x23, 0x12, 0x08, 0x23, 0x21, 0x38, 0x00, 0x20,
+ 0x13, 0x20, 0x3B, 0x1C, 0x20, 0x3B, 0x29, 0x20, 0x23, 0x24, 0x21, 0x24, 0x21, 0x24, 0x3B, 0x13,
+ 0x23, 0x26, 0x23, 0x13, 0x21, 0x24, 0x26, 0x29, 0x12, 0x22, 0x2B, 0x02, 0x1E, 0x0D, 0x1F, 0x2D,
+ 0x00, 0x0D, 0x12, 0x00, 0x3C, 0x21, 0x29, 0x3C, 0x21, 0x2A, 0x3C, 0x3B, 0x22, 0x1E, 0x20, 0x10,
+ 0x1F, 0x3C, 0x0D, 0x29, 0x3C, 0x21, 0x24, 0x08, 0x23, 0x20, 0x38, 0x39, 0x3C, 0x20, 0x13, 0x3C,
+ 0x00, 0x0D, 0x13, 0x1F, 0x3C, 0x09, 0x26, 0x1F, 0x08, 0x09, 0x26, 0x12, 0x08, 0x23, 0x29, 0x20,
+ 0x23, 0x21, 0x24, 0x20, 0x13, 0x20, 0x3B, 0x16, 0x20, 0x3B, 0x29, 0x20, 0x3B, 0x29, 0x20, 0x3B,
+ 0x13, 0x21, 0x24, 0x29, 0x0B, 0x13, 0x09, 0x3B, 0x13, 0x09, 0x3B, 0x13, 0x21, 0x3B, 0x13, 0x0D,
+ 0x26, 0x29, 0x26, 0x29, 0x3D, 0x12, 0x22, 0x28, 0x2E, 0x04, 0x08, 0x13, 0x3C, 0x3B, 0x3C, 0x20,
+ 0x10, 0x3C, 0x21, 0x07, 0x08, 0x10, 0x00, 0x08, 0x0D, 0x29, 0x08, 0x0D, 0x29, 0x08, 0x09, 0x13,
+ 0x20, 0x23, 0x39, 0x08, 0x09, 0x13, 0x08, 0x09, 0x16, 0x08, 0x09, 0x10, 0x12, 0x20, 0x3B, 0x3D,
+ 0x09, 0x26, 0x20, 0x3B, 0x24, 0x39, 0x09, 0x26, 0x20, 0x0D, 0x13, 0x00, 0x09, 0x13, 0x20, 0x0D,
+ 0x26, 0x12, 0x20, 0x3B, 0x13, 0x21, 0x26, 0x0B, 0x12, 0x09, 0x3B, 0x16, 0x09, 0x3B, 0x3D, 0x09,
+ 0x26, 0x0D, 0x13, 0x26, 0x3D, 0x1C, 0x12, 0x1F, 0x28, 0x2E, 0x07, 0x0B, 0x08, 0x09, 0x00, 0x39,
+ 0x0B, 0x08, 0x26, 0x08, 0x09, 0x13, 0x20, 0x0B, 0x39, 0x10, 0x39, 0x0D, 0x13, 0x20, 0x10, 0x12,
+ 0x09, 0x13, 0x20, 0x3B, 0x13, 0x09, 0x26, 0x0B, 0x09, 0x3B, 0x1C, 0x09, 0x3B, 0x13, 0x20, 0x3B,
+ 0x13, 0x09, 0x26, 0x0B, 0x16, 0x0D, 0x13, 0x09, 0x13, 0x09, 0x13, 0x26, 0x3D, 0x1C, 0x1F, 0x28,
+ 0x2E, 0x07, 0x10, 0x39, 0x0B, 0x39, 0x39, 0x13, 0x39, 0x0B, 0x39, 0x0B, 0x39, 0x26, 0x39, 0x10,
+ 0x20, 0x3B, 0x16, 0x20, 0x10, 0x09, 0x26, 0x0B, 0x13, 0x09, 0x13, 0x26, 0x1C, 0x0B, 0x3D, 0x1C,
+ 0x1F, 0x28, 0x2B, 0x07, 0x0C, 0x39, 0x0B, 0x39, 0x0B, 0x0C, 0x0B, 0x26, 0x0B, 0x26, 0x3D, 0x0D,
+ 0x1C, 0x14, 0x28, 0x2B, 0x39, 0x0B, 0x0C, 0x0E, 0x3D, 0x1C, 0x0D, 0x12, 0x22, 0x2B, 0x07, 0x0C,
+ 0x0E, 0x3D, 0x1C, 0x10, 0x1F, 0x2B, 0x0C, 0x0E, 0x19, 0x14, 0x10, 0x1F, 0x28, 0x0C, 0x0E, 0x19,
+ 0x14, 0x26, 0x22, 0x2B, 0x0C, 0x0E, 0x19, 0x14, 0x26, 0x28, 0x0E, 0x19, 0x14, 0x26, 0x28, 0x0E,
+ 0x19, 0x14, 0x28, 0x0E, 0x19, 0x14, 0x22, 0x28, 0x2B, 0x0E, 0x14, 0x2B, 0x31, 0x00, 0x3A, 0x3A,
+ 0x05, 0x05, 0x1B, 0x1D, 0x33, 0x06, 0x35, 0x35, 0x20, 0x21, 0x37, 0x21, 0x24, 0x05, 0x1B, 0x2C,
+ 0x2C, 0x2C, 0x06, 0x34, 0x1E, 0x34, 0x00, 0x08, 0x36, 0x09, 0x21, 0x26, 0x1C, 0x2C, 0x00, 0x02,
+ 0x02, 0x02, 0x3F, 0x04, 0x04, 0x04, 0x34, 0x39, 0x20, 0x0A, 0x0C, 0x39, 0x0B, 0x0F, 0x07, 0x07,
+ 0x07, 0x07, 0x34, 0x39, 0x39, 0x0A, 0x0C, 0x39, 0x0C, 0x0F, 0x07, 0x07, 0x07, 0x00, 0x39, 0x39,
+ 0x0C, 0x0F, 0x07, 0x07, 0x39, 0x0C, 0x0F, 0x07, 0x39, 0x0C, 0x0F, 0x39, 0x39, 0x0C, 0x0F, 0x39,
+ 0x0C, 0x39, 0x0C, 0x0F, 0x00, 0x11, 0x27, 0x17, 0x2F, 0x27, 0x00, 0x27, 0x17, 0x00, 0x11, 0x17,
+ 0x00, 0x11, 0x17, 0x11, 0x00, 0x27, 0x15, 0x11, 0x17, 0x01, 0x15, 0x11, 0x15, 0x11, 0x15, 0x15,
+ 0x17, 0x00, 0x27, 0x01, 0x27, 0x27, 0x15, 0x00, 0x27, 0x11, 0x27, 0x15, 0x15, 0x15, 0x27, 0x15,
+ 0x15, 0x15, 0x15, 0x17, 0x2F, 0x11, 0x17, 0x27, 0x27, 0x27, 0x11, 0x27, 0x15, 0x27, 0x27, 0x15,
+ 0x15, 0x27, 0x17, 0x2F, 0x27, 0x17, 0x2F, 0x27, 0x17, 0x2F, 0x27, 0x17, 0x2F, 0x27, 0x17, 0x2F,
+ 0x27, 0x17, 0x2F, 0x27, 0x17, 0x2F, 0x27, 0x17, 0x2F, 0x27, 0x17, 0x2F, 0x27, 0x17, 0x2F, 0x27,
+ 0x17, 0x2F, 0x27, 0x17, 0x2F, 0x27, 0x17, 0x2F, 0x17, 0x2F, 0x2B, 0x00, 0x27, 0x00, 0x00, 0x11,
+ 0x15, 0x00, 0x11, 0x11, 0x27, 0x27, 0x15, 0x17, 0x15, 0x17, 0x15, 0x17, 0x27, 0x17, 0x27, 0x17,
+ 0x27, 0x17, 0x27, 0x17, 0x27, 0x17, 0x27, 0x17, 0x27, 0x17, 0x27, 0x17, 0x27, 0x17, 0x27, 0x17,
+ 0x27, 0x15, 0x27, 0x27, 0x15, 0x27
+};
+
+const uint32_t ff_aac_ac_hash_m[742] = {
+ 0x00000104, 0x0000030A, 0x00000510, 0x00000716,
+ 0x00000A1F, 0x00000F2E, 0x00011100, 0x00111103,
+ 0x00111306, 0x00111436, 0x00111623, 0x00111929,
+ 0x00111F2E, 0x0011221B, 0x00112435, 0x00112621,
+ 0x00112D12, 0x00113130, 0x0011331D, 0x00113535,
+ 0x00113938, 0x0011411B, 0x00114433, 0x00114635,
+ 0x00114F29, 0x00116635, 0x00116F24, 0x00117433,
+ 0x0011FF0F, 0x00121102, 0x0012132D, 0x00121436,
+ 0x00121623, 0x00121912, 0x0012213F, 0x0012232D,
+ 0x00122436, 0x00122638, 0x00122A29, 0x00122F2B,
+ 0x0012322D, 0x00123436, 0x00123738, 0x00123B29,
+ 0x0012411D, 0x00124536, 0x00124938, 0x00124F12,
+ 0x00125535, 0x00125F29, 0x00126535, 0x0012B837,
+ 0x0013112A, 0x0013131E, 0x0013163B, 0x0013212D,
+ 0x0013233C, 0x00132623, 0x00132F2E, 0x0013321E,
+ 0x00133521, 0x00133824, 0x0013411E, 0x00134336,
+ 0x00134838, 0x00135135, 0x00135537, 0x00135F12,
+ 0x00137637, 0x0013FF29, 0x00140024, 0x00142321,
+ 0x00143136, 0x00143321, 0x00143F25, 0x00144321,
+ 0x00148638, 0x0014FF29, 0x00154323, 0x0015FF12,
+ 0x0016F20C, 0x0018A529, 0x00210031, 0x0021122C,
+ 0x00211408, 0x00211713, 0x00211F2E, 0x0021222A,
+ 0x00212408, 0x00212710, 0x00212F2E, 0x0021331E,
+ 0x00213436, 0x00213824, 0x0021412D, 0x0021431E,
+ 0x00214536, 0x00214F1F, 0x00216637, 0x00220004,
+ 0x0022122A, 0x00221420, 0x00221829, 0x00221F2E,
+ 0x0022222D, 0x00222408, 0x00222623, 0x00222929,
+ 0x00222F2B, 0x0022321E, 0x00223408, 0x00223724,
+ 0x00223A29, 0x0022411E, 0x00224436, 0x00224823,
+ 0x00225134, 0x00225621, 0x00225F12, 0x00226336,
+ 0x00227637, 0x0022FF29, 0x0023112D, 0x0023133C,
+ 0x00231420, 0x00231916, 0x0023212D, 0x0023233C,
+ 0x00232509, 0x00232929, 0x0023312D, 0x00233308,
+ 0x00233509, 0x00233724, 0x0023413C, 0x00234421,
+ 0x00234A13, 0x0023513C, 0x00235421, 0x00235F1F,
+ 0x00236421, 0x0023FF29, 0x00240024, 0x0024153B,
+ 0x00242108, 0x00242409, 0x00242726, 0x00243108,
+ 0x00243409, 0x00243610, 0x00244136, 0x00244321,
+ 0x00244523, 0x00244F1F, 0x00245423, 0x0024610A,
+ 0x00246423, 0x0024FF29, 0x00252510, 0x00253121,
+ 0x0025343B, 0x00254121, 0x00254510, 0x00254F25,
+ 0x00255221, 0x0025FF12, 0x00266513, 0x0027F529,
+ 0x0029F101, 0x002CF224, 0x00310030, 0x0031122A,
+ 0x00311420, 0x00311816, 0x0031212C, 0x0031231E,
+ 0x00312408, 0x00312710, 0x0031312A, 0x0031321E,
+ 0x00313408, 0x00313623, 0x0031411E, 0x0031433C,
+ 0x00320007, 0x0032122D, 0x00321420, 0x00321816,
+ 0x0032212D, 0x0032233C, 0x00322509, 0x00322916,
+ 0x0032312D, 0x00323420, 0x00323710, 0x00323F2B,
+ 0x00324308, 0x00324623, 0x00324F25, 0x00325421,
+ 0x00325F1F, 0x00326421, 0x0032FF29, 0x00331107,
+ 0x00331308, 0x0033150D, 0x0033211E, 0x00332308,
+ 0x00332420, 0x00332610, 0x00332929, 0x0033311E,
+ 0x00333308, 0x0033363B, 0x00333A29, 0x0033413C,
+ 0x00334320, 0x0033463B, 0x00334A29, 0x0033510A,
+ 0x00335320, 0x00335824, 0x0033610A, 0x00336321,
+ 0x00336F12, 0x00337623, 0x00341139, 0x0034153B,
+ 0x00342108, 0x00342409, 0x00342610, 0x00343108,
+ 0x00343409, 0x00343610, 0x00344108, 0x0034440D,
+ 0x00344610, 0x0034510A, 0x00345309, 0x0034553B,
+ 0x0034610A, 0x00346309, 0x0034F824, 0x00350029,
+ 0x00352510, 0x00353120, 0x0035330D, 0x00353510,
+ 0x00354120, 0x0035430D, 0x00354510, 0x00354F28,
+ 0x0035530D, 0x00355510, 0x00355F1F, 0x00356410,
+ 0x00359626, 0x0035FF12, 0x00366426, 0x0036FF12,
+ 0x0037F426, 0x0039D712, 0x003BF612, 0x003DF81F,
+ 0x00410004, 0x00411207, 0x0041150D, 0x0041212A,
+ 0x00412420, 0x0041311E, 0x00413308, 0x00413509,
+ 0x00413F2B, 0x00414208, 0x00420007, 0x0042123C,
+ 0x00421409, 0x00422107, 0x0042223C, 0x00422409,
+ 0x00422610, 0x0042313C, 0x00423409, 0x0042363B,
+ 0x0042413C, 0x00424320, 0x0042463B, 0x00425108,
+ 0x00425409, 0x0042FF29, 0x00431107, 0x00431320,
+ 0x0043153B, 0x0043213C, 0x00432320, 0x00432610,
+ 0x0043313C, 0x00433320, 0x0043353B, 0x00433813,
+ 0x00434108, 0x00434409, 0x00434610, 0x00435108,
+ 0x0043553B, 0x00435F25, 0x00436309, 0x0043753B,
+ 0x0043FF29, 0x00441239, 0x0044143B, 0x00442139,
+ 0x00442309, 0x0044253B, 0x00443108, 0x00443220,
+ 0x0044353B, 0x0044410A, 0x00444309, 0x0044453B,
+ 0x00444813, 0x0044510A, 0x00445309, 0x00445510,
+ 0x00445F25, 0x0044630D, 0x00450026, 0x00452713,
+ 0x00453120, 0x0045330D, 0x00453510, 0x00454120,
+ 0x0045430D, 0x00454510, 0x00455120, 0x0045530D,
+ 0x00456209, 0x00456410, 0x0045FF12, 0x00466513,
+ 0x0047FF22, 0x0048FF25, 0x0049F43D, 0x004BFB25,
+ 0x004EF825, 0x004FFF18, 0x00511339, 0x00512107,
+ 0x00513409, 0x00520007, 0x00521107, 0x00521320,
+ 0x00522107, 0x00522409, 0x0052313C, 0x00523320,
+ 0x0052353B, 0x00524108, 0x00524320, 0x00531139,
+ 0x00531309, 0x00532139, 0x00532309, 0x0053253B,
+ 0x00533108, 0x0053340D, 0x00533713, 0x00534108,
+ 0x0053453B, 0x00534F2B, 0x00535309, 0x00535610,
+ 0x00535F25, 0x0053643B, 0x00541139, 0x00542139,
+ 0x00542309, 0x00542613, 0x00543139, 0x00543309,
+ 0x00543510, 0x00543F2B, 0x00544309, 0x00544510,
+ 0x00544F28, 0x0054530D, 0x0054FF12, 0x00553613,
+ 0x00553F2B, 0x00554410, 0x0055510A, 0x0055543B,
+ 0x00555F25, 0x0055633B, 0x0055FF12, 0x00566513,
+ 0x00577413, 0x0059FF28, 0x005CC33D, 0x005EFB28,
+ 0x005FFF18, 0x00611339, 0x00612107, 0x00613320,
+ 0x0061A724, 0x00621107, 0x0062140B, 0x00622107,
+ 0x00622320, 0x00623139, 0x00623320, 0x00631139,
+ 0x0063130C, 0x00632139, 0x00632309, 0x00633139,
+ 0x00633309, 0x00633626, 0x00633F2B, 0x00634309,
+ 0x00634F2B, 0x0063543B, 0x0063FF12, 0x0064343B,
+ 0x00643F2B, 0x0064443B, 0x00645209, 0x00665513,
+ 0x0066610A, 0x00666526, 0x0067A616, 0x0069843D,
+ 0x006CF612, 0x006EF326, 0x006FFF18, 0x0071130C,
+ 0x00721107, 0x00722239, 0x0072291C, 0x0072340B,
+ 0x00731139, 0x00732239, 0x0073630B, 0x0073FF12,
+ 0x0074430B, 0x00755426, 0x00776F28, 0x00777410,
+ 0x0078843D, 0x007CF416, 0x007EF326, 0x007FFF18,
+ 0x00822239, 0x00831139, 0x0083430B, 0x0084530B,
+ 0x0087561C, 0x00887F25, 0x00888426, 0x008AF61C,
+ 0x008F0018, 0x008FFF18, 0x00911107, 0x0093230B,
+ 0x0094530B, 0x0097743D, 0x00998C25, 0x00999616,
+ 0x009EF825, 0x009FFF18, 0x00A3430B, 0x00A4530B,
+ 0x00A7743D, 0x00AA9F2B, 0x00AAA616, 0x00ABD61F,
+ 0x00AFFF18, 0x00B3330B, 0x00B44426, 0x00B7643D,
+ 0x00BB971F, 0x00BBB53D, 0x00BEF512, 0x00BFFF18,
+ 0x00C22139, 0x00C5330E, 0x00C7633D, 0x00CCAF2E,
+ 0x00CCC616, 0x00CFFF18, 0x00D4440E, 0x00D6420E,
+ 0x00DDCF2E, 0x00DDD516, 0x00DFFF18, 0x00E4330E,
+ 0x00E6841C, 0x00EEE61C, 0x00EFFF18, 0x00F3320E,
+ 0x00F55319, 0x00F8F41C, 0x00FAFF2E, 0x00FF002E,
+ 0x00FFF10C, 0x00FFF33D, 0x00FFF722, 0x00FFFF18,
+ 0x01000232, 0x0111113E, 0x01112103, 0x0111311A,
+ 0x0112111A, 0x01122130, 0x01123130, 0x0112411D,
+ 0x01131102, 0x01132102, 0x01133102, 0x01141108,
+ 0x01142136, 0x01143136, 0x01144135, 0x0115223B,
+ 0x01211103, 0x0121211A, 0x01213130, 0x01221130,
+ 0x01222130, 0x01223102, 0x01231104, 0x01232104,
+ 0x01233104, 0x01241139, 0x01241220, 0x01242220,
+ 0x01251109, 0x0125223B, 0x0125810A, 0x01283212,
+ 0x0131111A, 0x01312130, 0x0131222C, 0x0131322A,
+ 0x0132122A, 0x0132222D, 0x0132322D, 0x01331207,
+ 0x01332234, 0x01333234, 0x01341139, 0x01343134,
+ 0x01344134, 0x01348134, 0x0135220B, 0x0136110B,
+ 0x01365224, 0x01411102, 0x01412104, 0x01431239,
+ 0x01432239, 0x0143320A, 0x01435134, 0x01443107,
+ 0x01444134, 0x01446134, 0x0145220E, 0x01455134,
+ 0x0147110E, 0x01511102, 0x01521239, 0x01531239,
+ 0x01532239, 0x01533107, 0x0155220E, 0x01555134,
+ 0x0157110E, 0x01611107, 0x01621239, 0x01631239,
+ 0x01661139, 0x01666134, 0x01711107, 0x01721239,
+ 0x01745107, 0x0177110C, 0x01811107, 0x01821107,
+ 0x0185110C, 0x0188210C, 0x01911107, 0x01933139,
+ 0x01A11107, 0x01A31139, 0x01F5220E, 0x02000001,
+ 0x02000127, 0x02000427, 0x02000727, 0x02000E2F,
+ 0x02110000, 0x02111200, 0x02111411, 0x02111827,
+ 0x02111F2F, 0x02112411, 0x02112715, 0x02113200,
+ 0x02113411, 0x02113715, 0x02114200, 0x02121200,
+ 0x02121301, 0x02121F2F, 0x02122200, 0x02122615,
+ 0x02122F2F, 0x02123311, 0x02123F2F, 0x02124411,
+ 0x02131211, 0x02132311, 0x02133211, 0x02184415,
+ 0x02211200, 0x02211311, 0x02211F2F, 0x02212311,
+ 0x02212F2F, 0x02213211, 0x02221201, 0x02221311,
+ 0x02221F2F, 0x02222311, 0x02222F2F, 0x02223211,
+ 0x02223F2F, 0x02231211, 0x02232211, 0x02232F2F,
+ 0x02233211, 0x02233F2F, 0x02287515, 0x022DAB17,
+ 0x02311211, 0x02311527, 0x02312211, 0x02321211,
+ 0x02322211, 0x02322F2F, 0x02323311, 0x02323F2F,
+ 0x02331211, 0x02332211, 0x02332F2F, 0x02333F2F,
+ 0x0237FF17, 0x02385615, 0x023D9517, 0x02410027,
+ 0x02487827, 0x024E3117, 0x024FFF2F, 0x02598627,
+ 0x025DFF2F, 0x025FFF2F, 0x02687827, 0x026DFA17,
+ 0x026FFF2F, 0x02796427, 0x027E4217, 0x027FFF2F,
+ 0x02888727, 0x028EFF2F, 0x028FFF2F, 0x02984327,
+ 0x029F112F, 0x029FFF2F, 0x02A76527, 0x02AEF717,
+ 0x02AFFF2F, 0x02B7C827, 0x02BEF917, 0x02BFFF2F,
+ 0x02C66527, 0x02CD5517, 0x02CFFF2F, 0x02D63227,
+ 0x02DDD527, 0x02DFFF2B, 0x02E84717, 0x02EEE327,
+ 0x02EFFF2F, 0x02F54527, 0x02FCF817, 0x02FFEF2B,
+ 0x02FFFA2F, 0x02FFFE2F, 0x03000127, 0x03000201,
+ 0x03111200, 0x03122115, 0x03123200, 0x03133211,
+ 0x03211200, 0x03213127, 0x03221200, 0x03345215,
+ 0x04000F17, 0x04122F17, 0x043F6515, 0x043FFF17,
+ 0x044F5527, 0x044FFF17, 0x045F0017, 0x045FFF17,
+ 0x046F6517, 0x04710027, 0x047F4427, 0x04810027,
+ 0x048EFA15, 0x048FFF2F, 0x049F4427, 0x049FFF2F,
+ 0x04AEA727, 0x04AFFF2F, 0x04BE9C15, 0x04BFFF2F,
+ 0x04CE5427, 0x04CFFF2F, 0x04DE3527, 0x04DFFF17,
+ 0x04EE4627, 0x04EFFF17, 0x04FEF327, 0x04FFFF2F,
+ 0x06000F27, 0x069FFF17, 0x06FFFF17, 0x08110017,
+ 0x08EFFF15, 0xFFFFFF00
+};
+
/* @name swb_offsets
* Sample offset into the window indicating the beginning of a scalefactor
* window band
diff --git a/libavcodec/aactab.h b/libavcodec/aactab.h
index 91262380d4..9d584ebbe5 100644
--- a/libavcodec/aactab.h
+++ b/libavcodec/aactab.h
@@ -93,6 +93,12 @@ extern const float *const ff_aac_codebook_vectors[];
extern const float *const ff_aac_codebook_vector_vals[];
extern const uint16_t *const ff_aac_codebook_vector_idx[];
+extern const uint16_t ff_aac_ac_msb_cdfs[64][17];
+extern const uint16_t ff_aac_ac_lsb_cdfs[3][4];
+extern const uint8_t ff_aac_ac_lookup_m[742];
+extern const uint32_t ff_aac_ac_hash_m[742];
+extern const uint16_t ff_aac_ac_cf_m[64][17];
+
extern const uint16_t * const ff_swb_offset_1024[13];
extern const uint16_t * const ff_swb_offset_960 [13];
extern const uint16_t * const ff_swb_offset_512 [13];
--
2.43.0.381.gb435a96ce8
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 16+ messages in thread
* [FFmpeg-devel] [PATCH v5 09/10] aacdec: add a decoder for AAC USAC (xHE-AAC)
2024-05-30 2:37 [FFmpeg-devel] [PATCH v5 00/10] aacdec: add a native xHE-AAC decoder Lynne via ffmpeg-devel
` (7 preceding siblings ...)
2024-05-30 2:37 ` [FFmpeg-devel] [PATCH v5 08/10] aactab: add new scalefactor offset tables for 96/768pt windows Lynne via ffmpeg-devel
@ 2024-05-30 2:37 ` Lynne via ffmpeg-devel
2024-05-30 2:40 ` [FFmpeg-devel] [PATCH v5 10/10] fate: add tests for xHE-AAC Lynne via ffmpeg-devel
` (2 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Lynne via ffmpeg-devel @ 2024-05-30 2:37 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Lynne
This commit adds a decoder for the frequency-domain part of USAC.
What works:
- Mono
- Stereo (no prediction)
- Stereo (mid/side coding)
- Stereo (complex prediction)
What's left:
- Speech coding
Known issues:
- Desync with certain sequences
- Preroll crossover missing (shouldn't matter, bitrate adaptation only)
---
libavcodec/aac/Makefile | 3 +-
libavcodec/aac/aacdec.c | 188 +--
libavcodec/aac/aacdec.h | 187 +++
libavcodec/aac/aacdec_ac.c | 208 ++++
libavcodec/aac/aacdec_ac.h | 54 +
libavcodec/aac/aacdec_dsp_template.c | 4 +-
libavcodec/aac/aacdec_latm.h | 14 +-
libavcodec/aac/aacdec_lpd.c | 198 ++++
libavcodec/aac/aacdec_lpd.h | 33 +
libavcodec/aac/aacdec_usac.c | 1608 ++++++++++++++++++++++++++
libavcodec/aac/aacdec_usac.h | 37 +
libavcodec/aactab.c | 42 +
libavcodec/aactab.h | 10 +
13 files changed, 2510 insertions(+), 76 deletions(-)
create mode 100644 libavcodec/aac/aacdec_ac.c
create mode 100644 libavcodec/aac/aacdec_ac.h
create mode 100644 libavcodec/aac/aacdec_lpd.c
create mode 100644 libavcodec/aac/aacdec_lpd.h
create mode 100644 libavcodec/aac/aacdec_usac.c
create mode 100644 libavcodec/aac/aacdec_usac.h
diff --git a/libavcodec/aac/Makefile b/libavcodec/aac/Makefile
index c3e525d373..70b1dca274 100644
--- a/libavcodec/aac/Makefile
+++ b/libavcodec/aac/Makefile
@@ -2,6 +2,7 @@ clean::
$(RM) $(CLEANSUFFIXES:%=libavcodec/aac/%)
OBJS-$(CONFIG_AAC_DECODER) += aac/aacdec.o aac/aacdec_tab.o \
- aac/aacdec_float.o
+ aac/aacdec_float.o aac/aacdec_usac.o \
+ aac/aacdec_ac.o aac/aacdec_lpd.o
OBJS-$(CONFIG_AAC_FIXED_DECODER) += aac/aacdec.o aac/aacdec_tab.o \
aac/aacdec_fixed.o
diff --git a/libavcodec/aac/aacdec.c b/libavcodec/aac/aacdec.c
index 6f37ac5361..2b8322fc68 100644
--- a/libavcodec/aac/aacdec.c
+++ b/libavcodec/aac/aacdec.c
@@ -40,6 +40,7 @@
#include "aacdec.h"
#include "aacdec_tab.h"
+#include "aacdec_usac.h"
#include "libavcodec/aac.h"
#include "libavcodec/aac_defines.h"
@@ -535,6 +536,8 @@ static av_cold void flush(AVCodecContext *avctx)
}
}
}
+
+ ff_aac_usac_reset_state(ac, &ac->oc[1]);
}
/**
@@ -993,13 +996,14 @@ static int decode_eld_specific_config(AACDecContext *ac, AVCodecContext *avctx,
*/
static int decode_audio_specific_config_gb(AACDecContext *ac,
AVCodecContext *avctx,
- MPEG4AudioConfig *m4ac,
+ OutputConfiguration *oc,
GetBitContext *gb,
int get_bit_alignment,
int sync_extension)
{
int i, ret;
GetBitContext gbc = *gb;
+ MPEG4AudioConfig *m4ac = &oc->m4ac;
MPEG4AudioConfig m4ac_bak = *m4ac;
if ((i = ff_mpeg4audio_get_config_gb(m4ac, &gbc, sync_extension, avctx)) < 0) {
@@ -1033,14 +1037,22 @@ static int decode_audio_specific_config_gb(AACDecContext *ac,
case AOT_ER_AAC_LC:
case AOT_ER_AAC_LD:
if ((ret = decode_ga_specific_config(ac, avctx, gb, get_bit_alignment,
- m4ac, m4ac->chan_config)) < 0)
+ &oc->m4ac, m4ac->chan_config)) < 0)
return ret;
break;
case AOT_ER_AAC_ELD:
if ((ret = decode_eld_specific_config(ac, avctx, gb,
- m4ac, m4ac->chan_config)) < 0)
+ &oc->m4ac, m4ac->chan_config)) < 0)
+ return ret;
+ break;
+#if CONFIG_AAC_DECODER
+ case AOT_USAC_NOSBR: /* fallthrough */
+ case AOT_USAC:
+ if ((ret = ff_aac_usac_config_decode(ac, avctx, gb,
+ oc, m4ac->chan_config)) < 0)
return ret;
break;
+#endif
default:
avpriv_report_missing_feature(avctx,
"Audio object type %s%d",
@@ -1060,7 +1072,7 @@ static int decode_audio_specific_config_gb(AACDecContext *ac,
static int decode_audio_specific_config(AACDecContext *ac,
AVCodecContext *avctx,
- MPEG4AudioConfig *m4ac,
+ OutputConfiguration *oc,
const uint8_t *data, int64_t bit_size,
int sync_extension)
{
@@ -1080,7 +1092,7 @@ static int decode_audio_specific_config(AACDecContext *ac,
if ((ret = init_get_bits(&gb, data, bit_size)) < 0)
return ret;
- return decode_audio_specific_config_gb(ac, avctx, m4ac, &gb, 0,
+ return decode_audio_specific_config_gb(ac, avctx, oc, &gb, 0,
sync_extension);
}
@@ -1104,6 +1116,15 @@ static av_cold int decode_close(AVCodecContext *avctx)
{
AACDecContext *ac = avctx->priv_data;
+ for (int i = 0; i < 2; i++) {
+ OutputConfiguration *oc = &ac->oc[i];
+ AACUSACConfig *usac = &oc->usac;
+ for (int j = 0; j < usac->nb_elems; j++) {
+ AACUsacElemConfig *ec = &usac->elems[i];
+ av_freep(&ec->ext.pl_data);
+ }
+ }
+
for (int type = 0; type < FF_ARRAY_ELEMS(ac->che); type++) {
for (int i = 0; i < MAX_ELEM_ID; i++) {
if (ac->che[type][i]) {
@@ -1181,7 +1202,7 @@ av_cold int ff_aac_decode_init(AVCodecContext *avctx)
ac->oc[1].m4ac.sample_rate = avctx->sample_rate;
if (avctx->extradata_size > 0) {
- if ((ret = decode_audio_specific_config(ac, ac->avctx, &ac->oc[1].m4ac,
+ if ((ret = decode_audio_specific_config(ac, ac->avctx, &ac->oc[1],
avctx->extradata,
avctx->extradata_size * 8LL,
1)) < 0)
@@ -1549,9 +1570,16 @@ static int decode_pulses(Pulse *pulse, GetBitContext *gb,
int ff_aac_decode_tns(AACDecContext *ac, TemporalNoiseShaping *tns,
GetBitContext *gb, const IndividualChannelStream *ics)
{
+ int tns_max_order = INT32_MAX;
+ const int is_usac = ac->oc[1].m4ac.object_type == AOT_USAC ||
+ ac->oc[1].m4ac.object_type == AOT_USAC_NOSBR;
int w, filt, i, coef_len, coef_res, coef_compress;
const int is8 = ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE;
- const int tns_max_order = is8 ? 7 : ac->oc[1].m4ac.object_type == AOT_AAC_MAIN ? 20 : 12;
+
+ /* USAC doesn't seem to have a limit */
+ if (!is_usac)
+ tns_max_order = is8 ? 7 : ac->oc[1].m4ac.object_type == AOT_AAC_MAIN ? 20 : 12;
+
for (w = 0; w < ics->num_windows; w++) {
if ((tns->n_filt[w] = get_bits(gb, 2 - is8))) {
coef_res = get_bits1(gb);
@@ -1560,7 +1588,12 @@ int ff_aac_decode_tns(AACDecContext *ac, TemporalNoiseShaping *tns,
int tmp2_idx;
tns->length[w][filt] = get_bits(gb, 6 - 2 * is8);
- if ((tns->order[w][filt] = get_bits(gb, 5 - 2 * is8)) > tns_max_order) {
+ if (is_usac)
+ tns->order[w][filt] = get_bits(gb, 4 - is8);
+ else
+ tns->order[w][filt] = get_bits(gb, 5 - (2 * is8));
+
+ if (tns->order[w][filt] > tns_max_order) {
av_log(ac->avctx, AV_LOG_ERROR,
"TNS filter order %d is greater than maximum %d.\n",
tns->order[w][filt], tns_max_order);
@@ -1598,6 +1631,7 @@ static void decode_mid_side_stereo(ChannelElement *cpe, GetBitContext *gb,
{
int idx;
int max_idx = cpe->ch[0].ics.num_window_groups * cpe->ch[0].ics.max_sfb;
+ cpe->max_sfb_ste = cpe->ch[0].ics.max_sfb;
if (ms_present == 1) {
for (idx = 0; idx < max_idx; idx++)
cpe->ms_mask[idx] = get_bits1(gb);
@@ -2182,42 +2216,19 @@ static int aac_decode_er_frame(AVCodecContext *avctx, AVFrame *frame,
return 0;
}
-static int aac_decode_frame_int(AVCodecContext *avctx, AVFrame *frame,
- int *got_frame_ptr, GetBitContext *gb,
- const AVPacket *avpkt)
+static int decode_frame_ga(AVCodecContext *avctx, AACDecContext *ac,
+ GetBitContext *gb, int *got_frame_ptr)
{
- AACDecContext *ac = avctx->priv_data;
- ChannelElement *che = NULL, *che_prev = NULL;
+ int err;
+ int is_dmono;
+ int elem_id;
enum RawDataBlockType elem_type, che_prev_type = TYPE_END;
- int err, elem_id;
- int samples = 0, multiplier, audio_found = 0, pce_found = 0;
- int is_dmono, sce_count = 0;
- int payload_alignment;
uint8_t che_presence[4][MAX_ELEM_ID] = {{0}};
+ ChannelElement *che = NULL, *che_prev = NULL;
+ int samples = 0, multiplier, audio_found = 0, pce_found = 0, sce_count = 0;
+ AVFrame *frame = ac->frame;
- ac->frame = frame;
-
- if (show_bits(gb, 12) == 0xfff) {
- if ((err = parse_adts_frame_header(ac, gb)) < 0) {
- av_log(avctx, AV_LOG_ERROR, "Error decoding AAC frame header.\n");
- goto fail;
- }
- if (ac->oc[1].m4ac.sampling_index > 12) {
- av_log(ac->avctx, AV_LOG_ERROR, "invalid sampling rate index %d\n", ac->oc[1].m4ac.sampling_index);
- err = AVERROR_INVALIDDATA;
- goto fail;
- }
- }
-
- if ((err = frame_configure_elements(avctx)) < 0)
- goto fail;
-
- // The AV_PROFILE_AAC_* defines are all object_type - 1
- // This may lead to an undefined profile being signaled
- ac->avctx->profile = ac->oc[1].m4ac.object_type - 1;
-
- payload_alignment = get_bits_count(gb);
- ac->tags_mapped = 0;
+ int payload_alignment = get_bits_count(gb);
// parse
while ((elem_type = get_bits(gb, 3)) != TYPE_END) {
elem_id = get_bits(gb, 4);
@@ -2225,28 +2236,23 @@ static int aac_decode_frame_int(AVCodecContext *avctx, AVFrame *frame,
if (avctx->debug & FF_DEBUG_STARTCODE)
av_log(avctx, AV_LOG_DEBUG, "Elem type:%x id:%x\n", elem_type, elem_id);
- if (!avctx->ch_layout.nb_channels && elem_type != TYPE_PCE) {
- err = AVERROR_INVALIDDATA;
- goto fail;
- }
+ if (!avctx->ch_layout.nb_channels && elem_type != TYPE_PCE)
+ return AVERROR_INVALIDDATA;
if (elem_type < TYPE_DSE) {
if (che_presence[elem_type][elem_id]) {
int error = che_presence[elem_type][elem_id] > 1;
av_log(ac->avctx, error ? AV_LOG_ERROR : AV_LOG_DEBUG, "channel element %d.%d duplicate\n",
elem_type, elem_id);
- if (error) {
- err = AVERROR_INVALIDDATA;
- goto fail;
- }
+ if (error)
+ return AVERROR_INVALIDDATA;
}
che_presence[elem_type][elem_id]++;
if (!(che=ff_aac_get_che(ac, elem_type, elem_id))) {
av_log(ac->avctx, AV_LOG_ERROR, "channel element %d.%d is not allocated\n",
elem_type, elem_id);
- err = AVERROR_INVALIDDATA;
- goto fail;
+ return AVERROR_INVALIDDATA;
}
samples = ac->oc[1].m4ac.frame_length_short ? 960 : 1024;
che->present = 1;
@@ -2283,10 +2289,8 @@ static int aac_decode_frame_int(AVCodecContext *avctx, AVFrame *frame,
int tags;
int pushed = push_output_configuration(ac);
- if (pce_found && !pushed) {
- err = AVERROR_INVALIDDATA;
- goto fail;
- }
+ if (pce_found && !pushed)
+ return AVERROR_INVALIDDATA;
tags = decode_pce(avctx, &ac->oc[1].m4ac, layout_map, gb,
payload_alignment);
@@ -2312,8 +2316,7 @@ static int aac_decode_frame_int(AVCodecContext *avctx, AVFrame *frame,
elem_id += get_bits(gb, 8) - 1;
if (get_bits_left(gb) < 8 * elem_id) {
av_log(avctx, AV_LOG_ERROR, "TYPE_FIL: "overread_err);
- err = AVERROR_INVALIDDATA;
- goto fail;
+ return AVERROR_INVALIDDATA;
}
err = 0;
while (elem_id > 0) {
@@ -2337,19 +2340,16 @@ static int aac_decode_frame_int(AVCodecContext *avctx, AVFrame *frame,
}
if (err)
- goto fail;
+ return err;
if (get_bits_left(gb) < 3) {
av_log(avctx, AV_LOG_ERROR, overread_err);
- err = AVERROR_INVALIDDATA;
- goto fail;
+ return AVERROR_INVALIDDATA;
}
}
- if (!avctx->ch_layout.nb_channels) {
- *got_frame_ptr = 0;
+ if (!avctx->ch_layout.nb_channels)
return 0;
- }
multiplier = (ac->oc[1].m4ac.sbr == 1) ? ac->oc[1].m4ac.ext_sample_rate > ac->oc[1].m4ac.sample_rate : 0;
samples <<= multiplier;
@@ -2364,16 +2364,17 @@ static int aac_decode_frame_int(AVCodecContext *avctx, AVFrame *frame,
if (!ac->frame->data[0] && samples) {
av_log(avctx, AV_LOG_ERROR, "no frame data found\n");
- err = AVERROR_INVALIDDATA;
- goto fail;
+ return AVERROR_INVALIDDATA;
}
if (samples) {
ac->frame->nb_samples = samples;
ac->frame->sample_rate = avctx->sample_rate;
- } else
+ *got_frame_ptr = 1;
+ } else {
av_frame_unref(ac->frame);
- *got_frame_ptr = !!samples;
+ *got_frame_ptr = 0;
+ }
/* for dual-mono audio (SCE + SCE) */
is_dmono = ac->dmono_mode && sce_count == 2 &&
@@ -2387,6 +2388,59 @@ static int aac_decode_frame_int(AVCodecContext *avctx, AVFrame *frame,
}
return 0;
+}
+
+static int aac_decode_frame_int(AVCodecContext *avctx, AVFrame *frame,
+ int *got_frame_ptr, GetBitContext *gb,
+ const AVPacket *avpkt)
+{
+ int err;
+ AACDecContext *ac = avctx->priv_data;
+
+ ac->frame = frame;
+ *got_frame_ptr = 0;
+
+ if (show_bits(gb, 12) == 0xfff) {
+ if ((err = parse_adts_frame_header(ac, gb)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Error decoding AAC frame header.\n");
+ goto fail;
+ }
+ if (ac->oc[1].m4ac.sampling_index > 12) {
+ av_log(ac->avctx, AV_LOG_ERROR, "invalid sampling rate index %d\n", ac->oc[1].m4ac.sampling_index);
+ err = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+ }
+
+ if ((err = frame_configure_elements(avctx)) < 0)
+ goto fail;
+
+ // The AV_PROFILE_AAC_* defines are all object_type - 1
+ // This may lead to an undefined profile being signaled
+ ac->avctx->profile = ac->oc[1].m4ac.object_type - 1;
+
+ ac->tags_mapped = 0;
+
+ if ((ac->oc[1].m4ac.object_type == AOT_USAC) ||
+ (ac->oc[1].m4ac.object_type == AOT_USAC_NOSBR)) {
+ if (ac->is_fixed) {
+ avpriv_report_missing_feature(ac->avctx,
+ "AAC USAC fixed-point decoding");
+ return AVERROR_PATCHWELCOME;
+ }
+#if CONFIG_AAC_DECODER
+ err = ff_aac_usac_decode_frame(avctx, ac, gb, got_frame_ptr);
+ if (err < 0)
+ goto fail;
+#endif
+ } else {
+ err = decode_frame_ga(avctx, ac, gb, got_frame_ptr);
+ if (err < 0)
+ goto fail;
+ }
+
+ return err;
+
fail:
pop_output_configuration(ac);
return err;
@@ -2414,7 +2468,7 @@ static int aac_decode_frame(AVCodecContext *avctx, AVFrame *frame,
if (new_extradata) {
/* discard previous configuration */
ac->oc[1].status = OC_NONE;
- err = decode_audio_specific_config(ac, ac->avctx, &ac->oc[1].m4ac,
+ err = decode_audio_specific_config(ac, ac->avctx, &ac->oc[1],
new_extradata,
new_extradata_size * 8LL, 1);
if (err < 0) {
diff --git a/libavcodec/aac/aacdec.h b/libavcodec/aac/aacdec.h
index 8d1eb74066..ee21a94007 100644
--- a/libavcodec/aac/aacdec.h
+++ b/libavcodec/aac/aacdec.h
@@ -42,6 +42,8 @@
#include "libavcodec/avcodec.h"
#include "libavcodec/mpeg4audio.h"
+#include "aacdec_ac.h"
+
typedef struct AACDecContext AACDecContext;
/**
@@ -69,6 +71,32 @@ enum CouplingPoint {
AFTER_IMDCT = 3,
};
+enum AACUsacElem {
+ ID_USAC_SCE = 0,
+ ID_USAC_CPE = 1,
+ ID_USAC_LFE = 2,
+ ID_USAC_EXT = 3,
+};
+
+enum ExtensionHeaderType {
+ ID_CONFIG_EXT_FILL = 0,
+ ID_CONFIG_EXT_LOUDNESS_INFO = 2,
+ ID_CONFIG_EXT_STREAM_ID = 7,
+};
+
+enum AACUsacExtension {
+ ID_EXT_ELE_FILL,
+ ID_EXT_ELE_MPEGS,
+ ID_EXT_ELE_SAOC,
+ ID_EXT_ELE_AUDIOPREROLL,
+ ID_EXT_ELE_UNI_DRC,
+};
+
+enum AACUSACLoudnessExt {
+ UNIDRCLOUDEXT_TERM = 0x0,
+ UNIDRCLOUDEXT_EQ = 0x1,
+};
+
// Supposed to be equal to AAC_RENAME() in case of USE_FIXED.
#define RENAME_FIXED(name) name ## _fixed
@@ -93,6 +121,40 @@ typedef struct LongTermPrediction {
int8_t used[MAX_LTP_LONG_SFB];
} LongTermPrediction;
+/* Per channel core mode */
+typedef struct AACUsacElemData {
+ uint8_t core_mode;
+ uint8_t scale_factor_grouping;
+
+ /* Timewarping ratio */
+#define NUM_TW_NODES 16
+ uint8_t tw_ratio[NUM_TW_NODES];
+
+ struct {
+ uint8_t acelp_core_mode : 3;
+ uint8_t lpd_mode : 5;
+
+ uint8_t bpf_control_info : 1;
+ uint8_t core_mode_last : 1;
+ uint8_t fac_data_present : 1;
+
+ int last_lpd_mode;
+ } ldp;
+
+ struct {
+ unsigned int seed;
+ uint8_t level : 3;
+ uint8_t offset : 5;
+ } noise;
+
+ struct {
+ uint8_t gain;
+ uint32_t kv[8 /* (1024 / 16) / 8 */][8];
+ } fac;
+
+ AACArithState ac;
+} AACUsacElemData;
+
/**
* Individual Channel Stream
*/
@@ -145,11 +207,13 @@ typedef struct ChannelCoupling {
*/
typedef struct SingleChannelElement {
IndividualChannelStream ics;
+ AACUsacElemData ue; ///< USAC element data
TemporalNoiseShaping tns;
enum BandType band_type[128]; ///< band types
int sfo[128]; ///< scalefactor offsets
INTFLOAT_UNION(sf, [128]); ///< scalefactors (8 windows * 16 sfb max)
INTFLOAT_ALIGNED_UNION(32, coeffs, 1024); ///< coefficients for IMDCT, maybe processed
+ INTFLOAT_ALIGNED_UNION(32, prev_coeffs, 1024); ///< unscaled previous contents of coeffs[] for USAC
INTFLOAT_ALIGNED_UNION(32, saved, 1536); ///< overlap
INTFLOAT_ALIGNED_UNION(32, ret_buf, 2048); ///< PCM output buffer
INTFLOAT_ALIGNED_UNION(16, ltp_state, 3072); ///< time signal for LTP
@@ -163,25 +227,148 @@ typedef struct SingleChannelElement {
};
} SingleChannelElement;
+typedef struct AACUsacStereo {
+ uint8_t common_window;
+ uint8_t common_tw;
+
+ uint8_t ms_mask_mode;
+ uint8_t config_idx;
+
+ /* Complex prediction */
+ uint8_t use_prev_frame;
+ uint8_t pred_dir;
+ uint8_t complex_coef;
+
+ uint8_t pred_used[128];
+
+ INTFLOAT_ALIGNED_UNION(32, alpha_q_re, 1024);
+ INTFLOAT_ALIGNED_UNION(32, alpha_q_im, 1024);
+ INTFLOAT_ALIGNED_UNION(32, prev_alpha_q_re, 1024);
+ INTFLOAT_ALIGNED_UNION(32, prev_alpha_q_im, 1024);
+
+ INTFLOAT_ALIGNED_UNION(32, dmix_re, 1024);
+ INTFLOAT_ALIGNED_UNION(32, prev_dmix_re, 1024); /* Recalculated on every frame */
+ INTFLOAT_ALIGNED_UNION(32, dmix_im, 1024); /* Final prediction data */
+} AACUsacStereo;
+
/**
* channel element - generic struct for SCE/CPE/CCE/LFE
*/
typedef struct ChannelElement {
int present;
// CPE specific
+ uint8_t max_sfb_ste; ///< (USAC) Maximum of both max_sfb values
uint8_t ms_mask[128]; ///< Set if mid/side stereo is used for each scalefactor window band
// shared
SingleChannelElement ch[2];
// CCE specific
ChannelCoupling coup;
+ // USAC stereo coupling data
+ AACUsacStereo us;
} ChannelElement;
+typedef struct AACUSACLoudnessInfo {
+ uint8_t drc_set_id : 6;
+ uint8_t downmix_id : 7;
+ struct {
+ uint16_t lvl : 12;
+ uint8_t present : 1;
+ } sample_peak;
+
+ struct {
+ uint16_t lvl : 12;
+ uint8_t measurement : 4;
+ uint8_t reliability : 2;
+ uint8_t present : 1;
+ } true_peak;
+
+ uint8_t nb_measurements : 4;
+ struct {
+ uint8_t method_def : 4;
+ uint8_t method_val;
+ uint8_t measurement : 4;
+ uint8_t reliability : 2;
+ } measurements[16];
+} AACUSACLoudnessInfo;
+
+typedef struct AACUsacElemConfig {
+ enum AACUsacElem type;
+
+ uint8_t tw_mdct : 1;
+ uint8_t noise_fill : 1;
+
+ uint8_t stereo_config_index;
+
+ struct {
+ int ratio;
+
+ uint8_t harmonic_sbr : 1; /* harmonicSBR */
+ uint8_t bs_intertes : 1; /* bs_interTes */
+ uint8_t bs_pvc : 1; /* bs_pvc */
+
+ struct {
+ uint8_t start_freq; /* dflt_start_freq */
+ uint8_t stop_freq; /* dflt_stop_freq */
+
+ uint8_t freq_scale; /* dflt_freq_scale */
+ uint8_t alter_scale : 1; /* dflt_alter_scale */
+ uint8_t noise_scale; /* dflt_noise_scale */
+
+ uint8_t limiter_bands; /* dflt_limiter_bands */
+ uint8_t limiter_gains; /* dflt_limiter_gains */
+ uint8_t interpol_freq : 1; /* dflt_interpol_freq */
+ uint8_t smoothing_mode : 1; /* dflt_smoothing_mode */
+ } dflt;
+ } sbr;
+
+ struct {
+ uint8_t freq_res; /* bsFreqRes */
+ uint8_t fixed_gain; /* bsFixedGainDMX */
+ uint8_t temp_shape_config; /* bsTempShapeConfig */
+ uint8_t decorr_config; /* bsDecorrConfig */
+ uint8_t high_rate_mode : 1; /* bsHighRateMode */
+ uint8_t phase_coding : 1; /* bsPhaseCoding */
+
+ uint8_t otts_bands_phase; /* bsOttBandsPhase */
+ uint8_t residual_coding; /* bsResidualCoding */
+ uint8_t residual_bands; /* bsResidualBands */
+ uint8_t pseudo_lr : 1; /* bsPseudoLr */
+ uint8_t env_quant_mode : 1; /* bsEnvQuantMode */
+ } mps;
+
+ struct {
+ enum AACUsacExtension type;
+ uint8_t payload_frag;
+ uint32_t default_len;
+ uint32_t pl_data_offset;
+ uint8_t *pl_data;
+ } ext;
+} AACUsacElemConfig;
+
+typedef struct AACUSACConfig {
+ uint8_t core_sbr_frame_len_idx; /* coreSbrFrameLengthIndex */
+ uint8_t rate_idx;
+ uint16_t core_frame_len;
+ uint16_t stream_identifier;
+
+ AACUsacElemConfig elems[64];
+ int nb_elems;
+
+ struct {
+ uint8_t nb_album;
+ AACUSACLoudnessInfo album_info[64];
+ uint8_t nb_info;
+ AACUSACLoudnessInfo info[64];
+ } loudness;
+} AACUSACConfig;
+
typedef struct OutputConfiguration {
MPEG4AudioConfig m4ac;
uint8_t layout_map[MAX_ELEM_ID*4][3];
int layout_map_tags;
AVChannelLayout ch_layout;
enum OCStatus status;
+ AACUSACConfig usac;
} OutputConfiguration;
/**
diff --git a/libavcodec/aac/aacdec_ac.c b/libavcodec/aac/aacdec_ac.c
new file mode 100644
index 0000000000..7e5077cd19
--- /dev/null
+++ b/libavcodec/aac/aacdec_ac.c
@@ -0,0 +1,208 @@
+/*
+ * AAC definitions and structures
+ * Copyright (c) 2024 Lynne
+ *
+ * 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 "libavcodec/aactab.h"
+#include "aacdec_ac.h"
+
+uint32_t ff_aac_ac_map_process(AACArithState *state, int reset, int N)
+{
+ float ratio;
+ if (reset) {
+ memset(state->last, 0, sizeof(state->last));
+ state->last_len = N;
+ } else if (state->last_len != N) {
+ int i;
+ uint8_t last[512 /* 2048 / 4 */];
+ memcpy(last, state->last, sizeof(last));
+
+ ratio = state->last_len / (float)N;
+ for (i = 0; i < N/2; i++) {
+ int k = (int)(i * ratio);
+ state->last[i] = last[k];
+ }
+
+ for (; i < FF_ARRAY_ELEMS(state->last); i++)
+ state->last[i] = 0;
+
+ state->last_len = N;
+ }
+
+ state->cur[3] = 0;
+ state->cur[2] = 0;
+ state->cur[1] = 0;
+ state->cur[0] = 1;
+
+ state->state_pre = state->last[0] << 12;
+ return state->last[0] << 12;
+}
+
+uint32_t ff_aac_ac_get_context(AACArithState *state, uint32_t c, int i, int N)
+{
+ c = state->state_pre >> 8;
+ c = c + (state->last[i + 1] << 8);
+ c = (c << 4);
+ c += state->cur[1];
+
+ state->state_pre = c;
+
+ if (i > 3 &&
+ ((state->cur[3] + state->cur[2] + state->cur[1]) < 5))
+ return c + 0x10000;
+
+ return c;
+}
+
+uint32_t ff_aac_ac_get_pk(uint32_t c)
+{
+ int i_min = -1;
+ int i, j;
+ int i_max = FF_ARRAY_ELEMS(ff_aac_ac_lookup_m) - 1;
+ while ((i_max - i_min) > 1) {
+ i = i_min + ((i_max - i_min) / 2);
+ j = ff_aac_ac_hash_m[i];
+ if (c < (j >> 8))
+ i_max = i;
+ else if (c > (j >> 8))
+ i_min = i;
+ else
+ return (j & 0xFF);
+ }
+ return ff_aac_ac_lookup_m[i_max];
+}
+
+void ff_aac_ac_update_context(AACArithState *state, int idx,
+ uint16_t a, uint16_t b)
+{
+ state->cur[0] = a + b + 1;
+ if (state->cur[0] > 0xF)
+ state->cur[0] = 0xF;
+
+ state->cur[3] = state->cur[2];
+ state->cur[2] = state->cur[1];
+ state->cur[1] = state->cur[0];
+
+ state->last[idx] = state->cur[0];
+}
+
+/* Initialize AC */
+void ff_aac_ac_init(AACArith *ac, GetBitContext *gb)
+{
+ ac->low = 0;
+ ac->high = UINT16_MAX;
+ ac->val = get_bits(gb, 16);
+}
+
+uint16_t ff_aac_ac_decode(AACArith *ac, GetBitContext *gb,
+ const uint16_t *cdf, uint16_t cdf_len)
+{
+ int val = ac->val;
+ int low = ac->low;
+ int high = ac->high;
+
+ int sym;
+ int rng = high - low + 1;
+ int c = ((((int)(val - low + 1)) << 14) - ((int)1));
+
+ const uint16_t *p = cdf - 1;
+
+ /* One for each possible CDF length in the spec */
+ switch (cdf_len) {
+ case 2:
+ if ((p[1] * rng) > c)
+ p += 1;
+ break;
+ case 4:
+ if ((p[2] * rng) > c)
+ p += 2;
+ if ((p[1] * rng) > c)
+ p += 1;
+ break;
+ case 17:
+ /* First check if the current probability is even met at all */
+ if ((p[1] * rng) <= c)
+ break;
+ p += 1;
+ for (int i = 8; i >= 1; i >>= 1)
+ if ((p[i] * rng) > c)
+ p += i;
+ break;
+ case 27:
+ if ((p[16] * rng) > c)
+ p += 16;
+ if ((p[8] * rng) > c)
+ p += 8;
+ if (p != (cdf - 1 + 24))
+ if ((p[4] * rng) > c)
+ p += 4;
+ if ((p[2] * rng) > c)
+ p += 2;
+
+ if (p != (cdf - 1 + 24 + 2))
+ if ((p[1] * rng) > c)
+ p += 1;
+ break;
+ default:
+ /* This should never happen */
+ av_assert2(0);
+ }
+
+ sym = (int)((ptrdiff_t)(p - cdf)) + 1;
+ if (sym)
+ high = low + ((rng * cdf[sym - 1]) >> 14) - 1;
+ low += (rng * cdf[sym]) >> 14;
+
+ /* This loop could be done faster */
+ while (1) {
+ if (high < 32768) {
+ ;
+ } else if (low >= 32768) {
+ val -= 32768;
+ low -= 32768;
+ high -= 32768;
+ } else if (low >= 16384 && high < 49152) {
+ val -= 16384;
+ low -= 16384;
+ high -= 16384;
+ } else {
+ break;
+ }
+ low += low;
+ high += high + 1;
+ val = (val << 1) | get_bits1(gb);
+ };
+
+ ac->low = low;
+ ac->high = high;
+ ac->val = val;
+
+ return sym;
+}
+
+void ff_aac_ac_finish(AACArithState *state, int offset, int N)
+{
+ int i;
+
+ for (i = offset; i < N/2; i++)
+ state->last[i] = 1;
+
+ for (; i < FF_ARRAY_ELEMS(state->last); i++)
+ state->last[i] = 0;
+}
diff --git a/libavcodec/aac/aacdec_ac.h b/libavcodec/aac/aacdec_ac.h
new file mode 100644
index 0000000000..0b98c0f0d9
--- /dev/null
+++ b/libavcodec/aac/aacdec_ac.h
@@ -0,0 +1,54 @@
+/*
+ * AAC definitions and structures
+ * Copyright (c) 2024 Lynne
+ *
+ * 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_AC_H
+#define AVCODEC_AAC_AACDEC_AC_H
+
+#include "libavcodec/get_bits.h"
+
+typedef struct AACArithState {
+ uint8_t last[512 /* 2048 / 4 */];
+ int last_len;
+ uint8_t cur[4];
+ uint16_t state_pre;
+} AACArithState;
+
+typedef struct AACArith {
+ uint16_t low;
+ uint16_t high;
+ uint16_t val;
+} AACArith;
+
+#define FF_AAC_AC_ESCAPE 16
+
+uint32_t ff_aac_ac_map_process(AACArithState *state, int reset, int len);
+uint32_t ff_aac_ac_get_context(AACArithState *state, uint32_t old_c, int idx, int len);
+uint32_t ff_aac_ac_get_pk(uint32_t c);
+
+void ff_aac_ac_update_context(AACArithState *state, int idx, uint16_t a, uint16_t b);
+void ff_aac_ac_init(AACArith *ac, GetBitContext *gb);
+
+uint16_t ff_aac_ac_decode(AACArith *ac, GetBitContext *gb,
+ const uint16_t *cdf, uint16_t cdf_len);
+
+void ff_aac_ac_finish(AACArithState *state, int offset, int nb);
+
+#endif /* AVCODEC_AACDEC_AC_H */
diff --git a/libavcodec/aac/aacdec_dsp_template.c b/libavcodec/aac/aacdec_dsp_template.c
index 59a69d88f3..8d31af22f8 100644
--- a/libavcodec/aac/aacdec_dsp_template.c
+++ b/libavcodec/aac/aacdec_dsp_template.c
@@ -88,8 +88,8 @@ static void AAC_RENAME(apply_mid_side_stereo)(AACDecContext *ac, ChannelElement
INTFLOAT *ch1 = cpe->ch[1].AAC_RENAME(coeffs);
const uint16_t *offsets = ics->swb_offset;
for (int g = 0; g < ics->num_window_groups; g++) {
- for (int sfb = 0; sfb < ics->max_sfb; sfb++) {
- const int idx = g*ics->max_sfb + sfb;
+ for (int sfb = 0; sfb < cpe->max_sfb_ste; sfb++) {
+ const int idx = g*cpe->max_sfb_ste + sfb;
if (cpe->ms_mask[idx] &&
cpe->ch[0].band_type[idx] < NOISE_BT &&
cpe->ch[1].band_type[idx] < NOISE_BT) {
diff --git a/libavcodec/aac/aacdec_latm.h b/libavcodec/aac/aacdec_latm.h
index e40a2fe1a7..047c11e0fb 100644
--- a/libavcodec/aac/aacdec_latm.h
+++ b/libavcodec/aac/aacdec_latm.h
@@ -56,7 +56,8 @@ static int latm_decode_audio_specific_config(struct LATMContext *latmctx,
{
AACDecContext *ac = &latmctx->aac_ctx;
AVCodecContext *avctx = ac->avctx;
- MPEG4AudioConfig m4ac = { 0 };
+ OutputConfiguration oc = { 0 };
+ MPEG4AudioConfig *m4ac = &oc.m4ac;
GetBitContext gbc;
int config_start_bit = get_bits_count(gb);
int sync_extension = 0;
@@ -76,7 +77,7 @@ static int latm_decode_audio_specific_config(struct LATMContext *latmctx,
if (get_bits_left(gb) <= 0)
return AVERROR_INVALIDDATA;
- bits_consumed = decode_audio_specific_config_gb(NULL, avctx, &m4ac,
+ bits_consumed = decode_audio_specific_config_gb(NULL, avctx, &oc,
&gbc, config_start_bit,
sync_extension);
@@ -88,11 +89,12 @@ static int latm_decode_audio_specific_config(struct LATMContext *latmctx,
asclen = bits_consumed;
if (!latmctx->initialized ||
- ac->oc[1].m4ac.sample_rate != m4ac.sample_rate ||
- ac->oc[1].m4ac.chan_config != m4ac.chan_config) {
+ ac->oc[1].m4ac.sample_rate != m4ac->sample_rate ||
+ ac->oc[1].m4ac.chan_config != m4ac->chan_config) {
if (latmctx->initialized) {
- av_log(avctx, AV_LOG_INFO, "audio config changed (sample_rate=%d, chan_config=%d)\n", m4ac.sample_rate, m4ac.chan_config);
+ av_log(avctx, AV_LOG_INFO, "audio config changed (sample_rate=%d, chan_config=%d)\n",
+ m4ac->sample_rate, m4ac->chan_config);
} else {
av_log(avctx, AV_LOG_DEBUG, "initializing latmctx\n");
}
@@ -280,7 +282,7 @@ static int latm_decode_frame(AVCodecContext *avctx, AVFrame *out,
} else {
push_output_configuration(&latmctx->aac_ctx);
if ((err = decode_audio_specific_config(
- &latmctx->aac_ctx, avctx, &latmctx->aac_ctx.oc[1].m4ac,
+ &latmctx->aac_ctx, avctx, &latmctx->aac_ctx.oc[1],
avctx->extradata, avctx->extradata_size*8LL, 1)) < 0) {
pop_output_configuration(&latmctx->aac_ctx);
return err;
diff --git a/libavcodec/aac/aacdec_lpd.c b/libavcodec/aac/aacdec_lpd.c
new file mode 100644
index 0000000000..796edd2ab5
--- /dev/null
+++ b/libavcodec/aac/aacdec_lpd.c
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2024 Lynne <dev@lynne.ee>
+ *
+ * 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_lpd.h"
+#include "aacdec_usac.h"
+#include "libavcodec/unary.h"
+
+const uint8_t ff_aac_lpd_mode_tab[32][4] = {
+ { 0, 0, 0, 0 },
+ { 1, 0, 0, 0 },
+ { 0, 1, 0, 0 },
+ { 1, 1, 0, 0 },
+ { 0, 0, 1, 0 },
+ { 1, 0, 1, 0 },
+ { 0, 1, 1, 0 },
+ { 1, 1, 1, 0 },
+ { 0, 0, 0, 1 },
+ { 1, 0, 0, 1 },
+ { 0, 1, 0, 1 },
+ { 1, 1, 0, 1 },
+ { 0, 0, 1, 1 },
+ { 1, 0, 1, 1 },
+ { 0, 1, 1, 1 },
+ { 1, 1, 1, 1 },
+ { 2, 2, 0, 0 },
+ { 2, 2, 1, 0 },
+ { 2, 2, 0, 1 },
+ { 2, 2, 1, 1 },
+ { 0, 0, 2, 2 },
+ { 1, 0, 2, 2 },
+ { 0, 1, 2, 2 },
+ { 1, 1, 2, 2 },
+ { 2, 2, 2, 2 },
+ { 3, 3, 3, 3 },
+ /* Larger values are reserved, but permit them for resilience */
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+};
+
+static void parse_qn(GetBitContext *gb, int *qn, int nk_mode, int no_qn)
+{
+ if (nk_mode == 1) {
+ for (int k = 0; k < no_qn; k++) {
+ qn[k] = get_unary(gb, 0, INT32_MAX); // TODO: find proper ranges
+ if (qn[k])
+ qn[k]++;
+ }
+ return;
+ }
+
+ for (int k = 0; k < no_qn; k++)
+ qn[k] = get_bits(gb, 2) + 2;
+
+ if (nk_mode == 2) {
+ for (int k = 0; k < no_qn; k++) {
+ if (qn[k] > 4) {
+ qn[k] = get_unary(gb, 0, INT32_MAX);;
+ if (qn[k])
+ qn[k] += 4;
+ }
+ }
+ return;
+ }
+
+ for (int k = 0; k < no_qn; k++) {
+ if (qn[k] > 4) {
+ int qn_ext = get_unary(gb, 0, INT32_MAX);;
+ switch (qn_ext) {
+ case 0: qn[k] = 5; break;
+ case 1: qn[k] = 6; break;
+ case 2: qn[k] = 0; break;
+ default: qn[k] = qn_ext + 4; break;
+ }
+ }
+ }
+}
+
+static int parse_codebook_idx(GetBitContext *gb, uint32_t *kv,
+ int nk_mode, int no_qn)
+{
+ int idx, n, nk;
+
+ int qn[2];
+ parse_qn(gb, qn, nk_mode, no_qn);
+
+ for (int k = 0; k < no_qn; k++) {
+ if (qn[k] > 4) {
+ nk = (qn[k] - 3) / 2;
+ n = qn[k] - nk*2;
+ } else {
+ nk = 0;
+ n = qn[k];
+ }
+ }
+
+ idx = get_bits(gb, 4*n);
+
+ if (nk > 0)
+ for (int i = 0; i < 8; i++)
+ kv[i] = get_bits(gb, nk);
+
+ return 0;
+}
+
+int ff_aac_parse_fac_data(AACUsacElemData *ce, GetBitContext *gb,
+ int use_gain, int len)
+{
+ int ret;
+ if (use_gain)
+ ce->fac.gain = get_bits(gb, 7);
+
+ for (int i = 0; i < len/8; i++) {
+ ret = parse_codebook_idx(gb, ce->fac.kv[i], 1, 1);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+int ff_aac_ldp_parse_channel_stream(AACDecContext *ac, AACUSACConfig *usac,
+ AACUsacElemData *ce, GetBitContext *gb)
+{
+ int k;
+ const uint8_t *mod;
+ int first_ldp_flag;
+ int first_tcx_flag;
+
+ ce->ldp.acelp_core_mode = get_bits(gb, 3);
+ ce->ldp.lpd_mode = get_bits(gb, 5);
+
+ ce->ldp.bpf_control_info = get_bits1(gb);
+ ce->ldp.core_mode_last = get_bits1(gb);
+ ce->ldp.fac_data_present = get_bits1(gb);
+
+ mod = ff_aac_lpd_mode_tab[ce->ldp.lpd_mode];
+
+ first_ldp_flag = !ce->ldp.core_mode_last;
+ first_tcx_flag = 1;
+ if (first_ldp_flag)
+ ce->ldp.last_lpd_mode = -1; /* last_ldp_mode is a **STATEFUL** value */
+
+ k = 0;
+ while (k < 0) {
+ if (!k) {
+ if (ce->ldp.core_mode_last && ce->ldp.fac_data_present)
+ ff_aac_parse_fac_data(ce, gb, 0, usac->core_frame_len/8);
+ } else {
+ if (!ce->ldp.last_lpd_mode && mod[k] > 0 ||
+ ce->ldp.last_lpd_mode && !mod[k])
+ ff_aac_parse_fac_data(ce, gb, 0, usac->core_frame_len/8);
+ }
+ if (!mod[k]) {
+// parse_acelp_coding();
+ ce->ldp.last_lpd_mode = 0;
+ k++;
+ } else {
+// parse_tcx_coding();
+ ce->ldp.last_lpd_mode = mod[k];
+ k += (1 << (mod[k] - 1));
+ first_tcx_flag = 0;
+ }
+ }
+
+// parse_lpc_data(first_lpd_flag);
+
+ if (!ce->ldp.core_mode_last && ce->ldp.fac_data_present) {
+ uint16_t len_8 = usac->core_frame_len / 8;
+ uint16_t len_16 = usac->core_frame_len / 16;
+ uint16_t fac_len = get_bits1(gb) /* short_fac_flag */ ? len_8 : len_16;
+ int ret = ff_aac_parse_fac_data(ce, gb, 1, fac_len);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
diff --git a/libavcodec/aac/aacdec_lpd.h b/libavcodec/aac/aacdec_lpd.h
new file mode 100644
index 0000000000..924ff75e52
--- /dev/null
+++ b/libavcodec/aac/aacdec_lpd.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2024 Lynne <dev@lynne.ee>
+ *
+ * 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_LPD_H
+#define AVCODEC_AAC_AACDEC_LPD_H
+
+#include "aacdec.h"
+#include "libavcodec/get_bits.h"
+
+int ff_aac_parse_fac_data(AACUsacElemData *ce, GetBitContext *gb,
+ int use_gain, int len);
+
+int ff_aac_ldp_parse_channel_stream(AACDecContext *ac, AACUSACConfig *usac,
+ AACUsacElemData *ce, GetBitContext *gb);
+
+#endif /* AVCODEC_AAC_AACDEC_LPD_H */
diff --git a/libavcodec/aac/aacdec_usac.c b/libavcodec/aac/aacdec_usac.c
new file mode 100644
index 0000000000..c3c9137a2e
--- /dev/null
+++ b/libavcodec/aac/aacdec_usac.c
@@ -0,0 +1,1608 @@
+/*
+ * Copyright (c) 2024 Lynne <dev@lynne.ee>
+ *
+ * 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_usac.h"
+#include "aacdec_tab.h"
+#include "aacdec_lpd.h"
+#include "aacdec_ac.h"
+
+#include "libavcodec/aactab.h"
+#include "libavutil/mem.h"
+#include "libavcodec/mpeg4audio.h"
+#include "libavcodec/unary.h"
+
+/* Number of scalefactor bands per complex prediction band, equal to 2. */
+#define SFB_PER_PRED_BAND 2
+
+static inline uint32_t get_escaped_value(GetBitContext *gb, int nb1, int nb2, int nb3)
+{
+ uint32_t val = get_bits(gb, nb1), val2;
+ if (val < ((1 << nb1) - 1))
+ return val;
+
+ val += val2 = get_bits(gb, nb2);
+ if (val2 == ((1 << nb2) - 1))
+ val += get_bits(gb, nb3);
+
+ return val;
+}
+
+/* ISO/IEC 23003-3, Table 74 — bsOutputChannelPos */
+static const enum AVChannel usac_ch_pos_to_av[64] = {
+ [0] = AV_CHAN_FRONT_LEFT,
+ [1] = AV_CHAN_FRONT_RIGHT,
+ [2] = AV_CHAN_FRONT_CENTER,
+ [3] = AV_CHAN_LOW_FREQUENCY,
+ [4] = AV_CHAN_SIDE_LEFT, // +110 degrees, Ls|LS|kAudioChannelLabel_LeftSurround
+ [5] = AV_CHAN_SIDE_RIGHT, // -110 degrees, Rs|RS|kAudioChannelLabel_RightSurround
+ [6] = AV_CHAN_FRONT_LEFT_OF_CENTER,
+ [7] = AV_CHAN_FRONT_RIGHT_OF_CENTER,
+ [8] = AV_CHAN_BACK_LEFT, // +135 degrees, Lsr|BL|kAudioChannelLabel_RearSurroundLeft
+ [9] = AV_CHAN_BACK_RIGHT, // -135 degrees, Rsr|BR|kAudioChannelLabel_RearSurroundRight
+ [10] = AV_CHAN_BACK_CENTER,
+ [11] = AV_CHAN_SURROUND_DIRECT_LEFT,
+ [12] = AV_CHAN_SURROUND_DIRECT_RIGHT,
+ [13] = AV_CHAN_SIDE_SURROUND_LEFT, // +90 degrees, Lss|SL|kAudioChannelLabel_LeftSideSurround
+ [14] = AV_CHAN_SIDE_SURROUND_RIGHT, // -90 degrees, Rss|SR|kAudioChannelLabel_RightSideSurround
+ [15] = AV_CHAN_WIDE_LEFT, // +60 degrees, Lw|FLw|kAudioChannelLabel_LeftWide
+ [16] = AV_CHAN_WIDE_RIGHT, // -60 degrees, Rw|FRw|kAudioChannelLabel_RightWide
+ [17] = AV_CHAN_TOP_FRONT_LEFT,
+ [18] = AV_CHAN_TOP_FRONT_RIGHT,
+ [19] = AV_CHAN_TOP_FRONT_CENTER,
+ [20] = AV_CHAN_TOP_BACK_LEFT,
+ [21] = AV_CHAN_TOP_BACK_RIGHT,
+ [22] = AV_CHAN_TOP_BACK_CENTER,
+ [23] = AV_CHAN_TOP_SIDE_LEFT,
+ [24] = AV_CHAN_TOP_SIDE_RIGHT,
+ [25] = AV_CHAN_TOP_CENTER,
+ [26] = AV_CHAN_LOW_FREQUENCY_2,
+ [27] = AV_CHAN_BOTTOM_FRONT_LEFT,
+ [28] = AV_CHAN_BOTTOM_FRONT_RIGHT,
+ [29] = AV_CHAN_BOTTOM_FRONT_CENTER,
+ [30] = AV_CHAN_TOP_SURROUND_LEFT, ///< +110 degrees, Lvs, TpLS
+ [31] = AV_CHAN_TOP_SURROUND_RIGHT, ///< -110 degrees, Rvs, TpRS
+};
+
+static int decode_loudness_info(AACDecContext *ac, AACUSACLoudnessInfo *info,
+ GetBitContext *gb)
+{
+ info->drc_set_id = get_bits(gb, 6);
+ info->downmix_id = get_bits(gb, 7);
+
+ if ((info->sample_peak.present = get_bits1(gb))) /* samplePeakLevelPresent */
+ info->sample_peak.lvl = get_bits(gb, 12);
+
+ if ((info->true_peak.present = get_bits1(gb))) { /* truePeakLevelPresent */
+ info->true_peak.lvl = get_bits(gb, 12);
+ info->true_peak.measurement = get_bits(gb, 4);
+ info->true_peak.reliability = get_bits(gb, 2);
+ }
+
+ info->nb_measurements = get_bits(gb, 4);
+ for (int i = 0; i < info->nb_measurements; i++) {
+ info->measurements[i].method_def = get_bits(gb, 4);
+ info->measurements[i].method_val = get_unary(gb, 0, 8);
+ info->measurements[i].measurement = get_bits(gb, 4);
+ info->measurements[i].reliability = get_bits(gb, 2);
+ }
+
+ return 0;
+}
+
+static int decode_loudness_set(AACDecContext *ac, AACUSACConfig *usac,
+ GetBitContext *gb)
+{
+ int ret;
+
+ usac->loudness.nb_album = get_bits(gb, 6); /* loudnessInfoAlbumCount */
+ usac->loudness.nb_info = get_bits(gb, 6); /* loudnessInfoCount */
+
+ for (int i = 0; i < usac->loudness.nb_album; i++) {
+ ret = decode_loudness_info(ac, &usac->loudness.album_info[i], gb);
+ if (ret < 0)
+ return ret;
+ }
+
+ for (int i = 0; i < usac->loudness.nb_info; i++) {
+ ret = decode_loudness_info(ac, &usac->loudness.info[i], gb);
+ if (ret < 0)
+ return ret;
+ }
+
+ if (get_bits1(gb)) { /* loudnessInfoSetExtPresent */
+ enum AACUSACLoudnessExt type;
+ while ((type = get_bits(gb, 4)) != UNIDRCLOUDEXT_TERM) {
+ uint8_t size_bits = get_bits(gb, 4) + 4;
+ uint8_t bit_size = get_bits(gb, size_bits) + 1;
+ switch (type) {
+ case UNIDRCLOUDEXT_EQ:
+ avpriv_report_missing_feature(ac->avctx, "loudnessInfoV1");
+ return AVERROR_PATCHWELCOME;
+ default:
+ for (int i = 0; i < bit_size; i++)
+ skip_bits1(gb);
+ }
+ }
+ }
+
+ return 0;
+}
+
+static void decode_usac_sbr_data(AACUsacElemConfig *e, GetBitContext *gb)
+{
+ uint8_t header_extra1;
+ uint8_t header_extra2;
+
+ e->sbr.harmonic_sbr = get_bits1(gb); /* harmonicSBR */
+ e->sbr.bs_intertes = get_bits1(gb); /* bs_interTes */
+ e->sbr.bs_pvc = get_bits1(gb); /* bs_pvc */
+
+ e->sbr.dflt.start_freq = get_bits(gb, 4); /* dflt_start_freq */
+ e->sbr.dflt.stop_freq = get_bits(gb, 4); /* dflt_stop_freq */
+
+ header_extra1 = get_bits1(gb); /* dflt_header_extra1 */
+ header_extra2 = get_bits1(gb); /* dflt_header_extra2 */
+
+ e->sbr.dflt.freq_scale = 2;
+ e->sbr.dflt.alter_scale = 1;
+ e->sbr.dflt.noise_scale = 2;
+ if (header_extra1) {
+ e->sbr.dflt.freq_scale = get_bits(gb, 2); /* dflt_freq_scale */
+ e->sbr.dflt.alter_scale = get_bits1(gb); /* dflt_alter_scale */
+ e->sbr.dflt.noise_scale = get_bits(gb, 2); /* dflt_noise_scale */
+ }
+
+ e->sbr.dflt.limiter_bands = 2;
+ e->sbr.dflt.limiter_gains = 2;
+ e->sbr.dflt.interpol_freq = 1;
+ e->sbr.dflt.smoothing_mode = 1;
+ if (header_extra2) {
+ e->sbr.dflt.limiter_bands = get_bits(gb, 2); /* dflt_limiter_bands */
+ e->sbr.dflt.limiter_gains = get_bits(gb, 2); /* dflt_limiter_gains */
+ e->sbr.dflt.interpol_freq = get_bits1(gb); /* dflt_interpol_freq */
+ e->sbr.dflt.smoothing_mode = get_bits1(gb); /* dflt_smoothing_mode */
+ }
+}
+
+static void decode_usac_element_core(AACUsacElemConfig *e,
+ GetBitContext *gb,
+ int sbr_ratio)
+{
+ e->tw_mdct = get_bits1(gb); /* tw_mdct */
+ e->noise_fill = get_bits1(gb);
+ e->sbr.ratio = sbr_ratio;
+}
+
+static void decode_usac_element_pair(AACUsacElemConfig *e, GetBitContext *gb)
+{
+ e->stereo_config_index = 0;
+ if (e->sbr.ratio) {
+ decode_usac_sbr_data(e, gb);
+ e->stereo_config_index = get_bits(gb, 2);
+ }
+ if (e->stereo_config_index) {
+ e->mps.freq_res = get_bits(gb, 3); /* bsFreqRes */
+ e->mps.fixed_gain = get_bits(gb, 3); /* bsFixedGainDMX */
+ e->mps.temp_shape_config = get_bits(gb, 2); /* bsTempShapeConfig */
+ e->mps.decorr_config = get_bits(gb, 2); /* bsDecorrConfig */
+ e->mps.high_rate_mode = get_bits1(gb); /* bsHighRateMode */
+ e->mps.phase_coding = get_bits1(gb); /* bsPhaseCoding */
+
+ if (get_bits1(gb)) /* bsOttBandsPhasePresent */
+ e->mps.otts_bands_phase = get_bits(gb, 5); /* bsOttBandsPhase */
+
+ e->mps.residual_coding = e->stereo_config_index >= 2; /* bsResidualCoding */
+ if (e->mps.residual_coding) {
+ e->mps.residual_bands = get_bits(gb, 5); /* bsResidualBands */
+ e->mps.pseudo_lr = get_bits1(gb); /* bsPseudoLr */
+ }
+ if (e->mps.temp_shape_config == 2)
+ e->mps.env_quant_mode = get_bits1(gb); /* bsEnvQuantMode */
+ }
+}
+
+static int decode_usac_extension(AACDecContext *ac, AACUsacElemConfig *e,
+ GetBitContext *gb)
+{
+ int len = 0, ext_config_len;
+
+ e->ext.type = get_escaped_value(gb, 4, 8, 16); /* usacExtElementType */
+ ext_config_len = get_escaped_value(gb, 4, 8, 16); /* usacExtElementConfigLength */
+
+ if (get_bits1(gb)) /* usacExtElementDefaultLengthPresent */
+ len = get_escaped_value(gb, 8, 16, 0) + 1;
+
+ e->ext.default_len = len;
+ e->ext.payload_frag = get_bits1(gb); /* usacExtElementPayloadFrag */
+
+ av_log(ac->avctx, AV_LOG_DEBUG, "Extension present: type %i, len %i\n",
+ e->ext.type, ext_config_len);
+
+ switch (e->ext.type) {
+#if 0 /* Skip unsupported values */
+ case ID_EXT_ELE_MPEGS:
+ break;
+ case ID_EXT_ELE_SAOC:
+ break;
+ case ID_EXT_ELE_UNI_DRC:
+ break;
+#endif
+ case ID_EXT_ELE_FILL:
+ break; /* This is what the spec does */
+ case ID_EXT_ELE_AUDIOPREROLL:
+ /* No configuration needed - fallthrough (len should be 0) */
+ default:
+ skip_bits(gb, 8*ext_config_len);
+ break;
+ };
+
+ return 0;
+}
+
+int ff_aac_usac_reset_state(AACDecContext *ac, OutputConfiguration *oc)
+{
+ AACUSACConfig *usac = &oc->usac;
+ int elem_id[3 /* SCE, CPE, LFE */] = { 0, 0, 0 };
+
+ ChannelElement *che;
+ enum RawDataBlockType type;
+ int id, ch;
+
+ /* Initialize state */
+ for (int i = 0; i < usac->nb_elems; i++) {
+ AACUsacElemConfig *e = &usac->elems[i];
+ if (e->type != ID_USAC_SCE && e->type != ID_USAC_CPE)
+ continue;
+
+ if (e->type == ID_USAC_SCE) {
+ ch = 1;
+ type = TYPE_SCE;
+ id = elem_id[0]++;
+ } else {
+ ch = 2;
+ type = TYPE_CPE;
+ id = elem_id[1]++;
+ }
+
+ che = ff_aac_get_che(ac, type, id);
+ if (che) {
+ AACUsacStereo *us = &che->us;
+ memset(us, 0, sizeof(*us));
+
+ for (int j = 0; j < ch; j++) {
+ SingleChannelElement *sce = &che->ch[ch];
+ AACUsacElemData *ue = &sce->ue;
+
+ memset(ue, 0, sizeof(*ue));
+
+ if (!ch)
+ ue->noise.seed = 0x3039;
+ else
+ che->ch[1].ue.noise.seed = 0x10932;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/* UsacConfig */
+int ff_aac_usac_config_decode(AACDecContext *ac, AVCodecContext *avctx,
+ GetBitContext *gb, OutputConfiguration *oc,
+ int channel_config)
+{
+ int ret, idx;
+ uint8_t freq_idx;
+ uint8_t channel_config_idx;
+ int nb_elements;
+ int samplerate;
+ int sbr_ratio;
+ MPEG4AudioConfig *m4ac = &oc->m4ac;
+ AACUSACConfig *usac = &oc->usac;
+ int elem_id[3 /* SCE, CPE, LFE */];
+
+ uint8_t layout_map[MAX_ELEM_ID*4][3];
+
+ memset(usac, 0, sizeof(*usac));
+
+ freq_idx = get_bits(gb, 5); /* usacSamplingFrequencyIndex */
+ if (freq_idx == 0x1f) {
+ samplerate = get_bits(gb, 24); /* usacSamplingFrequency */
+
+ /* Try to match up an index for the custom sample rate.
+ * TODO: not sure if correct */
+ for (idx = 0; idx < /* FF_ARRAY_ELEMS(ff_aac_usac_samplerate) */ 32; idx++) {
+ if (ff_aac_usac_samplerate[idx] >= samplerate)
+ break;
+ }
+ idx = FFMIN(idx, /* FF_ARRAY_ELEMS(ff_aac_usac_samplerate) */ 32 - 1);
+ usac->rate_idx = idx;
+ } else {
+ samplerate = ff_aac_usac_samplerate[freq_idx];
+ if (samplerate < 0)
+ return AVERROR(EINVAL);
+ usac->rate_idx = freq_idx;
+ }
+
+ m4ac->sample_rate = avctx->sample_rate = samplerate;
+
+ usac->core_sbr_frame_len_idx = get_bits(gb, 3); /* coreSbrFrameLengthIndex */
+ m4ac->frame_length_short = usac->core_sbr_frame_len_idx == 0 ||
+ usac->core_sbr_frame_len_idx == 2;
+
+ usac->core_frame_len = (usac->core_sbr_frame_len_idx == 0 ||
+ usac->core_sbr_frame_len_idx == 2) ? 768 : 1024;
+
+ sbr_ratio = usac->core_sbr_frame_len_idx == 2 ? 2 :
+ usac->core_sbr_frame_len_idx == 3 ? 3 :
+ usac->core_sbr_frame_len_idx == 4 ? 1 :
+ 0;
+
+ channel_config_idx = get_bits(gb, 5); /* channelConfigurationIndex */
+ if (!channel_config_idx) {
+ /* UsacChannelConfig() */
+ uint8_t nb_channels = get_escaped_value(gb, 5, 8, 16); /* numOutChannels */
+ if (nb_channels >= 64)
+ return AVERROR(EINVAL);
+
+ av_channel_layout_uninit(&ac->oc[1].ch_layout);
+
+ ret = av_channel_layout_custom_init(&ac->oc[1].ch_layout, nb_channels);
+ if (ret < 0)
+ return ret;
+
+ for (int i = 0; i < nb_channels; i++) {
+ AVChannelCustom *cm = &ac->oc[1].ch_layout.u.map[i];
+ cm->id = usac_ch_pos_to_av[get_bits(gb, 5)]; /* bsOutputChannelPos */
+ if (cm->id == AV_CHAN_NONE)
+ cm->id = AV_CHAN_UNKNOWN;
+ }
+
+ ret = av_channel_layout_retype(&ac->oc[1].ch_layout,
+ AV_CHANNEL_ORDER_NATIVE,
+ AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL);
+ if (ret < 0)
+ return ret;
+
+ ret = av_channel_layout_copy(&avctx->ch_layout, &ac->oc[1].ch_layout);
+ if (ret < 0)
+ return ret;
+ } else {
+ if ((ret = ff_aac_set_default_channel_config(ac, avctx, layout_map,
+ &nb_elements, channel_config_idx)))
+ return ret;
+ }
+
+ /* UsacDecoderConfig */
+ elem_id[0] = elem_id[1] = elem_id[2] = 0;
+ usac->nb_elems = get_escaped_value(gb, 4, 8, 16) + 1;
+
+ for (int i = 0; i < usac->nb_elems; i++) {
+ AACUsacElemConfig *e = &usac->elems[i];
+ memset(e, 0, sizeof(*e));
+
+ e->type = get_bits(gb, 2); /* usacElementType */
+ av_log(ac->avctx, AV_LOG_DEBUG, "Element present: idx %i, type %i\n",
+ i, e->type);
+
+ switch (e->type) {
+ case ID_USAC_SCE: /* SCE */
+ /* UsacCoreConfig */
+ decode_usac_element_core(e, gb, sbr_ratio);
+ if (e->sbr.ratio > 0)
+ decode_usac_sbr_data(e, gb);
+ layout_map[i][0] = TYPE_SCE;
+ layout_map[i][1] = i;
+ layout_map[i][2] = AAC_CHANNEL_FRONT;
+ elem_id[0]++;
+
+ break;
+ case ID_USAC_CPE: /* UsacChannelPairElementConf */
+ /* UsacCoreConfig */
+ decode_usac_element_core(e, gb, sbr_ratio);
+ decode_usac_element_pair(e, gb);
+ layout_map[i][0] = TYPE_CPE;
+ layout_map[i][1] = i;
+ layout_map[i][2] = AAC_CHANNEL_FRONT;
+ elem_id[1]++;
+
+ break;
+ case ID_USAC_LFE: /* LFE */
+ /* LFE has no need for any configuration */
+ e->tw_mdct = 0;
+ e->noise_fill = 0;
+ elem_id[2]++;
+ break;
+ case ID_USAC_EXT: /* EXT */
+ ret = decode_usac_extension(ac, e, gb);
+ if (ret < 0)
+ return ret;
+ break;
+ };
+ }
+
+ ret = ff_aac_output_configure(ac, layout_map, elem_id[0] + elem_id[1] + elem_id[2], OC_GLOBAL_HDR, 0);
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Unable to parse channel config!\n");
+ return ret;
+ }
+
+ if (get_bits1(gb)) { /* usacConfigExtensionPresent */
+ int invalid;
+ int nb_extensions = get_escaped_value(gb, 2, 4, 8) + 1; /* numConfigExtensions */
+ for (int i = 0; i < nb_extensions; i++) {
+ int type = get_escaped_value(gb, 4, 8, 16);
+ int len = get_escaped_value(gb, 4, 8, 16);
+ switch (type) {
+ case ID_CONFIG_EXT_LOUDNESS_INFO:
+ ret = decode_loudness_set(ac, usac, gb);
+ if (ret < 0)
+ return ret;
+ break;
+ case ID_CONFIG_EXT_STREAM_ID:
+ usac->stream_identifier = get_bits(gb, 16);
+ break;
+ case ID_CONFIG_EXT_FILL: /* fallthrough */
+ invalid = 0;
+ while (len--) {
+ if (get_bits(gb, 8) != 0xA5)
+ invalid++;
+ }
+ if (invalid)
+ av_log(avctx, AV_LOG_WARNING, "Invalid fill bytes: %i\n",
+ invalid);
+ break;
+ default:
+ while (len--)
+ skip_bits(gb, 8);
+ break;
+ }
+ }
+ }
+
+ ret = ff_aac_usac_reset_state(ac, oc);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int decode_usac_scale_factors(AACDecContext *ac,
+ SingleChannelElement *sce,
+ GetBitContext *gb, uint8_t global_gain)
+{
+ IndividualChannelStream *ics = &sce->ics;
+
+ /* Decode all scalefactors. */
+ int offset_sf = global_gain;
+ for (int g = 0; g < ics->num_window_groups; g++) {
+ for (int sfb = 0; sfb < ics->max_sfb; sfb++) {
+ /* First coefficient is just the global gain */
+ if (!g && !sfb) {
+ /* The cannonical representation of quantized scalefactors
+ * in the spec is with 100 subtracted. */
+ sce->sfo[0] = offset_sf - 100;
+ continue;
+ }
+
+ offset_sf += get_vlc2(gb, ff_vlc_scalefactors, 7, 3) - SCALE_DIFF_ZERO;
+ if (offset_sf > 255U) {
+ av_log(ac->avctx, AV_LOG_ERROR,
+ "Scalefactor (%d) out of range.\n", offset_sf);
+ return AVERROR_INVALIDDATA;
+ }
+
+ sce->sfo[g*ics->max_sfb + sfb] = offset_sf - 100;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * Decode and dequantize arithmetically coded, uniformly quantized value
+ *
+ * @param coef array of dequantized, scaled spectral data
+ * @param sf array of scalefactors or intensity stereo positions
+ *
+ * @return Returns error status. 0 - OK, !0 - error
+ */
+static int decode_spectrum_and_dequant_ac(AACDecContext *s, float coef[1024],
+ GetBitContext *gb, const float sf[120],
+ AACArithState *state, int reset,
+ uint16_t len, uint16_t N)
+{
+ AACArith ac;
+ int i, a, b;
+ uint32_t c;
+
+ int gb_count;
+ GetBitContext gb2;
+
+ ff_aac_ac_init(&ac, gb);
+ c = ff_aac_ac_map_process(state, reset, N);
+
+ /* Backup reader for rolling back by 14 bits at the end */
+ gb2 = (GetBitContext)*gb;
+ gb_count = get_bits_count(&gb2);
+
+ for (i = 0; i < len/2; i++) {
+ /* MSB */
+ int lvl, esc_nb, m;
+ c = ff_aac_ac_get_context(state, c, i, N);
+ for (lvl=esc_nb=0;;) {
+ uint32_t pki = ff_aac_ac_get_pk(c + (esc_nb << 17));
+ m = ff_aac_ac_decode(&ac, &gb2, ff_aac_ac_msb_cdfs[pki],
+ FF_ARRAY_ELEMS(ff_aac_ac_msb_cdfs[pki]));
+ if (m < FF_AAC_AC_ESCAPE)
+ break;
+ lvl++;
+
+ /* Cargo-culted value. */
+ if (lvl > 23)
+ return AVERROR(EINVAL);
+
+ if ((esc_nb = lvl) > 7)
+ esc_nb = 7;
+ }
+
+ b = m >> 2;
+ a = m - (b << 2);
+
+ /* ARITH_STOP detection */
+ if (!m) {
+ if (esc_nb)
+ break;
+ a = b = 0;
+ }
+
+ /* LSB */
+ for (int l = lvl; l > 0; l--) {
+ int lsbidx = !a ? 1 : (!b ? 0 : 2);
+ uint8_t r = ff_aac_ac_decode(&ac, &gb2, ff_aac_ac_lsb_cdfs[lsbidx],
+ FF_ARRAY_ELEMS(ff_aac_ac_lsb_cdfs[lsbidx]));
+ a = (a << 1) | (r & 1);
+ b = (b << 1) | ((r >> 1) & 1);
+ }
+
+ /* Dequantize coeffs here */
+ coef[2*i + 0] = a * cbrt(a);
+ coef[2*i + 1] = b * cbrt(b);
+ ff_aac_ac_update_context(state, i, a, b);
+ }
+
+ if (len > 1) {
+ /* "Rewind" bitstream back by 14 bits */
+ int gb_count2 = get_bits_count(&gb2);
+ skip_bits(gb, gb_count2 - gb_count - 14);
+ } else {
+ *gb = gb2;
+ }
+
+ ff_aac_ac_finish(state, i, N);
+
+ for (; i < N/2; i++) {
+ coef[2*i + 0] = 0;
+ coef[2*i + 1] = 0;
+ }
+
+ /* Signs */
+ for (i = 0; i < len; i++) {
+ if (coef[i]) {
+ if (!get_bits1(gb)) /* s */
+ coef[i] *= -1;
+ }
+ }
+
+ return 0;
+}
+
+static int decode_usac_stereo_cplx(AACDecContext *ac, AACUsacStereo *us,
+ ChannelElement *cpe, GetBitContext *gb,
+ int num_window_groups, int indep_flag)
+{
+ int delta_code_time;
+ IndividualChannelStream *ics = &cpe->ch[0].ics;
+
+ if (!get_bits1(gb)) { /* cplx_pred_all */
+ for (int g = 0; g < num_window_groups; g++) {
+ for (int sfb = 0; sfb < cpe->max_sfb_ste; sfb += SFB_PER_PRED_BAND) {
+ const uint8_t val = get_bits1(gb);
+ us->pred_used[g*cpe->max_sfb_ste + sfb] = val;
+ if ((sfb + 1) < cpe->max_sfb_ste)
+ us->pred_used[g*cpe->max_sfb_ste + sfb + 1] = val;
+ }
+ }
+ } else {
+ for (int g = 0; g < num_window_groups; g++)
+ for (int sfb = 0; sfb < cpe->max_sfb_ste; sfb++)
+ us->pred_used[g*cpe->max_sfb_ste + sfb] = 1;
+ }
+
+ us->pred_dir = get_bits1(gb);
+ us->complex_coef = get_bits1(gb);
+
+ us->use_prev_frame = 0;
+ if (us->complex_coef && !indep_flag)
+ us->use_prev_frame = get_bits1(gb);
+
+ delta_code_time = 0;
+ if (!indep_flag)
+ delta_code_time = get_bits1(gb);
+
+ /* TODO: shouldn't be needed */
+ for (int g = 0; g < num_window_groups; g++) {
+ for (int sfb = 0; sfb < cpe->max_sfb_ste; sfb += SFB_PER_PRED_BAND) {
+ float last_alpha_q_re = 0;
+ float last_alpha_q_im = 0;
+ if (delta_code_time) {
+ if (g) {
+ last_alpha_q_re = us->prev_alpha_q_re[(g - 1)*cpe->max_sfb_ste + sfb];
+ last_alpha_q_im = us->prev_alpha_q_im[(g - 1)*cpe->max_sfb_ste + sfb];
+ } else if ((ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) &&
+ ics->window_sequence[1] == EIGHT_SHORT_SEQUENCE ||
+ ics->window_sequence[1] == EIGHT_SHORT_SEQUENCE) {
+ /* The spec doesn't explicitly mention this, but it doesn't make
+ * any other sense otherwise! */
+ last_alpha_q_re = us->prev_alpha_q_re[7*cpe->max_sfb_ste + sfb];
+ last_alpha_q_im = us->prev_alpha_q_im[7*cpe->max_sfb_ste + sfb];
+ } else {
+ last_alpha_q_re = us->prev_alpha_q_re[g*cpe->max_sfb_ste + sfb];
+ last_alpha_q_im = us->prev_alpha_q_im[g*cpe->max_sfb_ste + sfb];
+ }
+ } else {
+ if (sfb) {
+ last_alpha_q_re = us->alpha_q_re[g*cpe->max_sfb_ste + sfb - 1];
+ last_alpha_q_im = us->alpha_q_im[g*cpe->max_sfb_ste + sfb - 1];
+ }
+ }
+
+ if (us->pred_used[g*cpe->max_sfb_ste + sfb]) {
+ int val = -get_vlc2(gb, ff_vlc_scalefactors, 7, 3) + 60;
+ last_alpha_q_re += val * 0.1f;
+ if (us->complex_coef) {
+ val = -get_vlc2(gb, ff_vlc_scalefactors, 7, 3) + 60;
+ last_alpha_q_im += val * 0.1f;
+ }
+ us->alpha_q_re[g*cpe->max_sfb_ste + sfb] = last_alpha_q_re;
+ us->alpha_q_im[g*cpe->max_sfb_ste + sfb] = last_alpha_q_im;
+ } else {
+ us->alpha_q_re[g*cpe->max_sfb_ste + sfb] = 0;
+ us->alpha_q_im[g*cpe->max_sfb_ste + sfb] = 0;
+ }
+
+ if ((sfb + 1) < cpe->max_sfb_ste) {
+ us->alpha_q_re[g*cpe->max_sfb_ste + sfb + 1] =
+ us->alpha_q_re[g*cpe->max_sfb_ste + sfb];
+ us->alpha_q_im[g*cpe->max_sfb_ste + sfb + 1] =
+ us->alpha_q_im[g*cpe->max_sfb_ste + sfb];
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int setup_sce(AACDecContext *ac, SingleChannelElement *sce,
+ AACUSACConfig *usac)
+{
+ AACUsacElemData *ue = &sce->ue;
+ IndividualChannelStream *ics = &sce->ics;
+
+ /* Setup window parameters */
+ if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
+ if (usac->core_frame_len == 768) {
+ ics->swb_offset = ff_swb_offset_96[usac->rate_idx];
+ ics->num_swb = ff_aac_num_swb_96[usac->rate_idx];
+ } else {
+ ics->swb_offset = ff_swb_offset_128[usac->rate_idx];
+ ics->num_swb = ff_aac_num_swb_128[usac->rate_idx];
+ }
+ ics->tns_max_bands = ff_tns_max_bands_128[usac->rate_idx];
+
+ /* Setup scalefactor grouping. 7 bit mask. */
+ ics->num_window_groups = 0;
+ for (int j = 0; j < 7; j++) {
+ ics->group_len[j] = 1;
+ if (ue->scale_factor_grouping & (1 << (6 - j)))
+ ics->group_len[ics->num_window_groups] += 1;
+ else
+ ics->num_window_groups++;
+ }
+
+ ics->group_len[7] = 1;
+ ics->num_window_groups++;
+ ics->num_windows = 8;
+ } else {
+ if (usac->core_frame_len == 768) {
+ ics->swb_offset = ff_swb_offset_768[usac->rate_idx];
+ ics->num_swb = ff_aac_num_swb_768[usac->rate_idx];
+ } else {
+ ics->swb_offset = ff_swb_offset_1024[usac->rate_idx];
+ ics->num_swb = ff_aac_num_swb_1024[usac->rate_idx];
+ }
+ ics->tns_max_bands = ff_tns_max_bands_1024[usac->rate_idx];
+
+ ics->group_len[0] = 1;
+ ics->num_window_groups = 1;
+ ics->num_windows = 1;
+ }
+
+ if (ics->max_sfb > ics->num_swb) {
+ av_log(ac->avctx, AV_LOG_ERROR,
+ "Number of scalefactor bands in group (%d) "
+ "exceeds limit (%d).\n",
+ ics->max_sfb, ics->num_swb);
+ return AVERROR(EINVAL);
+ }
+
+ /* Just some defaults for the band types */
+ for (int i = 0; i < FF_ARRAY_ELEMS(sce->band_type); i++)
+ sce->band_type[i] = ESC_BT;
+
+ return 0;
+}
+
+static int decode_usac_stereo_info(AACDecContext *ac, AACUSACConfig *usac,
+ AACUsacElemConfig *ec, ChannelElement *cpe,
+ GetBitContext *gb, int indep_flag)
+{
+ int ret, tns_active;
+
+ AACUsacStereo *us = &cpe->us;
+ SingleChannelElement *sce1 = &cpe->ch[0];
+ SingleChannelElement *sce2 = &cpe->ch[1];
+ IndividualChannelStream *ics1 = &sce1->ics;
+ IndividualChannelStream *ics2 = &sce2->ics;
+ AACUsacElemData *ue1 = &sce1->ue;
+ AACUsacElemData *ue2 = &sce2->ue;
+
+ us->common_window = 0;
+ us->common_tw = 0;
+
+ if (!(!ue1->core_mode && !ue2->core_mode))
+ return 0;
+
+ tns_active = get_bits1(gb);
+ us->common_window = get_bits1(gb);
+
+ if (us->common_window) {
+ /* ics_info() */
+ ics1->window_sequence[1] = ics1->window_sequence[0];
+ ics2->window_sequence[1] = ics2->window_sequence[0];
+ ics1->window_sequence[0] = ics2->window_sequence[0] = get_bits(gb, 2);
+
+ ics1->use_kb_window[1] = ics1->use_kb_window[0];
+ ics2->use_kb_window[1] = ics2->use_kb_window[0];
+ ics1->use_kb_window[0] = ics2->use_kb_window[0] = get_bits1(gb);
+
+ if (ics1->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
+ ics1->max_sfb = ics2->max_sfb = get_bits(gb, 4);
+ ue1->scale_factor_grouping = ue2->scale_factor_grouping = get_bits(gb, 7);
+ } else {
+ ics1->max_sfb = ics2->max_sfb = get_bits(gb, 6);
+ }
+
+ if (!get_bits1(gb)) { /* common_max_sfb */
+ if (ics2->window_sequence[0] == EIGHT_SHORT_SEQUENCE)
+ ics2->max_sfb = get_bits(gb, 4);
+ else
+ ics2->max_sfb = get_bits(gb, 6);
+ }
+
+ ret = setup_sce(ac, sce1, usac);
+ if (ret < 0)
+ return ret;
+
+ ret = setup_sce(ac, sce2, usac);
+ if (ret < 0)
+ return ret;
+
+ cpe->max_sfb_ste = FFMAX(ics1->max_sfb, ics2->max_sfb);
+
+ us->ms_mask_mode = get_bits(gb, 2); /* ms_mask_present */
+ memset(cpe->ms_mask, 0, sizeof(cpe->ms_mask));
+ if (us->ms_mask_mode == 1) {
+ for (int g = 0; g < ics1->num_window_groups; g++)
+ for (int sfb = 0; sfb < cpe->max_sfb_ste; sfb++)
+ cpe->ms_mask[g*cpe->max_sfb_ste + sfb] = get_bits1(gb);
+ } else if (us->ms_mask_mode == 2) {
+ memset(cpe->ms_mask, 0xFF, sizeof(cpe->ms_mask));
+ } else if ((us->ms_mask_mode == 3) && !ec->stereo_config_index) {
+ ret = decode_usac_stereo_cplx(ac, us, cpe, gb,
+ ics1->num_window_groups, indep_flag);
+ if (ret < 0)
+ return ret;
+ }
+ }
+
+ if (ec->tw_mdct) {
+ us->common_tw = get_bits1(gb);
+ avpriv_report_missing_feature(ac->avctx,
+ "AAC USAC timewarping");
+ return AVERROR_PATCHWELCOME;
+ }
+
+ sce1->tns.present = sce2->tns.present = 0;
+ if (tns_active) {
+ av_unused int tns_on_lr;
+ int common_tns = 0;
+ if (us->common_window)
+ common_tns = get_bits1(gb);
+
+ tns_on_lr = get_bits1(gb);
+ if (common_tns) {
+ ret = ff_aac_decode_tns(ac, &sce1->tns, gb, ics1);
+ if (ret < 0)
+ return ret;
+ memcpy(&sce2->tns, &sce1->tns, sizeof(sce1->tns));
+ sce2->tns.present = 0;
+ sce1->tns.present = 0;
+ } else {
+ if (get_bits1(gb)) {
+ sce2->tns.present = 1;
+ sce1->tns.present = 1;
+ } else {
+ sce2->tns.present = get_bits1(gb);
+ sce1->tns.present = !sce2->tns.present;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/* 7.2.4 Generation of random signs for spectral noise filling
+ * This function is exactly defined, though we've helped the definition
+ * along with being slightly faster. */
+static inline float noise_random_sign(unsigned int *seed)
+{
+ unsigned int new_seed = *seed = ((*seed) * 69069) + 5;
+ if (((new_seed) & 0x10000) > 0)
+ return -1.f;
+ return +1.f;
+}
+
+static void apply_noise_fill(AACDecContext *ac, SingleChannelElement *sce,
+ AACUsacElemData *ue)
+{
+ float *coef;
+ IndividualChannelStream *ics = &sce->ics;
+
+ float noise_val = pow(2, (ue->noise.level - 14)/3);
+ int noise_offset = ue->noise.offset - 16;
+ int band_off;
+
+ band_off = ff_usac_noise_fill_start_offset[ac->oc[1].m4ac.frame_length_short]
+ [ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE];
+
+ coef = sce->coeffs;
+ for (int g = 0; g < ics->num_window_groups; g++) {
+ unsigned g_len = ics->group_len[g];
+
+ for (int sfb = 0; sfb < ics->max_sfb; sfb++) {
+ float *cb = coef + ics->swb_offset[sfb];
+ int cb_len = ics->swb_offset[sfb + 1] - ics->swb_offset[sfb];
+ int band_quantized_to_zero = 1;
+
+ if (ics->swb_offset[sfb] < band_off)
+ continue;
+
+ for (int group = 0; group < (unsigned)g_len; group++, cb += 128) {
+ for (int z = 0; z < cb_len; z++) {
+ if (cb[z] == 0)
+ cb[z] = noise_random_sign(&sce->ue.noise.seed) * noise_val;
+ else
+ band_quantized_to_zero = 0;
+ }
+ }
+
+ if (band_quantized_to_zero)
+ sce->sf[g*ics->max_sfb + sfb] += noise_offset;
+ }
+ coef += g_len << 7;
+ }
+}
+
+static void spectrum_scale(AACDecContext *ac, SingleChannelElement *sce,
+ AACUsacElemData *ue)
+{
+ IndividualChannelStream *ics = &sce->ics;
+ float *coef;
+
+ /* Synthesise noise */
+ if (ue->noise.level)
+ apply_noise_fill(ac, sce, ue);
+
+ /* Apply scalefactors */
+ coef = sce->coeffs;
+ for (int g = 0; g < ics->num_window_groups; g++) {
+ unsigned g_len = ics->group_len[g];
+
+ for (int sfb = 0; sfb < ics->max_sfb; sfb++) {
+ float *cb = coef + ics->swb_offset[sfb];
+ int cb_len = ics->swb_offset[sfb + 1] - ics->swb_offset[sfb];
+ float sf = sce->sf[g*ics->max_sfb + sfb];
+
+ for (int group = 0; group < (unsigned)g_len; group++, cb += 128)
+ ac->fdsp->vector_fmul_scalar(cb, cb, sf, cb_len);
+ }
+ coef += g_len << 7;
+ }
+}
+
+static void complex_stereo_downmix_prev(AACDecContext *ac, ChannelElement *cpe,
+ float *dmix_re)
+{
+ IndividualChannelStream *ics = &cpe->ch[0].ics;
+ int sign = !cpe->us.pred_dir ? +1 : -1;
+ float *coef1 = cpe->ch[0].coeffs;
+ float *coef2 = cpe->ch[1].coeffs;
+
+ for (int g = 0; g < ics->num_window_groups; g++) {
+ unsigned g_len = ics->group_len[g];
+ for (int sfb = 0; sfb < cpe->max_sfb_ste; sfb++) {
+ int off = ics->swb_offset[sfb];
+ int cb_len = ics->swb_offset[sfb + 1] - off;
+
+ float *c1 = coef1 + off;
+ float *c2 = coef2 + off;
+ float *dm = dmix_re + off;
+
+ for (int group = 0; group < (unsigned)g_len;
+ group++, c1 += 128, c2 += 128, dm += 128) {
+ for (int z = 0; z < cb_len; z++)
+ dm[z] = 0.5*(c1[z] + sign*c2[z]);
+ }
+ }
+
+ coef1 += g_len << 7;
+ coef2 += g_len << 7;
+ dmix_re += g_len << 7;
+ }
+}
+
+static void complex_stereo_downmix_cur(AACDecContext *ac, ChannelElement *cpe,
+ float *dmix_re)
+{
+ AACUsacStereo *us = &cpe->us;
+ IndividualChannelStream *ics = &cpe->ch[0].ics;
+ int sign = !cpe->us.pred_dir ? +1 : -1;
+ float *coef1 = cpe->ch[0].coeffs;
+ float *coef2 = cpe->ch[1].coeffs;
+
+ for (int g = 0; g < ics->num_window_groups; g++) {
+ unsigned g_len = ics->group_len[g];
+ for (int sfb = 0; sfb < cpe->max_sfb_ste; sfb++) {
+ int off = ics->swb_offset[sfb];
+ int cb_len = ics->swb_offset[sfb + 1] - off;
+
+ float *c1 = coef1 + off;
+ float *c2 = coef2 + off;
+ float *dm = dmix_re + off;
+
+ if (us->pred_used[g*cpe->max_sfb_ste + sfb]) {
+ for (int group = 0; group < (unsigned)g_len;
+ group++, c1 += 128, c2 += 128, dm += 128) {
+ for (int z = 0; z < cb_len; z++)
+ dm[z] = 0.5*(c1[z] + sign*c2[z]);
+ }
+ } else {
+ for (int group = 0; group < (unsigned)g_len;
+ group++, c1 += 128, c2 += 128, dm += 128) {
+ for (int z = 0; z < cb_len; z++)
+ dm[z] = c1[z];
+ }
+ }
+ }
+
+ coef1 += g_len << 7;
+ coef2 += g_len << 7;
+ dmix_re += g_len << 7;
+ }
+}
+
+static void complex_stereo_interpolate_imag(float *im, float *re, const float f[6],
+ int len, int factor_even, int factor_odd)
+{
+ int i = 0;
+ float s;
+
+ s = f[6]*re[2] + f[5]*re[1] + f[4]*re[0] +
+ f[3]*re[0] +
+ f[2]*re[1] + f[1]*re[2] + f[0]*re[3];
+ im[i] += s*factor_even;
+
+ i = 1;
+ s = f[6]*re[1] + f[5]*re[0] + f[4]*re[0] +
+ f[3]*re[1] +
+ f[2]*re[2] + f[1]*re[3] + f[0]*re[4];
+ im[i] += s*factor_odd;
+
+ i = 2;
+ s = f[6]*re[0] + f[5]*re[0] + f[4]*re[1] +
+ f[3]*re[2] +
+ f[2]*re[3] + f[1]*re[4] + f[0]*re[5];
+
+ im[i] += s*factor_even;
+ for (i = 3; i < len - 4; i += 2) {
+ s = f[6]*re[i-3] + f[5]*re[i-2] + f[4]*re[i-1] +
+ f[3]*re[i] +
+ f[2]*re[i+1] + f[1]*re[i+2] + f[0]*re[i+3];
+ im[i+0] += s*factor_odd;
+
+ s = f[6]*re[i-2] + f[5]*re[i-1] + f[4]*re[i] +
+ f[3]*re[i+1] +
+ f[2]*re[i+2] + f[1]*re[i+3] + f[0]*re[i+4];
+ im[i+1] += s*factor_even;
+ }
+
+ i = len - 3;
+ s = f[6]*re[i-3] + f[5]*re[i-2] + f[4]*re[i-1] +
+ f[3]*re[i] +
+ f[2]*re[i+1] + f[1]*re[i+2] + f[0]*re[i+2];
+ im[i] += s*factor_odd;
+
+ i = len - 2;
+ s = f[6]*re[i-3] + f[5]*re[i-2] + f[4]*re[i-1] +
+ f[3]*re[i] +
+ f[2]*re[i+1] + f[1]*re[i+1] + f[0]*re[i];
+ im[i] += s*factor_even;
+
+ i = len - 1;
+ s = f[6]*re[i-3] + f[5]*re[i-2] + f[4]*re[i-1] +
+ f[3]*re[i] +
+ f[2]*re[i] + f[1]*re[i-1] + f[0]*re[i-2];
+ im[i] += s*factor_odd;
+}
+
+static void apply_complex_stereo(AACDecContext *ac, ChannelElement *cpe)
+{
+ AACUsacStereo *us = &cpe->us;
+ IndividualChannelStream *ics = &cpe->ch[0].ics;
+ float *coef1 = cpe->ch[0].coeffs;
+ float *coef2 = cpe->ch[1].coeffs;
+ float *dmix_im = us->dmix_im;
+
+ for (int g = 0; g < ics->num_window_groups; g++) {
+ unsigned g_len = ics->group_len[g];
+ for (int sfb = 0; sfb < cpe->max_sfb_ste; sfb++) {
+ int off = ics->swb_offset[sfb];
+ int cb_len = ics->swb_offset[sfb + 1] - off;
+
+ float *c1 = coef1 + off;
+ float *c2 = coef2 + off;
+ float *dm_im = dmix_im + off;
+ float alpha_re = us->alpha_q_re[g*cpe->max_sfb_ste + sfb];
+ float alpha_im = us->alpha_q_im[g*cpe->max_sfb_ste + sfb];
+
+ if (!us->pred_used[g*cpe->max_sfb_ste + sfb])
+ continue;
+
+ if (!cpe->us.pred_dir) {
+ for (int group = 0; group < (unsigned)g_len;
+ group++, c1 += 128, c2 += 128, dm_im += 128) {
+ for (int z = 0; z < cb_len; z++) {
+ float side;
+ side = c2[z] - alpha_re*c1[z] - alpha_im*dm_im[z];
+ c2[z] = c1[z] - side;
+ c1[z] = c1[z] + side;
+ }
+ }
+ } else {
+ for (int group = 0; group < (unsigned)g_len;
+ group++, c1 += 128, c2 += 128, dm_im += 128) {
+ for (int z = 0; z < cb_len; z++) {
+ float mid;
+ mid = c2[z] - alpha_re*c1[z] - alpha_im*dm_im[z];
+ c2[z] = mid - c1[z];
+ c1[z] = mid + c1[z];
+ }
+ }
+ }
+ }
+
+ coef1 += g_len << 7;
+ coef2 += g_len << 7;
+ dmix_im += g_len << 7;
+ }
+}
+
+static const float *complex_stereo_get_filter(ChannelElement *cpe, int is_prev)
+{
+ int win, shape;
+ if (!is_prev) {
+ switch (cpe->ch[0].ics.window_sequence[0]) {
+ default:
+ case ONLY_LONG_SEQUENCE:
+ case EIGHT_SHORT_SEQUENCE:
+ win = 0;
+ break;
+ case LONG_START_SEQUENCE:
+ win = 1;
+ break;
+ case LONG_STOP_SEQUENCE:
+ win = 2;
+ break;
+ }
+
+ if (cpe->ch[0].ics.use_kb_window[0] == 0 &&
+ cpe->ch[0].ics.use_kb_window[1] == 0)
+ shape = 0;
+ else if (cpe->ch[0].ics.use_kb_window[0] == 1 &&
+ cpe->ch[0].ics.use_kb_window[1] == 1)
+ shape = 1;
+ else if (cpe->ch[0].ics.use_kb_window[0] == 0 &&
+ cpe->ch[0].ics.use_kb_window[1] == 1)
+ shape = 2;
+ else if (cpe->ch[0].ics.use_kb_window[0] == 1 &&
+ cpe->ch[0].ics.use_kb_window[1] == 0)
+ shape = 3;
+ else
+ shape = 3;
+ } else {
+ win = cpe->ch[0].ics.window_sequence[0] == LONG_STOP_SEQUENCE;
+ shape = cpe->ch[0].ics.use_kb_window[1];
+ }
+
+ return ff_aac_usac_mdst_filt_cur[win][shape];
+}
+
+static void spectrum_decode(AACDecContext *ac, AACUSACConfig *usac,
+ ChannelElement *cpe, int nb_channels)
+{
+ AACUsacStereo *us = &cpe->us;
+
+ for (int ch = 0; ch < nb_channels; ch++) {
+ SingleChannelElement *sce = &cpe->ch[ch];
+ AACUsacElemData *ue = &sce->ue;
+
+ spectrum_scale(ac, sce, ue);
+ }
+
+ if (nb_channels > 1 && us->common_window) {
+ if (us->ms_mask_mode == 3) {
+ const float *filt;
+ complex_stereo_downmix_cur(ac, cpe, us->dmix_re);
+ complex_stereo_downmix_prev(ac, cpe, us->prev_dmix_re);
+
+ filt = complex_stereo_get_filter(cpe, 0);
+ complex_stereo_interpolate_imag(us->dmix_im, us->dmix_re, filt,
+ usac->core_frame_len, 1, 1);
+ if (us->use_prev_frame) {
+ filt = complex_stereo_get_filter(cpe, 1);
+ complex_stereo_interpolate_imag(us->dmix_im, us->prev_dmix_re, filt,
+ usac->core_frame_len, -1, 1);
+ }
+
+ apply_complex_stereo(ac, cpe);
+ } else if (us->ms_mask_mode > 0) {
+ ac->dsp.apply_mid_side_stereo(ac, cpe);
+ }
+ }
+
+ /* Save coefficients and alpha values for prediction reasons */
+ if (nb_channels > 1) {
+ AACUsacStereo *us = &cpe->us;
+ for (int ch = 0; ch < nb_channels; ch++) {
+ SingleChannelElement *sce = &cpe->ch[ch];
+ memcpy(sce->prev_coeffs, sce->coeffs, sizeof(sce->coeffs));
+ }
+ memcpy(us->prev_alpha_q_re, us->alpha_q_re, sizeof(us->alpha_q_re));
+ memcpy(us->prev_alpha_q_im, us->alpha_q_im, sizeof(us->alpha_q_im));
+ }
+
+ for (int ch = 0; ch < nb_channels; ch++) {
+ SingleChannelElement *sce = &cpe->ch[ch];
+
+ /* Apply TNS */
+ if (sce->tns.present)
+ ac->dsp.apply_tns(sce->coeffs, &sce->tns, &sce->ics, 1);
+
+ ac->oc[1].m4ac.frame_length_short ? ac->dsp.imdct_and_windowing_768(ac, sce) :
+ ac->dsp.imdct_and_windowing(ac, sce);
+ }
+}
+
+static int decode_usac_core_coder(AACDecContext *ac, AACUSACConfig *usac,
+ AACUsacElemConfig *ec, ChannelElement *che,
+ GetBitContext *gb, int indep_flag, int nb_channels)
+{
+ int ret;
+ int arith_reset_flag;
+ AACUsacStereo *us = &che->us;
+
+ /* Local symbols */
+ uint8_t global_gain;
+
+ us->common_window = 0;
+ che->ch[0].tns.present = che->ch[1].tns.present = 0;
+
+ for (int ch = 0; ch < nb_channels; ch++) {
+ SingleChannelElement *sce = &che->ch[ch];
+ AACUsacElemData *ue = &sce->ue;
+
+ ue->core_mode = get_bits1(gb);
+ }
+
+ if (nb_channels == 2) {
+ ret = decode_usac_stereo_info(ac, usac, ec, che, gb, indep_flag);
+ if (ret)
+ return ret;
+ }
+
+ for (int ch = 0; ch < nb_channels; ch++) {
+ SingleChannelElement *sce = &che->ch[ch];
+ IndividualChannelStream *ics = &sce->ics;
+ AACUsacElemData *ue = &sce->ue;
+
+ if (ue->core_mode) { /* lpd_channel_stream */
+ ret = ff_aac_ldp_parse_channel_stream(ac, usac, ue, gb);
+ if (ret < 0)
+ return ret;
+ }
+
+ if ((nb_channels == 1) ||
+ (che->ch[0].ue.core_mode != che->ch[1].ue.core_mode))
+ sce->tns.present = get_bits1(gb);
+
+ /* fd_channel_stream */
+ global_gain = get_bits(gb, 8);
+
+ ue->noise.level = 0;
+ if (ec->noise_fill) {
+ ue->noise.level = get_bits(gb, 3);
+ ue->noise.offset = get_bits(gb, 5);
+ }
+
+ if (!us->common_window) {
+ /* ics_info() */
+ ics->window_sequence[1] = ics->window_sequence[0];
+ ics->window_sequence[0] = get_bits(gb, 2);
+ ics->use_kb_window[1] = ics->use_kb_window[0];
+ ics->use_kb_window[0] = get_bits1(gb);
+ if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
+ ics->max_sfb = get_bits(gb, 4);
+ ue->scale_factor_grouping = get_bits(gb, 7);
+ } else {
+ ics->max_sfb = get_bits(gb, 6);
+ }
+
+ ret = setup_sce(ac, sce, usac);
+ if (ret < 0)
+ return ret;
+ }
+
+ if (ec->tw_mdct && !us->common_tw) {
+ /* tw_data() */
+ if (get_bits1(gb)) { /* tw_data_present */
+ /* Time warping is not supported in baseline profile streams. */
+ avpriv_report_missing_feature(ac->avctx,
+ "AAC USAC timewarping");
+ return AVERROR_PATCHWELCOME;
+ }
+ }
+
+ ret = decode_usac_scale_factors(ac, sce, gb, global_gain);
+ if (ret < 0)
+ return ret;
+
+ ac->dsp.dequant_scalefactors(sce);
+
+ if (sce->tns.present) {
+ ret = ff_aac_decode_tns(ac, &sce->tns, gb, ics);
+ if (ret < 0)
+ return ret;
+ }
+
+ /* ac_spectral_data */
+ arith_reset_flag = indep_flag;
+ if (!arith_reset_flag)
+ arith_reset_flag = get_bits1(gb);
+
+ /* Decode coeffs */
+ memset(&sce->coeffs[0], 0, 1024*sizeof(float));
+ for (int win = 0; win < ics->num_windows; win++) {
+ int lg = ics->swb_offset[ics->max_sfb];
+ int N;
+ if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE)
+ N = usac->core_frame_len / 8;
+ else
+ N = usac->core_frame_len;
+
+ ret = decode_spectrum_and_dequant_ac(ac, sce->coeffs + win*128, gb,
+ sce->sf, &ue->ac,
+ arith_reset_flag && (win == 0),
+ lg, N);
+ if (ret < 0)
+ return ret;
+ }
+
+ if (get_bits1(gb)) { /* fac_data_present */
+ const uint16_t len_8 = usac->core_frame_len / 8;
+ const uint16_t len_16 = usac->core_frame_len / 16;
+ const uint16_t fac_len = ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE ? len_8 : len_16;
+ ret = ff_aac_parse_fac_data(ue, gb, 1, fac_len);
+ if (ret < 0)
+ return ret;
+ }
+ }
+
+ spectrum_decode(ac, usac, che, nb_channels);
+
+ return 0;
+}
+
+static int parse_audio_preroll(AACDecContext *ac, GetBitContext *gb)
+{
+ int ret = 0;
+ GetBitContext gbc;
+ OutputConfiguration *oc = &ac->oc[1];
+ MPEG4AudioConfig *m4ac = &oc->m4ac;
+ MPEG4AudioConfig m4ac_bak = oc->m4ac;
+ uint8_t temp_data[512];
+ uint8_t *tmp_buf = temp_data;
+ size_t tmp_buf_size = sizeof(temp_data);
+
+ av_unused int crossfade;
+ int num_preroll_frames;
+
+ int config_len = get_escaped_value(gb, 4, 4, 8);
+
+ /* Implementations are free to pad the config to any length, so use a
+ * different reader for this. */
+ gbc = *gb;
+ ret = ff_aac_usac_config_decode(ac, ac->avctx, &gbc, oc, m4ac->chan_config);
+ if (ret < 0) {
+ *m4ac = m4ac_bak;
+ return ret;
+ } else {
+ ac->oc[1].m4ac.chan_config = 0;
+ }
+
+ /* 7.18.3.3 Bitrate adaption
+ * If configuration didn't change after applying preroll, continue
+ * without decoding it. */
+ if (!memcmp(m4ac, &m4ac_bak, sizeof(m4ac_bak)))
+ return 0;
+
+ skip_bits_long(gb, config_len*8);
+
+ crossfade = get_bits1(gb); /* applyCrossfade */
+ skip_bits1(gb); /* reserved */
+ num_preroll_frames = get_escaped_value(gb, 2, 4, 0); /* numPreRollFrames */
+
+ for (int i = 0; i < num_preroll_frames; i++) {
+ int got_frame_ptr = 0;
+ int au_len = get_escaped_value(gb, 16, 16, 0);
+
+ if (au_len*8 > tmp_buf_size) {
+ uint8_t *tmp2;
+ tmp_buf = tmp_buf == temp_data ? NULL : tmp_buf;
+ tmp2 = realloc(tmp_buf, au_len*8);
+ if (!tmp2) {
+ if (tmp_buf != temp_data)
+ av_free(tmp_buf);
+ return AVERROR(ENOMEM);
+ }
+ tmp_buf = tmp2;
+ }
+
+ /* Byte alignment is not guaranteed. */
+ for (int i = 0; i < au_len; i++)
+ tmp_buf[i] = get_bits(gb, 8);
+
+ ret = init_get_bits8(&gbc, tmp_buf, au_len);
+ if (ret < 0)
+ break;
+
+ ret = ff_aac_usac_decode_frame(ac->avctx, ac, &gbc, &got_frame_ptr);
+ if (ret < 0)
+ break;
+ }
+
+ if (tmp_buf != temp_data)
+ av_free(tmp_buf);
+
+ return 0;
+}
+
+static int parse_ext_ele(AACDecContext *ac, AACUsacElemConfig *e,
+ GetBitContext *gb)
+{
+ uint8_t *tmp;
+ uint8_t pl_frag_start = 1;
+ uint8_t pl_frag_end = 1;
+ uint32_t len;
+
+ if (!get_bits1(gb)) /* usacExtElementPresent */
+ return 0;
+
+ if (get_bits1(gb)) { /* usacExtElementUseDefaultLength */
+ len = e->ext.default_len;
+ } else {
+ len = get_bits(gb, 8); /* usacExtElementPayloadLength */
+ if (len == 255)
+ len += get_bits(gb, 16) - 2;
+ }
+
+ if (!len)
+ return 0;
+
+ if (e->ext.payload_frag) {
+ pl_frag_start = get_bits1(gb); /* usacExtElementStart */
+ pl_frag_end = get_bits1(gb); /* usacExtElementStop */
+ }
+
+ if (pl_frag_start)
+ e->ext.pl_data_offset = 0;
+
+ /* If an extension starts and ends this packet, we can directly use it */
+ if (!(pl_frag_start && pl_frag_end)) {
+ tmp = av_realloc(e->ext.pl_data, e->ext.pl_data_offset + len);
+ if (!tmp) {
+ av_free(e->ext.pl_data);
+ return AVERROR(ENOMEM);
+ }
+ e->ext.pl_data = tmp;
+
+ /* Readout data to a buffer */
+ for (int i = 0; i < len; i++)
+ e->ext.pl_data[e->ext.pl_data_offset + i] = get_bits(gb, 8);
+ }
+
+ e->ext.pl_data_offset += len;
+
+ if (pl_frag_end) {
+ int ret = 0;
+ int start_bits = get_bits_count(gb);
+ const int pl_len = e->ext.pl_data_offset;
+ GetBitContext *gb2 = gb;
+ GetBitContext gbc;
+ if (!(pl_frag_start && pl_frag_end)) {
+ ret = init_get_bits8(&gbc, e->ext.pl_data, pl_len);
+ if (ret < 0)
+ return ret;
+
+ gb2 = &gbc;
+ }
+
+ switch (e->ext.type) {
+ case ID_EXT_ELE_FILL:
+ /* Filler elements have no usable payload */
+ break;
+ case ID_EXT_ELE_AUDIOPREROLL:
+ ret = parse_audio_preroll(ac, gb2);
+ break;
+ default:
+ /* This should never happen */
+ av_assert0(0);
+ }
+ av_freep(&e->ext.pl_data);
+ if (ret < 0)
+ return ret;
+
+ skip_bits_long(gb, pl_len*8 - (get_bits_count(gb) - start_bits));
+ }
+
+ return 0;
+}
+
+int ff_aac_usac_decode_frame(AVCodecContext *avctx, AACDecContext *ac,
+ GetBitContext *gb, int *got_frame_ptr)
+{
+ int ret, nb_ch_el, is_dmono = 0;
+ int indep_flag, samples = 0;
+ int audio_found = 0, sce_count = 0;
+ AVFrame *frame = ac->frame;
+
+ ff_aac_output_configure(ac, ac->oc[1].layout_map, ac->oc[1].layout_map_tags,
+ ac->oc[1].status, 0);
+
+ indep_flag = get_bits1(gb);
+
+ nb_ch_el = 0;
+ for (int i = 0; i < ac->oc[1].usac.nb_elems; i++) {
+ AACUsacElemConfig *e = &ac->oc[1].usac.elems[i];
+ ChannelElement *che;
+
+ switch (e->type) {
+ case ID_USAC_LFE:
+ /* Fallthrough */
+ case ID_USAC_SCE:
+ che = ff_aac_get_che(ac, TYPE_SCE, nb_ch_el++);
+ if (!che) {
+ av_log(ac->avctx, AV_LOG_ERROR,
+ "channel element %d.%d is not allocated\n",
+ TYPE_SCE, nb_ch_el - 1);
+ return AVERROR_INVALIDDATA;
+ }
+
+ ret = decode_usac_core_coder(ac, &ac->oc[1].usac, e, che, gb,
+ indep_flag, 1);
+ if (ret < 0)
+ return ret;
+
+ sce_count++;
+ audio_found = 1;
+ che->present = 1;
+ samples = ac->oc[1].m4ac.frame_length_short ? 768 : 1024;
+ break;
+ case ID_USAC_CPE:
+ che = ff_aac_get_che(ac, TYPE_CPE, nb_ch_el++);
+ if (!che) {
+ av_log(ac->avctx, AV_LOG_ERROR,
+ "channel element %d.%d is not allocated\n",
+ TYPE_SCE, nb_ch_el - 1);
+ return AVERROR_INVALIDDATA;
+ }
+
+ ret = decode_usac_core_coder(ac, &ac->oc[1].usac, e, che, gb,
+ indep_flag, 2);
+ if (ret < 0)
+ return ret;
+
+ audio_found = 1;
+ che->present = 1;
+ samples = ac->oc[1].m4ac.frame_length_short ? 768 : 1024;
+ break;
+ case ID_USAC_EXT:
+ ret = parse_ext_ele(ac, e, gb);
+ if (ret < 0)
+ return ret;
+ break;
+ }
+ }
+
+ if (ac->oc[1].status && audio_found) {
+ avctx->sample_rate = ac->oc[1].m4ac.sample_rate;
+ avctx->frame_size = samples;
+ ac->oc[1].status = OC_LOCKED;
+ }
+
+ if (!frame->data[0] && samples) {
+ av_log(avctx, AV_LOG_ERROR, "no frame data found\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (samples) {
+ frame->nb_samples = samples;
+ frame->sample_rate = avctx->sample_rate;
+ frame->flags = indep_flag ? AV_FRAME_FLAG_KEY : 0x0;
+ *got_frame_ptr = 1;
+ } else {
+ av_frame_unref(ac->frame);
+ frame->flags = indep_flag ? AV_FRAME_FLAG_KEY : 0x0;
+ *got_frame_ptr = 0;
+ }
+
+ /* for dual-mono audio (SCE + SCE) */
+ is_dmono = ac->dmono_mode && sce_count == 2 &&
+ !av_channel_layout_compare(&ac->oc[1].ch_layout,
+ &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO);
+ if (is_dmono) {
+ if (ac->dmono_mode == 1)
+ frame->data[1] = frame->data[0];
+ else if (ac->dmono_mode == 2)
+ frame->data[0] = frame->data[1];
+ }
+
+ return 0;
+}
diff --git a/libavcodec/aac/aacdec_usac.h b/libavcodec/aac/aacdec_usac.h
new file mode 100644
index 0000000000..4116a2073a
--- /dev/null
+++ b/libavcodec/aac/aacdec_usac.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2024 Lynne <dev@lynne.ee>
+ *
+ * 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_H
+#define AVCODEC_AAC_AACDEC_USAC_H
+
+#include "aacdec.h"
+
+#include "libavcodec/get_bits.h"
+
+int ff_aac_usac_config_decode(AACDecContext *ac, AVCodecContext *avctx,
+ GetBitContext *gb, OutputConfiguration *oc,
+ int channel_config);
+
+int ff_aac_usac_reset_state(AACDecContext *ac, OutputConfiguration *oc);
+
+int ff_aac_usac_decode_frame(AVCodecContext *avctx, AACDecContext *ac,
+ GetBitContext *gb, int *got_frame_ptr);
+
+#endif /* AVCODEC_AAC_AACDEC_USAC_H */
diff --git a/libavcodec/aactab.c b/libavcodec/aactab.c
index 18afa69bad..7b040531aa 100644
--- a/libavcodec/aactab.c
+++ b/libavcodec/aactab.c
@@ -1998,6 +1998,11 @@ const uint8_t ff_tns_max_bands_128[] = {
};
// @}
+const uint8_t ff_usac_noise_fill_start_offset[2][2] = {
+ { 160, 20 },
+ { 120, 15 },
+};
+
const DECLARE_ALIGNED(32, float, ff_aac_eld_window_512)[1920] = {
0.00338834, 0.00567745, 0.00847677, 0.01172641,
0.01532555, 0.01917664, 0.02318809, 0.02729259,
@@ -3895,3 +3900,40 @@ DECLARE_ALIGNED(16, const float, ff_aac_deemph_weights)[16] = {
0,
USAC_EMPH_COEFF,
};
+
+const int ff_aac_usac_samplerate[32] = {
+ 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
+ 16000, 12000, 11025, 8000, 7350, -1, -1, 57600,
+ 51200, 40000, 38400, 34150, 28800, 25600, 20000, 19200,
+ 17075, 14400, 12800, 9600, -1, -1, -1, -1,
+};
+
+/* Window type (only long+eight, start/stop/stopstart), sine+sine, kbd+kbd, sine+kbd, kbd+sine */
+const float ff_aac_usac_mdst_filt_cur[4 /* Window */][4 /* Shape */][7] =
+{
+ { { 0.000000, 0.000000, 0.500000, 0.000000, -0.500000, 0.000000, 0.000000 },
+ { 0.091497, 0.000000, 0.581427, 0.000000, -0.581427, 0.000000, -0.091497 },
+ { 0.045748, 0.057238, 0.540714, 0.000000, -0.540714, -0.057238, -0.045748 },
+ { 0.045748, -0.057238, 0.540714, 0.000000, -0.540714, 0.057238, -0.045748 } },
+ { { 0.102658, 0.103791, 0.567149, 0.000000, -0.567149, -0.103791, -0.102658 },
+ { 0.150512, 0.047969, 0.608574, 0.000000, -0.608574, -0.047969, -0.150512 },
+ { 0.104763, 0.105207, 0.567861, 0.000000, -0.567861, -0.105207, -0.104763 },
+ { 0.148406, 0.046553, 0.607863, 0.000000, -0.607863, -0.046553, -0.148406 } },
+ { { 0.102658, -0.103791, 0.567149, 0.000000, -0.567149, 0.103791, -0.102658 },
+ { 0.150512, -0.047969, 0.608574, 0.000000, -0.608574, 0.047969, -0.150512 },
+ { 0.148406, -0.046553, 0.607863, 0.000000, -0.607863, 0.046553, -0.148406 },
+ { 0.104763, -0.105207, 0.567861, 0.000000, -0.567861, 0.105207, -0.104763 } },
+ { { 0.205316, 0.000000, 0.634298, 0.000000, -0.634298, 0.000000, -0.205316 },
+ { 0.209526, 0.000000, 0.635722, 0.000000, -0.635722, 0.000000, -0.209526 },
+ { 0.207421, 0.001416, 0.635010, 0.000000, -0.635010, -0.001416, -0.207421 },
+ { 0.207421, -0.001416, 0.635010, 0.000000, -0.635010, 0.001416, -0.207421 } }
+};
+
+/* Window type (everything/longstop+stopstart), sine or kbd */
+const float ff_aac_usac_mdst_filt_prev[2 /* Window */][2 /* sine/kbd */][7] =
+{
+ { { 0.000000, 0.106103, 0.250000, 0.318310, 0.250000, 0.106103, 0.000000 },
+ { 0.059509, 0.123714, 0.186579, 0.213077, 0.186579, 0.123714, 0.059509 } },
+ { { 0.038498, 0.039212, 0.039645, 0.039790, 0.039645, 0.039212, 0.038498 },
+ { 0.026142, 0.026413, 0.026577, 0.026631, 0.026577, 0.026413, 0.026142 } }
+};
diff --git a/libavcodec/aactab.h b/libavcodec/aactab.h
index 481fc57d93..8dbb2098c5 100644
--- a/libavcodec/aactab.h
+++ b/libavcodec/aactab.h
@@ -115,4 +115,14 @@ extern const uint8_t ff_tns_max_bands_512 [13];
extern const uint8_t ff_tns_max_bands_480 [13];
extern const uint8_t ff_tns_max_bands_128 [13];
+/* [x][y], x == 1 -> frame len is 768 frames, y == 1 -> is eight_short */
+extern const uint8_t ff_usac_noise_fill_start_offset[2][2];
+
+extern const int ff_aac_usac_samplerate[32];
+
+/* Window type (only long+eight, start/stop/stopstart), sine+sine, kbd+kbd, sine+kbd, kbd+sine */
+extern const float ff_aac_usac_mdst_filt_cur[4 /* Window */][4 /* Shape */][7];
+/* Window type (everything/longstop+stopstart), sine or kbd */
+extern const float ff_aac_usac_mdst_filt_prev[2 /* Window */][2 /* sine/kbd */][7];
+
#endif /* AVCODEC_AACTAB_H */
--
2.43.0.381.gb435a96ce8
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 16+ messages in thread