+/* these are unconfirmed but should be mostly correct */
+enum DCAExSSSpeakerMask {
+ DCA_EXSS_FRONT_CENTER = 0x0001,
+ DCA_EXSS_FRONT_LEFT_RIGHT = 0x0002,
+ DCA_EXSS_SIDE_REAR_LEFT_RIGHT = 0x0004,
+ DCA_EXSS_LFE = 0x0008,
+ DCA_EXSS_REAR_CENTER = 0x0010,
+ DCA_EXSS_FRONT_HIGH_LEFT_RIGHT = 0x0020,
+ DCA_EXSS_REAR_LEFT_RIGHT = 0x0040,
+ DCA_EXSS_FRONT_HIGH_CENTER = 0x0080,
+ DCA_EXSS_OVERHEAD = 0x0100,
+ DCA_EXSS_CENTER_LEFT_RIGHT = 0x0200,
+ DCA_EXSS_WIDE_LEFT_RIGHT = 0x0400,
+ DCA_EXSS_SIDE_LEFT_RIGHT = 0x0800,
+ DCA_EXSS_LFE2 = 0x1000,
+ DCA_EXSS_SIDE_HIGH_LEFT_RIGHT = 0x2000,
+ DCA_EXSS_REAR_HIGH_CENTER = 0x4000,
+ DCA_EXSS_REAR_HIGH_LEFT_RIGHT = 0x8000,
+};
+
+enum DCAExtensionMask {
+ DCA_EXT_CORE = 0x001, ///< core in core substream
+ DCA_EXT_XXCH = 0x002, ///< XXCh channels extension in core substream
+ DCA_EXT_X96 = 0x004, ///< 96/24 extension in core substream
+ DCA_EXT_XCH = 0x008, ///< XCh channel extension in core substream
+ DCA_EXT_EXSS_CORE = 0x010, ///< core in ExSS (extension substream)
+ DCA_EXT_EXSS_XBR = 0x020, ///< extended bitrate extension in ExSS
+ DCA_EXT_EXSS_XXCH = 0x040, ///< XXCh channels extension in ExSS
+ DCA_EXT_EXSS_X96 = 0x080, ///< 96/24 extension in ExSS
+ DCA_EXT_EXSS_LBR = 0x100, ///< low bitrate component in ExSS
+ DCA_EXT_EXSS_XLL = 0x200, ///< lossless extension in ExSS
+};
+
+/* -1 are reserved or unknown */
+static const int dca_ext_audio_descr_mask[] = {
+ DCA_EXT_XCH,
+ -1,
+ DCA_EXT_X96,
+ DCA_EXT_XCH | DCA_EXT_X96,
+ -1,
+ -1,
+ DCA_EXT_XXCH,
+ -1,
+};
+
+/* extensions that reside in core substream */
+#define DCA_CORE_EXTS (DCA_EXT_XCH | DCA_EXT_XXCH | DCA_EXT_X96)
+
+/* Tables for mapping dts channel configurations to libavcodec multichannel api.
+ * Some compromises have been made for special configurations. Most configurations
+ * are never used so complete accuracy is not needed.
+ *
+ * L = left, R = right, C = center, S = surround, F = front, R = rear, T = total, OV = overhead.
+ * S -> side, when both rear and back are configured move one of them to the side channel
+ * OV -> center back
+ * All 2 channel configurations -> AV_CH_LAYOUT_STEREO
+ */
+
+static const int64_t dca_core_channel_layout[] = {
+ AV_CH_FRONT_CENTER, ///< 1, A
+ AV_CH_LAYOUT_STEREO, ///< 2, A + B (dual mono)
+ AV_CH_LAYOUT_STEREO, ///< 2, L + R (stereo)
+ AV_CH_LAYOUT_STEREO, ///< 2, (L+R) + (L-R) (sum-difference)
+ AV_CH_LAYOUT_STEREO, ///< 2, LT +RT (left and right total)
+ AV_CH_LAYOUT_STEREO|AV_CH_FRONT_CENTER, ///< 3, C+L+R
+ AV_CH_LAYOUT_STEREO|AV_CH_BACK_CENTER, ///< 3, L+R+S
+ AV_CH_LAYOUT_STEREO|AV_CH_FRONT_CENTER|AV_CH_BACK_CENTER, ///< 4, C + L + R+ S
+ AV_CH_LAYOUT_STEREO|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT, ///< 4, L + R +SL+ SR
+ AV_CH_LAYOUT_STEREO|AV_CH_FRONT_CENTER|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT, ///< 5, C + L + R+ SL+SR
+ AV_CH_LAYOUT_STEREO|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER, ///< 6, CL + CR + L + R + SL + SR
+ AV_CH_LAYOUT_STEREO|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT|AV_CH_FRONT_CENTER|AV_CH_BACK_CENTER, ///< 6, C + L + R+ LR + RR + OV
+ AV_CH_FRONT_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_BACK_CENTER|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT, ///< 6, CF+ CR+LF+ RF+LR + RR
+ AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER|AV_CH_LAYOUT_STEREO|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT, ///< 7, CL + C + CR + L + R + SL + SR
+ AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER|AV_CH_LAYOUT_STEREO|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT, ///< 8, CL + CR + L + R + SL1 + SL2+ SR1 + SR2
+ AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER|AV_CH_LAYOUT_STEREO|AV_CH_SIDE_LEFT|AV_CH_BACK_CENTER|AV_CH_SIDE_RIGHT, ///< 8, CL + C+ CR + L + R + SL + S+ SR
+};
+
+static const int8_t dca_lfe_index[] = {
+ 1,2,2,2,2,3,2,3,2,3,2,3,1,3,2,3
+};
+
+static const int8_t dca_channel_reorder_lfe[][9] = {
+ { 0, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 1, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 1, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 1, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 1, -1, -1, -1, -1, -1, -1, -1},
+ { 2, 0, 1, -1, -1, -1, -1, -1, -1},
+ { 0, 1, 3, -1, -1, -1, -1, -1, -1},
+ { 2, 0, 1, 4, -1, -1, -1, -1, -1},
+ { 0, 1, 3, 4, -1, -1, -1, -1, -1},
+ { 2, 0, 1, 4, 5, -1, -1, -1, -1},
+ { 3, 4, 0, 1, 5, 6, -1, -1, -1},
+ { 2, 0, 1, 4, 5, 6, -1, -1, -1},
+ { 0, 6, 4, 5, 2, 3, -1, -1, -1},
+ { 4, 2, 5, 0, 1, 6, 7, -1, -1},
+ { 5, 6, 0, 1, 7, 3, 8, 4, -1},
+ { 4, 2, 5, 0, 1, 6, 8, 7, -1},
+};
+
+static const int8_t dca_channel_reorder_lfe_xch[][9] = {
+ { 0, 2, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 1, 3, -1, -1, -1, -1, -1, -1},
+ { 0, 1, 3, -1, -1, -1, -1, -1, -1},
+ { 0, 1, 3, -1, -1, -1, -1, -1, -1},
+ { 0, 1, 3, -1, -1, -1, -1, -1, -1},
+ { 2, 0, 1, 4, -1, -1, -1, -1, -1},
+ { 0, 1, 3, 4, -1, -1, -1, -1, -1},
+ { 2, 0, 1, 4, 5, -1, -1, -1, -1},
+ { 0, 1, 4, 5, 3, -1, -1, -1, -1},
+ { 2, 0, 1, 5, 6, 4, -1, -1, -1},
+ { 3, 4, 0, 1, 6, 7, 5, -1, -1},
+ { 2, 0, 1, 4, 5, 6, 7, -1, -1},
+ { 0, 6, 4, 5, 2, 3, 7, -1, -1},
+ { 4, 2, 5, 0, 1, 7, 8, 6, -1},
+ { 5, 6, 0, 1, 8, 3, 9, 4, 7},
+ { 4, 2, 5, 0, 1, 6, 9, 8, 7},
+};
+
+static const int8_t dca_channel_reorder_nolfe[][9] = {
+ { 0, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 1, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 1, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 1, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 1, -1, -1, -1, -1, -1, -1, -1},
+ { 2, 0, 1, -1, -1, -1, -1, -1, -1},
+ { 0, 1, 2, -1, -1, -1, -1, -1, -1},
+ { 2, 0, 1, 3, -1, -1, -1, -1, -1},
+ { 0, 1, 2, 3, -1, -1, -1, -1, -1},
+ { 2, 0, 1, 3, 4, -1, -1, -1, -1},
+ { 2, 3, 0, 1, 4, 5, -1, -1, -1},
+ { 2, 0, 1, 3, 4, 5, -1, -1, -1},
+ { 0, 5, 3, 4, 1, 2, -1, -1, -1},
+ { 3, 2, 4, 0, 1, 5, 6, -1, -1},
+ { 4, 5, 0, 1, 6, 2, 7, 3, -1},
+ { 3, 2, 4, 0, 1, 5, 7, 6, -1},
+};
+
+static const int8_t dca_channel_reorder_nolfe_xch[][9] = {
+ { 0, 1, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 1, 2, -1, -1, -1, -1, -1, -1},
+ { 0, 1, 2, -1, -1, -1, -1, -1, -1},
+ { 0, 1, 2, -1, -1, -1, -1, -1, -1},
+ { 0, 1, 2, -1, -1, -1, -1, -1, -1},
+ { 2, 0, 1, 3, -1, -1, -1, -1, -1},
+ { 0, 1, 2, 3, -1, -1, -1, -1, -1},
+ { 2, 0, 1, 3, 4, -1, -1, -1, -1},
+ { 0, 1, 3, 4, 2, -1, -1, -1, -1},
+ { 2, 0, 1, 4, 5, 3, -1, -1, -1},
+ { 2, 3, 0, 1, 5, 6, 4, -1, -1},
+ { 2, 0, 1, 3, 4, 5, 6, -1, -1},
+ { 0, 5, 3, 4, 1, 2, 6, -1, -1},
+ { 3, 2, 4, 0, 1, 6, 7, 5, -1},
+ { 4, 5, 0, 1, 7, 2, 8, 3, 6},
+ { 3, 2, 4, 0, 1, 5, 8, 7, 6},
+};
+