From 737f653e7cd569cfd85a7bdd9a8e27521aed2335 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Sat, 3 May 2025 12:26:43 +0300 Subject: [PATCH] qtdemux: Parse chan box This is another variant of providing channel positions. Also if neither chan nor chnl boxes are found, configure a default channel layout for raw audio tracks. Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/4403 Part-of: --- .../gst-plugins-good/gst/isomp4/fourcc.h | 1 + .../gst-plugins-good/gst/isomp4/qtdemux.c | 1357 ++++++++++++++++- 2 files changed, 1357 insertions(+), 1 deletion(-) diff --git a/subprojects/gst-plugins-good/gst/isomp4/fourcc.h b/subprojects/gst-plugins-good/gst/isomp4/fourcc.h index 1243381b12..ba34ee1e93 100644 --- a/subprojects/gst-plugins-good/gst/isomp4/fourcc.h +++ b/subprojects/gst-plugins-good/gst/isomp4/fourcc.h @@ -310,6 +310,7 @@ G_BEGIN_DECLS #define FOURCC_fpcm GST_MAKE_FOURCC('f','p','c','m') #define FOURCC_pcmC GST_MAKE_FOURCC('p','c','m','C') #define FOURCC_chnl GST_MAKE_FOURCC('c','h','n','l') +#define FOURCC_chan GST_MAKE_FOURCC('c','h','a','n') #define FOURCC_av01 GST_MAKE_FOURCC('a','v','0','1') #define FOURCC_av1C GST_MAKE_FOURCC('a','v','1','C') #define FOURCC_av1f GST_MAKE_FOURCC('a','v','1','f') diff --git a/subprojects/gst-plugins-good/gst/isomp4/qtdemux.c b/subprojects/gst-plugins-good/gst/isomp4/qtdemux.c index a287bc3c12..8ddf1fa3aa 100644 --- a/subprojects/gst-plugins-good/gst/isomp4/qtdemux.c +++ b/subprojects/gst-plugins-good/gst/isomp4/qtdemux.c @@ -13146,6 +13146,1340 @@ error: } } +// See CoreAudioTypes.h and ffmpeg's mov_chan.h +typedef enum +{ + AUDIO_CHANNEL_LAYOUT_TAG_USECHANNELDESCRIPTIONS = (0 << 16) | 0, + AUDIO_CHANNEL_LAYOUT_TAG_USECHANNELBITMAP = (1 << 16) | 0, + + AUDIO_CHANNEL_LAYOUT_TAG_MONO = (100 << 16) | 1, + AUDIO_CHANNEL_LAYOUT_TAG_STEREO = (101 << 16) | 2, + AUDIO_CHANNEL_LAYOUT_TAG_STEREOHEADPHONES = (102 << 16) | 2, + AUDIO_CHANNEL_LAYOUT_TAG_MATRIXSTEREO = (103 << 16) | 2, + AUDIO_CHANNEL_LAYOUT_TAG_MIDSIDE = (104 << 16) | 2, + AUDIO_CHANNEL_LAYOUT_TAG_XY = (105 << 16) | 2, + AUDIO_CHANNEL_LAYOUT_TAG_BINAURAL = (106 << 16) | 2, + AUDIO_CHANNEL_LAYOUT_TAG_AMBISONIC_B_FORMAT = (107 << 16) | 4, + + AUDIO_CHANNEL_LAYOUT_TAG_QUADRAPHONIC = (108 << 16) | 4, + AUDIO_CHANNEL_LAYOUT_TAG_PENTAGONAL = (109 << 16) | 5, + AUDIO_CHANNEL_LAYOUT_TAG_HEXAGONAL = (110 << 16) | 6, + AUDIO_CHANNEL_LAYOUT_TAG_OCTAGONAL = (111 << 16) | 8, + AUDIO_CHANNEL_LAYOUT_TAG_CUBE = (112 << 16) | 8, + + AUDIO_CHANNEL_LAYOUT_TAG_MPEG_3_0_A = (113 << 16) | 3, + AUDIO_CHANNEL_LAYOUT_TAG_MPEG_3_0_B = (114 << 16) | 3, + AUDIO_CHANNEL_LAYOUT_TAG_MPEG_4_0_A = (115 << 16) | 4, + AUDIO_CHANNEL_LAYOUT_TAG_MPEG_4_0_B = (116 << 16) | 4, + AUDIO_CHANNEL_LAYOUT_TAG_MPEG_5_0_A = (117 << 16) | 5, + AUDIO_CHANNEL_LAYOUT_TAG_MPEG_5_0_B = (118 << 16) | 5, + AUDIO_CHANNEL_LAYOUT_TAG_MPEG_5_0_C = (119 << 16) | 5, + AUDIO_CHANNEL_LAYOUT_TAG_MPEG_5_0_D = (120 << 16) | 5, + AUDIO_CHANNEL_LAYOUT_TAG_MPEG_5_1_A = (121 << 16) | 6, + AUDIO_CHANNEL_LAYOUT_TAG_MPEG_5_1_B = (122 << 16) | 6, + AUDIO_CHANNEL_LAYOUT_TAG_MPEG_5_1_C = (123 << 16) | 6, + AUDIO_CHANNEL_LAYOUT_TAG_MPEG_5_1_D = (124 << 16) | 6, + AUDIO_CHANNEL_LAYOUT_TAG_MPEG_6_1_A = (125 << 16) | 7, + AUDIO_CHANNEL_LAYOUT_TAG_MPEG_7_1_A = (126 << 16) | 8, + AUDIO_CHANNEL_LAYOUT_TAG_MPEG_7_1_B = (127 << 16) | 8, + AUDIO_CHANNEL_LAYOUT_TAG_MPEG_7_1_C = (128 << 16) | 8, + AUDIO_CHANNEL_LAYOUT_TAG_EMAGIC_DEFAULT_7_1 = (129 << 16) | 8, + AUDIO_CHANNEL_LAYOUT_TAG_SMPTE_DTV = (130 << 16) | 8, + + AUDIO_CHANNEL_LAYOUT_TAG_ITU_2_1 = (131 << 16) | 3, + AUDIO_CHANNEL_LAYOUT_TAG_ITU_2_2 = (132 << 16) | 4, + + AUDIO_CHANNEL_LAYOUT_TAG_DVD_4 = (133 << 16) | 3, + AUDIO_CHANNEL_LAYOUT_TAG_DVD_5 = (134 << 16) | 4, + AUDIO_CHANNEL_LAYOUT_TAG_DVD_6 = (135 << 16) | 5, + AUDIO_CHANNEL_LAYOUT_TAG_DVD_10 = (136 << 16) | 4, + AUDIO_CHANNEL_LAYOUT_TAG_DVD_11 = (137 << 16) | 5, + AUDIO_CHANNEL_LAYOUT_TAG_DVD_18 = (138 << 16) | 5, + + AUDIO_CHANNEL_LAYOUT_TAG_AUDIOUNIT_6_0 = (139 << 16) | 6, + AUDIO_CHANNEL_LAYOUT_TAG_AUDIOUNIT_7_0 = (140 << 16) | 7, + AUDIO_CHANNEL_LAYOUT_TAG_AUDIOUNIT_7_0_FRONT = (148 << 16) | 7, + AUDIO_CHANNEL_LAYOUT_TAG_AAC_6_0 = (141 << 16) | 6, + AUDIO_CHANNEL_LAYOUT_TAG_AAC_6_1 = (142 << 16) | 7, + AUDIO_CHANNEL_LAYOUT_TAG_AAC_7_0 = (143 << 16) | 7, + AUDIO_CHANNEL_LAYOUT_TAG_AAC_7_1_B = (183 << 16) | 8, + AUDIO_CHANNEL_LAYOUT_TAG_AAC_OCTAGONAL = (144 << 16) | 8, + + AUDIO_CHANNEL_LAYOUT_TAG_TMH_10_2_STD = (145 << 16) | 16, + AUDIO_CHANNEL_LAYOUT_TAG_TMH_10_2_FULL = (146 << 16) | 21, + + AUDIO_CHANNEL_LAYOUT_TAG_AC3_1_0_1 = (149 << 16) | 2, + AUDIO_CHANNEL_LAYOUT_TAG_AC3_3_0 = (150 << 16) | 3, + AUDIO_CHANNEL_LAYOUT_TAG_AC3_3_1 = (151 << 16) | 4, + AUDIO_CHANNEL_LAYOUT_TAG_AC3_3_0_1 = (152 << 16) | 4, + AUDIO_CHANNEL_LAYOUT_TAG_AC3_2_1_1 = (153 << 16) | 4, + AUDIO_CHANNEL_LAYOUT_TAG_AC3_3_1_1 = (154 << 16) | 5, + + AUDIO_CHANNEL_LAYOUT_TAG_EAC_6_0_A = (155 << 16) | 6, + AUDIO_CHANNEL_LAYOUT_TAG_EAC_7_0_A = (156 << 16) | 7, + + AUDIO_CHANNEL_LAYOUT_TAG_EAC3_6_1_A = (157 << 16) | 7, + AUDIO_CHANNEL_LAYOUT_TAG_EAC3_6_1_B = (158 << 16) | 7, + AUDIO_CHANNEL_LAYOUT_TAG_EAC3_6_1_C = (159 << 16) | 7, + AUDIO_CHANNEL_LAYOUT_TAG_EAC3_7_1_A = (160 << 16) | 8, + AUDIO_CHANNEL_LAYOUT_TAG_EAC3_7_1_B = (161 << 16) | 8, + AUDIO_CHANNEL_LAYOUT_TAG_EAC3_7_1_C = (162 << 16) | 8, + AUDIO_CHANNEL_LAYOUT_TAG_EAC3_7_1_D = (163 << 16) | 8, + AUDIO_CHANNEL_LAYOUT_TAG_EAC3_7_1_E = (164 << 16) | 8, + + AUDIO_CHANNEL_LAYOUT_TAG_EAC3_7_1_F = (165 << 16) | 8, + AUDIO_CHANNEL_LAYOUT_TAG_EAC3_7_1_G = (166 << 16) | 8, + AUDIO_CHANNEL_LAYOUT_TAG_EAC3_7_1_H = (167 << 16) | 8, + + AUDIO_CHANNEL_LAYOUT_TAG_DTS_3_1 = (168 << 16) | 4, + AUDIO_CHANNEL_LAYOUT_TAG_DTS_4_1 = (169 << 16) | 5, + AUDIO_CHANNEL_LAYOUT_TAG_DTS_6_0_A = (170 << 16) | 6, + AUDIO_CHANNEL_LAYOUT_TAG_DTS_6_0_B = (171 << 16) | 6, + AUDIO_CHANNEL_LAYOUT_TAG_DTS_6_0_C = (172 << 16) | 6, + AUDIO_CHANNEL_LAYOUT_TAG_DTS_6_1_A = (173 << 16) | 7, + AUDIO_CHANNEL_LAYOUT_TAG_DTS_6_1_B = (174 << 16) | 7, + AUDIO_CHANNEL_LAYOUT_TAG_DTS_6_1_C = (175 << 16) | 7, + AUDIO_CHANNEL_LAYOUT_TAG_DTS_7_0 = (176 << 16) | 7, + AUDIO_CHANNEL_LAYOUT_TAG_DTS_7_1 = (177 << 16) | 8, + AUDIO_CHANNEL_LAYOUT_TAG_DTS_8_0_A = (178 << 16) | 8, + AUDIO_CHANNEL_LAYOUT_TAG_DTS_8_0_B = (179 << 16) | 8, + AUDIO_CHANNEL_LAYOUT_TAG_DTS_8_1_A = (180 << 16) | 9, + AUDIO_CHANNEL_LAYOUT_TAG_DTS_8_1_B = (181 << 16) | 9, + AUDIO_CHANNEL_LAYOUT_TAG_DTS_6_1_D = (182 << 16) | 7, + + AUDIO_CHANNEL_LAYOUT_TAG_HOA_ACN_SN3D = (190U << 16) | 0, + AUDIO_CHANNEL_LAYOUT_TAG_HOA_ACN_N3D = (191U << 16) | 0, + + AUDIO_CHANNEL_LAYOUT_TAG_ATMOS_7_1_4 = (192U << 16) | 12, + AUDIO_CHANNEL_LAYOUT_TAG_ATMOS_9_1_6 = (193U << 16) | 16, + AUDIO_CHANNEL_LAYOUT_TAG_ATMOS_5_1_2 = (194U << 16) | 8, + + AUDIO_CHANNEL_LAYOUT_TAG_DISCRETEINORDER = (147 << 16) | 0, + AUDIO_CHANNEL_LAYOUT_TAG_UNKNOWN = 0xFFFF0000 +} AudioChannelLayoutTag; + +static const struct +{ + AudioChannelLayoutTag tag; + const GstAudioChannelPosition *positions; +} chan_layout_map[] = { + { + AUDIO_CHANNEL_LAYOUT_TAG_MONO, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_MONO, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_STEREO, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_STEREOHEADPHONES, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_MATRIXSTEREO, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_MIDSIDE, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_XY, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_BINAURAL, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + }, + }, + // TODO: AUDIO_CHANNEL_LAYOUT_TAG_AMBISONIC_B_FORMAT + { + AUDIO_CHANNEL_LAYOUT_TAG_QUADRAPHONIC, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, + GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_PENTAGONAL, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, + GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_HEXAGONAL, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, + GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_OCTAGONAL, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, + GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_CUBE, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, + GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, + GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_TOP_REAR_LEFT, + GST_AUDIO_CHANNEL_POSITION_TOP_REAR_RIGHT, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_MPEG_3_0_A, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_MPEG_3_0_B, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_MPEG_4_0_A, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_MPEG_4_0_B, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_MPEG_5_0_A, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_MPEG_5_0_B, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_MPEG_5_0_C, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_MPEG_5_0_D, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_MPEG_5_1_A, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_LFE1, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_MPEG_5_1_B, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_LFE1, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_MPEG_5_1_C, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + GST_AUDIO_CHANNEL_POSITION_LFE1, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_MPEG_5_1_D, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + GST_AUDIO_CHANNEL_POSITION_LFE1, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_MPEG_6_1_A, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_LFE1, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_MPEG_7_1_A, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_LFE1, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_MPEG_7_1_B, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + GST_AUDIO_CHANNEL_POSITION_LFE1, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_MPEG_7_1_C, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_LFE1, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, + GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_EMAGIC_DEFAULT_7_1, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_LFE1, + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, + }, + }, + // TODO: AUDIO_CHANNEL_LAYOUT_TAG_SMPTE_DTV + { + AUDIO_CHANNEL_LAYOUT_TAG_ITU_2_1, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_ITU_2_2, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_DVD_4, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_LFE1, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_DVD_5, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_LFE1, + GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_DVD_6, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_LFE1, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_DVD_10, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_LFE1, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_DVD_11, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_LFE1, + GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_DVD_18, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + GST_AUDIO_CHANNEL_POSITION_LFE1, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_AUDIOUNIT_6_0, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_AUDIOUNIT_7_0, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, + GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_AUDIOUNIT_7_0_FRONT, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_AAC_6_0, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_AAC_6_1, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, + GST_AUDIO_CHANNEL_POSITION_LFE1, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_AAC_7_0, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, + GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_AAC_7_1_B, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, + GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, + GST_AUDIO_CHANNEL_POSITION_LFE1, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_AAC_OCTAGONAL, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, + GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, + GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, + }, + }, + +// TODO: AUDIO_CHANNEL_LAYOUT_TAG_TMH_10_2_STD +// TODO: AUDIO_CHANNEL_LAYOUT_TAG_TMH_10_2_FULL + { + AUDIO_CHANNEL_LAYOUT_TAG_AC3_1_0_1, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_LFE1, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_AC3_3_0, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_AC3_3_1, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_AC3_3_0_1, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_LFE1, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_AC3_2_1_1, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, + GST_AUDIO_CHANNEL_POSITION_LFE1, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_AC3_3_1_1, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, + GST_AUDIO_CHANNEL_POSITION_LFE1, + }, + }, + + { + AUDIO_CHANNEL_LAYOUT_TAG_EAC_6_0_A, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_EAC_7_0_A, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, + GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, + }, + }, + + + { + AUDIO_CHANNEL_LAYOUT_TAG_EAC3_6_1_A, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + GST_AUDIO_CHANNEL_POSITION_LFE1, + GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, + }, + }, +// TODO: AUDIO_CHANNEL_LAYOUT_TAG_EAC3_6_1_B, + { + AUDIO_CHANNEL_LAYOUT_TAG_EAC3_6_1_C, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + GST_AUDIO_CHANNEL_POSITION_LFE1, + GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_CENTER, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_EAC3_7_1_A, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + GST_AUDIO_CHANNEL_POSITION_LFE1, + GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, + GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_EAC3_7_1_B, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + GST_AUDIO_CHANNEL_POSITION_LFE1, + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_EAC3_7_1_C, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + GST_AUDIO_CHANNEL_POSITION_LFE1, + GST_AUDIO_CHANNEL_POSITION_SURROUND_LEFT, + GST_AUDIO_CHANNEL_POSITION_SURROUND_RIGHT, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_EAC3_7_1_D, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + GST_AUDIO_CHANNEL_POSITION_LFE1, + GST_AUDIO_CHANNEL_POSITION_WIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_WIDE_RIGHT, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_EAC3_7_1_E, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + GST_AUDIO_CHANNEL_POSITION_LFE1, + GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_RIGHT, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_EAC3_7_1_F, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + GST_AUDIO_CHANNEL_POSITION_LFE1, + GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, + GST_AUDIO_CHANNEL_POSITION_TOP_CENTER, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_EAC3_7_1_G, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + GST_AUDIO_CHANNEL_POSITION_LFE1, + GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, + GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_CENTER, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_EAC3_7_1_H, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + GST_AUDIO_CHANNEL_POSITION_LFE1, + GST_AUDIO_CHANNEL_POSITION_TOP_CENTER, + GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_CENTER, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_DTS_3_1, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_LFE1, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_DTS_4_1, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, + GST_AUDIO_CHANNEL_POSITION_LFE1, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_DTS_6_0_A, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_DTS_6_0_B, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, + GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, + GST_AUDIO_CHANNEL_POSITION_TOP_CENTER, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_DTS_6_0_C, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, + GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_DTS_6_1_A, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + GST_AUDIO_CHANNEL_POSITION_LFE1, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_DTS_6_1_B, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, + GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, + GST_AUDIO_CHANNEL_POSITION_TOP_CENTER, + GST_AUDIO_CHANNEL_POSITION_LFE1, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_DTS_6_1_C, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, + GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, + GST_AUDIO_CHANNEL_POSITION_LFE1, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_DTS_7_0, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_DTS_7_1, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + GST_AUDIO_CHANNEL_POSITION_LFE1, + }, + }, + + { + AUDIO_CHANNEL_LAYOUT_TAG_DTS_8_0_A, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, + GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_DTS_8_0_B, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + }, + }, + + { + AUDIO_CHANNEL_LAYOUT_TAG_DTS_8_1_A, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, + GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, + GST_AUDIO_CHANNEL_POSITION_LFE1, + }, + }, + { + AUDIO_CHANNEL_LAYOUT_TAG_DTS_8_1_B, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + GST_AUDIO_CHANNEL_POSITION_LFE1, + }, + }, + + { + AUDIO_CHANNEL_LAYOUT_TAG_DTS_6_1_D, + (const GstAudioChannelPosition[]) { + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + GST_AUDIO_CHANNEL_POSITION_LFE1, + GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, + }, + }, + + // TODO: AUDIO_CHANNEL_LAYOUT_TAG_HOA_ACN_SN3D + // TODO: AUDIO_CHANNEL_LAYOUT_TAG_HOA_ACN_N3D + // TODO: AUDIO_CHANNEL_LAYOUT_TAG_ATMOS_7_1_4 + // TODO: AUDIO_CHANNEL_LAYOUT_TAG_ATMOS_9_1_6 + // TODO: AUDIO_CHANNEL_LAYOUT_TAG_ATMOS_5_1_2 +}; + +// Mapping bit N to GstAudioChannelPosition +static const GstAudioChannelPosition audio_channel_bitmap_mapping[32] = { + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, // 0 + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_LFE1, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, + GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, + GST_AUDIO_CHANNEL_POSITION_SURROUND_LEFT, + GST_AUDIO_CHANNEL_POSITION_SURROUND_RIGHT, // 10 + GST_AUDIO_CHANNEL_POSITION_TOP_CENTER, + GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_LEFT, + GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_CENTER, + GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_TOP_REAR_LEFT, + GST_AUDIO_CHANNEL_POSITION_TOP_REAR_CENTER, + GST_AUDIO_CHANNEL_POSITION_TOP_REAR_RIGHT, // 17 + GST_AUDIO_CHANNEL_POSITION_INVALID, + GST_AUDIO_CHANNEL_POSITION_INVALID, + GST_AUDIO_CHANNEL_POSITION_INVALID, // 20 + GST_AUDIO_CHANNEL_POSITION_INVALID, // LeftTopMiddle + GST_AUDIO_CHANNEL_POSITION_INVALID, + GST_AUDIO_CHANNEL_POSITION_INVALID, // RightTopMiddle + GST_AUDIO_CHANNEL_POSITION_INVALID, // LeftTopRear + GST_AUDIO_CHANNEL_POSITION_INVALID, // CenterTopRear + GST_AUDIO_CHANNEL_POSITION_INVALID, // RightTopRear +}; + +typedef enum +{ + AUDIO_CHANNEL_LABEL_UNKNOWN = 0xFFFFFFFF, + AUDIO_CHANNEL_LABEL_UNUSED = 0, + AUDIO_CHANNEL_LABEL_USE_COORDINATES = 100, + + AUDIO_CHANNEL_LABEL_LEFT = 1, + AUDIO_CHANNEL_LABEL_RIGHT = 2, + AUDIO_CHANNEL_LABEL_CENTER = 3, + AUDIO_CHANNEL_LABEL_LFE_SCREEN = 4, + AUDIO_CHANNEL_LABEL_LEFT_SURROUND = 5, + AUDIO_CHANNEL_LABEL_RIGHT_SURROUND = 6, + AUDIO_CHANNEL_LABEL_LEFT_CENTER = 7, + AUDIO_CHANNEL_LABEL_RIGHT_CENTER = 8, + AUDIO_CHANNEL_LABEL_CENTER_SURROUND = 9, + AUDIO_CHANNEL_LABEL_LEFT_SURROUND_DIRECT = 10, + AUDIO_CHANNEL_LABEL_RIGHT_SURROUND_DIRECT = 11, + AUDIO_CHANNEL_LABEL_TOP_CENTER_SURROUND = 12, + AUDIO_CHANNEL_LABEL_VERTICAL_HEIGHT_LEFT = 13, + AUDIO_CHANNEL_LABEL_VERTICAL_HEIGHT_CENTER = 14, + AUDIO_CHANNEL_LABEL_VERTICAL_HEIGHT_RIGHT = 15, + + AUDIO_CHANNEL_LABEL_TOP_BACK_LEFT = 16, + AUDIO_CHANNEL_LABEL_TOP_BACK_CENTER = 17, + AUDIO_CHANNEL_LABEL_TOP_BACK_RIGHT = 18, + + AUDIO_CHANNEL_LABEL_REAR_SURROUND_LEFT = 33, + AUDIO_CHANNEL_LABEL_REAR_SURROUND_RIGHT = 34, + AUDIO_CHANNEL_LABEL_LEFT_WIDE = 35, + AUDIO_CHANNEL_LABEL_RIGHT_WIDE = 36, + AUDIO_CHANNEL_LABEL_LFE2 = 37, + AUDIO_CHANNEL_LABEL_LEFT_TOTAL = 38, + AUDIO_CHANNEL_LABEL_RIGHT_TOTAL = 39, + AUDIO_CHANNEL_LABEL_HEARING_IMPAIRED = 40, + AUDIO_CHANNEL_LABEL_NARRATION = 41, + AUDIO_CHANNEL_LABEL_MONO = 42, + AUDIO_CHANNEL_LABEL_DIALOG_CENTRIC_MIX = 43, + + AUDIO_CHANNEL_LABEL_CENTER_SURROUND_DIRECT = 44, + + AUDIO_CHANNEL_LABEL_HAPTIC = 45, + + AUDIO_CHANNEL_LABEL_LEFT_TOP_MIDDLE = 49, + AUDIO_CHANNEL_LABEL_RIGHT_TOP_MIDDLE = 51, + AUDIO_CHANNEL_LABEL_LEFT_TOP_REAR = 52, + AUDIO_CHANNEL_LABEL_CENTER_TOP_REAR = 53, + AUDIO_CHANNEL_LABEL_RIGHT_TOP_REAR = 54, + + AUDIO_CHANNEL_LABEL_AMBISONIC_W = 200, + AUDIO_CHANNEL_LABEL_AMBISONIC_X = 201, + AUDIO_CHANNEL_LABEL_AMBISONIC_Y = 202, + AUDIO_CHANNEL_LABEL_AMBISONIC_Z = 203, + + AUDIO_CHANNEL_LABEL_MS_MID = 204, + AUDIO_CHANNEL_LABEL_MS_SIDE = 205, + + AUDIO_CHANNEL_LABEL_XY_X = 206, + AUDIO_CHANNEL_LABEL_XY_Y = 207, + + AUDIO_CHANNEL_LABEL_BINAURAL_LEFT = 208, + AUDIO_CHANNEL_LABEL_BINAURAL_RIGHT = 209, + + AUDIO_CHANNEL_LABEL_HEADPHONES_LEFT = 301, + AUDIO_CHANNEL_LABEL_HEADPHONES_RIGHT = 302, + AUDIO_CHANNEL_LABEL_CLICK_TRACK = 304, + AUDIO_CHANNEL_LABEL_FOREIGN_LANGUAGE = 305, +} AudioChannelLabel; + +static const struct +{ + AudioChannelLabel label; + GstAudioChannelPosition position; +} audio_channel_label_mapping[] = { + { + AUDIO_CHANNEL_LABEL_MONO, + GST_AUDIO_CHANNEL_POSITION_MONO}, + { + AUDIO_CHANNEL_LABEL_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT}, + { + AUDIO_CHANNEL_LABEL_RIGHT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + }, + { + AUDIO_CHANNEL_LABEL_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + }, + { + AUDIO_CHANNEL_LABEL_LFE_SCREEN, + GST_AUDIO_CHANNEL_POSITION_LFE1, + }, + { + AUDIO_CHANNEL_LABEL_LEFT_SURROUND, + GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, + }, + { + AUDIO_CHANNEL_LABEL_RIGHT_SURROUND, + GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, + }, + { + AUDIO_CHANNEL_LABEL_LEFT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, + }, + { + AUDIO_CHANNEL_LABEL_RIGHT_CENTER, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER}, + { + AUDIO_CHANNEL_LABEL_CENTER_SURROUND, + GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, + }, + { + AUDIO_CHANNEL_LABEL_LEFT_SURROUND_DIRECT, + GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + }, + { + AUDIO_CHANNEL_LABEL_RIGHT_SURROUND_DIRECT, + GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + }, + { + AUDIO_CHANNEL_LABEL_TOP_CENTER_SURROUND, + GST_AUDIO_CHANNEL_POSITION_TOP_CENTER, + }, + { + AUDIO_CHANNEL_LABEL_VERTICAL_HEIGHT_LEFT, + GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_LEFT, + }, + { + AUDIO_CHANNEL_LABEL_VERTICAL_HEIGHT_CENTER, + GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_CENTER, + }, + { + AUDIO_CHANNEL_LABEL_VERTICAL_HEIGHT_RIGHT, + GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_RIGHT, + }, + { + AUDIO_CHANNEL_LABEL_TOP_BACK_LEFT, + GST_AUDIO_CHANNEL_POSITION_TOP_REAR_LEFT, + }, + { + AUDIO_CHANNEL_LABEL_TOP_BACK_CENTER, + GST_AUDIO_CHANNEL_POSITION_TOP_REAR_CENTER, + }, + { + AUDIO_CHANNEL_LABEL_TOP_BACK_RIGHT, + GST_AUDIO_CHANNEL_POSITION_TOP_REAR_RIGHT, + }, + { + AUDIO_CHANNEL_LABEL_REAR_SURROUND_LEFT, + GST_AUDIO_CHANNEL_POSITION_TOP_REAR_LEFT, + }, + { + AUDIO_CHANNEL_LABEL_REAR_SURROUND_RIGHT, + GST_AUDIO_CHANNEL_POSITION_TOP_REAR_RIGHT, + }, + { + AUDIO_CHANNEL_LABEL_LEFT_WIDE, + GST_AUDIO_CHANNEL_POSITION_WIDE_LEFT, + }, + { + AUDIO_CHANNEL_LABEL_RIGHT_WIDE, + GST_AUDIO_CHANNEL_POSITION_WIDE_RIGHT, + }, + { + AUDIO_CHANNEL_LABEL_LFE2, + GST_AUDIO_CHANNEL_POSITION_LFE2, + }, + { + AUDIO_CHANNEL_LABEL_BINAURAL_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + }, + { + AUDIO_CHANNEL_LABEL_BINAURAL_RIGHT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + }, + { + AUDIO_CHANNEL_LABEL_HEADPHONES_LEFT, + GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + }, + { + AUDIO_CHANNEL_LABEL_HEADPHONES_RIGHT, + GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + } +}; + +static void +qtdemux_parse_chan (GstQTDemux * qtdemux, GstByteReader * br, + QtDemuxStream * stream, QtDemuxStreamStsdEntry * entry) +{ + GstAudioChannelPosition positions[64]; + guint n_channels = 0; + + // Skip over version and flags + gst_byte_reader_skip_unchecked (br, 4); + + if (gst_byte_reader_get_remaining (br) < 12) + return; + + guint32 layout_tag = gst_byte_reader_get_uint32_be_unchecked (br); + guint32 bitmap = gst_byte_reader_get_uint32_be_unchecked (br); + guint32 num_channel_descs = gst_byte_reader_get_uint32_be_unchecked (br); + + if (gst_byte_reader_get_remaining (br) < num_channel_descs * 5 * 4) + return; + + if (layout_tag == AUDIO_CHANNEL_LAYOUT_TAG_USECHANNELBITMAP) { + // Invalid/unsupported positions are mapped to defaults later + for (gsize i = 0; i < G_N_ELEMENTS (audio_channel_bitmap_mapping); i++) { + if (bitmap & (1 << i)) { + positions[n_channels] = audio_channel_bitmap_mapping[i]; + n_channels += 1; + } + } + } else if (layout_tag == AUDIO_CHANNEL_LAYOUT_TAG_USECHANNELDESCRIPTIONS) { + if (num_channel_descs < 64) { + n_channels = num_channel_descs; + + for (guint32 i = 0; i < num_channel_descs; i++) { + positions[i] = GST_AUDIO_CHANNEL_POSITION_INVALID; + + guint32 label = gst_byte_reader_get_uint32_be_unchecked (br); + + // Discrete channel + if (label == 400 || (label >> 16) == 1) { + positions[i] = GST_AUDIO_CHANNEL_POSITION_NONE; + } else { + // If a label is not found the channel stays invalid and is + // handled as an error later with mapping to the defaults + for (gsize j = 0; j < G_N_ELEMENTS (audio_channel_label_mapping); j++) { + if (audio_channel_label_mapping[j].label == label) { + positions[i] = audio_channel_label_mapping[j].position; + break; + } + } + } + + // Skip coordinates and flags + gst_byte_reader_skip_unchecked (br, 4 * 4); + } + } + } else if (layout_tag == AUDIO_CHANNEL_LAYOUT_TAG_DISCRETEINORDER) { + // Unordered + n_channels = entry->n_channels; + for (gsize i = 0; i < n_channels; i++) { + positions[i] = GST_AUDIO_CHANNEL_POSITION_NONE; + } + } else if (layout_tag & 0xffff) { + for (gsize i = 0; i < G_N_ELEMENTS (chan_layout_map); i++) { + if (chan_layout_map[i].tag == layout_tag) { + n_channels = layout_tag & 0xffff; + memcpy (positions, chan_layout_map[i].positions, + n_channels * sizeof (GstAudioChannelPosition)); + break; + } + } + } + + if (n_channels == 0) { + GST_WARNING_OBJECT (qtdemux, "Unsupported channel layout tag 0x%08x", + layout_tag); + return; + } + +#ifndef GST_DISABLE_GST_DEBUG + { + gchar *s = gst_audio_channel_positions_to_string (positions, n_channels); + + GST_DEBUG_OBJECT (qtdemux, "Retrieved channel positions %s", s); + + g_free (s); + } +#endif + + guint64 channel_mask; + GstAudioChannelPosition valid_positions[64]; + + if (!gst_audio_channel_positions_to_mask (positions, n_channels, FALSE, + &channel_mask)) { + GST_WARNING_OBJECT (qtdemux, "Can't convert channel positions to mask"); + goto error; + } + + memcpy (valid_positions, positions, sizeof (positions[0]) * n_channels); + if (!gst_audio_channel_positions_to_valid_order (valid_positions, n_channels)) { + GST_WARNING_OBJECT (qtdemux, + "Can't convert channel positions to GStreamer channel order"); + goto error; + } + + if (n_channels > 1) { + if (!gst_audio_get_channel_reorder_map (n_channels, positions, + valid_positions, entry->reorder_map)) { + GST_WARNING_OBJECT (qtdemux, "Can't calculate channel reorder map"); + goto error; + } + entry->needs_reorder = + memcmp (positions, valid_positions, + sizeof (positions[0]) * n_channels) != 0; + } + + gst_caps_set_simple (entry->caps, "channel-mask", GST_TYPE_BITMASK, + channel_mask, NULL); + + // Update based on the actual channel count from this box + entry->samples_per_frame = n_channels; + entry->bytes_per_frame = n_channels * entry->bytes_per_sample; + entry->samples_per_packet = entry->samples_per_frame; + entry->bytes_per_packet = entry->bytes_per_sample; + + stream->min_buffer_size = 1024 * entry->bytes_per_frame; + stream->max_buffer_size = entry->rate * entry->bytes_per_frame; + GST_DEBUG ("setting min/max buffer sizes to %d/%d", stream->min_buffer_size, + stream->max_buffer_size); + + return; + +error: + { + // Set a default channel mask on errors + guint64 default_mask = + gst_audio_channel_get_fallback_mask (entry->n_channels); + + GST_WARNING_OBJECT (qtdemux, + "Configuring default channel mask for %u channels", entry->n_channels); + + gst_caps_set_simple (entry->caps, "channel-mask", GST_TYPE_BITMASK, + default_mask, NULL); + } +} + /* parse the traks. * With each track we associate a new QtDemuxStream that contains all the info * about the trak. @@ -15539,11 +16873,12 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak, guint32 * mvhd_matrix) case FOURCC_fl32: case FOURCC_fl64: case FOURCC_s16l:{ - GNode *fmt, *chnl; + GNode *fmt, *chnl, *chan; // Parse channel layout information for raw PCM fmt = qtdemux_tree_get_child_by_type (stsd, fourcc); chnl = qtdemux_tree_get_child_by_type (fmt, FOURCC_chnl); + chan = qtdemux_tree_get_child_by_type (fmt, FOURCC_chan); if (chnl) { const guint8 *data = chnl->data; @@ -15554,6 +16889,26 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak, guint32 * mvhd_matrix) gst_byte_reader_skip_unchecked (&br, 4 + 4); qtdemux_parse_chnl (qtdemux, &br, stream, entry); } + } else if (chan) { + const guint8 *data = chan->data; + gsize len = QT_UINT32 (data); + if (len >= 8 + 4) { + GstByteReader br = GST_BYTE_READER_INIT (data, len); + // Skip over fourcc and length + gst_byte_reader_skip_unchecked (&br, 4 + 4); + qtdemux_parse_chan (qtdemux, &br, stream, entry); + } + } else { + // Set a default channel mask if all is unknown + guint64 default_mask = + gst_audio_channel_get_fallback_mask (entry->n_channels); + + GST_DEBUG_OBJECT (qtdemux, + "Configuring default channel mask for %u channels", + entry->n_channels); + + gst_caps_set_simple (entry->caps, "channel-mask", + GST_TYPE_BITMASK, default_mask, NULL); } break; }