mov_chan.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. /*
  2. * Copyright (c) 2011 Justin Ruggles
  3. *
  4. * This file is part of Libav.
  5. *
  6. * Libav is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * Libav is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with Libav; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. */
  20. /**
  21. * mov 'chan' tag reading/writing.
  22. * @author Justin Ruggles
  23. */
  24. #include <stdint.h>
  25. #include "libavutil/audioconvert.h"
  26. #include "libavcodec/avcodec.h"
  27. #include "mov_chan.h"
  28. /**
  29. * Channel Layout Tag
  30. * This tells which channels are present in the audio stream and the order in
  31. * which they appear.
  32. *
  33. * @note We're using the channel layout tag to indicate channel order
  34. * when the value is greater than 0x10000. The Apple documentation has
  35. * some contradictions as to how this is actually supposed to be handled.
  36. *
  37. * Core Audio File Format Spec:
  38. * "The high 16 bits indicates a specific ordering of the channels."
  39. * Core Audio Data Types Reference:
  40. * "These identifiers specify the channels included in a layout but
  41. * do not specify a particular ordering of those channels."
  42. */
  43. enum MovChannelLayoutTag {
  44. MOV_CH_LAYOUT_UNKNOWN = 0xFFFF0000,
  45. MOV_CH_LAYOUT_USE_DESCRIPTIONS = ( 0 << 16) | 0,
  46. MOV_CH_LAYOUT_USE_BITMAP = ( 1 << 16) | 0,
  47. MOV_CH_LAYOUT_DISCRETEINORDER = (147 << 16) | 0,
  48. MOV_CH_LAYOUT_MONO = (100 << 16) | 1,
  49. MOV_CH_LAYOUT_STEREO = (101 << 16) | 2,
  50. MOV_CH_LAYOUT_STEREOHEADPHONES = (102 << 16) | 2,
  51. MOV_CH_LAYOUT_MATRIXSTEREO = (103 << 16) | 2,
  52. MOV_CH_LAYOUT_MIDSIDE = (104 << 16) | 2,
  53. MOV_CH_LAYOUT_XY = (105 << 16) | 2,
  54. MOV_CH_LAYOUT_BINAURAL = (106 << 16) | 2,
  55. MOV_CH_LAYOUT_AMBISONIC_B_FORMAT = (107 << 16) | 4,
  56. MOV_CH_LAYOUT_QUADRAPHONIC = (108 << 16) | 4,
  57. MOV_CH_LAYOUT_PENTAGONAL = (109 << 16) | 5,
  58. MOV_CH_LAYOUT_HEXAGONAL = (110 << 16) | 6,
  59. MOV_CH_LAYOUT_OCTAGONAL = (111 << 16) | 8,
  60. MOV_CH_LAYOUT_CUBE = (112 << 16) | 8,
  61. MOV_CH_LAYOUT_MPEG_3_0_A = (113 << 16) | 3,
  62. MOV_CH_LAYOUT_MPEG_3_0_B = (114 << 16) | 3,
  63. MOV_CH_LAYOUT_MPEG_4_0_A = (115 << 16) | 4,
  64. MOV_CH_LAYOUT_MPEG_4_0_B = (116 << 16) | 4,
  65. MOV_CH_LAYOUT_MPEG_5_0_A = (117 << 16) | 5,
  66. MOV_CH_LAYOUT_MPEG_5_0_B = (118 << 16) | 5,
  67. MOV_CH_LAYOUT_MPEG_5_0_C = (119 << 16) | 5,
  68. MOV_CH_LAYOUT_MPEG_5_0_D = (120 << 16) | 5,
  69. MOV_CH_LAYOUT_MPEG_5_1_A = (121 << 16) | 6,
  70. MOV_CH_LAYOUT_MPEG_5_1_B = (122 << 16) | 6,
  71. MOV_CH_LAYOUT_MPEG_5_1_C = (123 << 16) | 6,
  72. MOV_CH_LAYOUT_MPEG_5_1_D = (124 << 16) | 6,
  73. MOV_CH_LAYOUT_MPEG_6_1_A = (125 << 16) | 7,
  74. MOV_CH_LAYOUT_MPEG_7_1_A = (126 << 16) | 8,
  75. MOV_CH_LAYOUT_MPEG_7_1_B = (127 << 16) | 8,
  76. MOV_CH_LAYOUT_MPEG_7_1_C = (128 << 16) | 8,
  77. MOV_CH_LAYOUT_EMAGIC_DEFAULT_7_1 = (129 << 16) | 8,
  78. MOV_CH_LAYOUT_SMPTE_DTV = (130 << 16) | 8,
  79. MOV_CH_LAYOUT_ITU_2_1 = (131 << 16) | 3,
  80. MOV_CH_LAYOUT_ITU_2_2 = (132 << 16) | 4,
  81. MOV_CH_LAYOUT_DVD_4 = (133 << 16) | 3,
  82. MOV_CH_LAYOUT_DVD_5 = (134 << 16) | 4,
  83. MOV_CH_LAYOUT_DVD_6 = (135 << 16) | 5,
  84. MOV_CH_LAYOUT_DVD_10 = (136 << 16) | 4,
  85. MOV_CH_LAYOUT_DVD_11 = (137 << 16) | 5,
  86. MOV_CH_LAYOUT_DVD_18 = (138 << 16) | 5,
  87. MOV_CH_LAYOUT_AUDIOUNIT_6_0 = (139 << 16) | 6,
  88. MOV_CH_LAYOUT_AUDIOUNIT_7_0 = (140 << 16) | 7,
  89. MOV_CH_LAYOUT_AUDIOUNIT_7_0_FRONT = (148 << 16) | 7,
  90. MOV_CH_LAYOUT_AAC_6_0 = (141 << 16) | 6,
  91. MOV_CH_LAYOUT_AAC_6_1 = (142 << 16) | 7,
  92. MOV_CH_LAYOUT_AAC_7_0 = (143 << 16) | 7,
  93. MOV_CH_LAYOUT_AAC_OCTAGONAL = (144 << 16) | 8,
  94. MOV_CH_LAYOUT_TMH_10_2_STD = (145 << 16) | 16,
  95. MOV_CH_LAYOUT_TMH_10_2_FULL = (146 << 16) | 21,
  96. MOV_CH_LAYOUT_AC3_1_0_1 = (149 << 16) | 2,
  97. MOV_CH_LAYOUT_AC3_3_0 = (150 << 16) | 3,
  98. MOV_CH_LAYOUT_AC3_3_1 = (151 << 16) | 4,
  99. MOV_CH_LAYOUT_AC3_3_0_1 = (152 << 16) | 4,
  100. MOV_CH_LAYOUT_AC3_2_1_1 = (153 << 16) | 4,
  101. MOV_CH_LAYOUT_AC3_3_1_1 = (154 << 16) | 5,
  102. MOV_CH_LAYOUT_EAC3_6_0_A = (155 << 16) | 6,
  103. MOV_CH_LAYOUT_EAC3_7_0_A = (156 << 16) | 7,
  104. MOV_CH_LAYOUT_EAC3_6_1_A = (157 << 16) | 7,
  105. MOV_CH_LAYOUT_EAC3_6_1_B = (158 << 16) | 7,
  106. MOV_CH_LAYOUT_EAC3_6_1_C = (159 << 16) | 7,
  107. MOV_CH_LAYOUT_EAC3_7_1_A = (160 << 16) | 8,
  108. MOV_CH_LAYOUT_EAC3_7_1_B = (161 << 16) | 8,
  109. MOV_CH_LAYOUT_EAC3_7_1_C = (162 << 16) | 8,
  110. MOV_CH_LAYOUT_EAC3_7_1_D = (163 << 16) | 8,
  111. MOV_CH_LAYOUT_EAC3_7_1_E = (164 << 16) | 8,
  112. MOV_CH_LAYOUT_EAC3_7_1_F = (165 << 16) | 8,
  113. MOV_CH_LAYOUT_EAC3_7_1_G = (166 << 16) | 8,
  114. MOV_CH_LAYOUT_EAC3_7_1_H = (167 << 16) | 8,
  115. MOV_CH_LAYOUT_DTS_3_1 = (168 << 16) | 4,
  116. MOV_CH_LAYOUT_DTS_4_1 = (169 << 16) | 5,
  117. MOV_CH_LAYOUT_DTS_6_0_A = (170 << 16) | 6,
  118. MOV_CH_LAYOUT_DTS_6_0_B = (171 << 16) | 6,
  119. MOV_CH_LAYOUT_DTS_6_0_C = (172 << 16) | 6,
  120. MOV_CH_LAYOUT_DTS_6_1_A = (173 << 16) | 7,
  121. MOV_CH_LAYOUT_DTS_6_1_B = (174 << 16) | 7,
  122. MOV_CH_LAYOUT_DTS_6_1_C = (175 << 16) | 7,
  123. MOV_CH_LAYOUT_DTS_6_1_D = (182 << 16) | 7,
  124. MOV_CH_LAYOUT_DTS_7_0 = (176 << 16) | 7,
  125. MOV_CH_LAYOUT_DTS_7_1 = (177 << 16) | 8,
  126. MOV_CH_LAYOUT_DTS_8_0_A = (178 << 16) | 8,
  127. MOV_CH_LAYOUT_DTS_8_0_B = (179 << 16) | 8,
  128. MOV_CH_LAYOUT_DTS_8_1_A = (180 << 16) | 9,
  129. MOV_CH_LAYOUT_DTS_8_1_B = (181 << 16) | 9,
  130. };
  131. struct MovChannelLayoutMap {
  132. uint32_t tag;
  133. uint64_t layout;
  134. };
  135. static const struct MovChannelLayoutMap mov_ch_layout_map_misc[] = {
  136. { MOV_CH_LAYOUT_USE_DESCRIPTIONS, 0 },
  137. { MOV_CH_LAYOUT_USE_BITMAP, 0 },
  138. { MOV_CH_LAYOUT_DISCRETEINORDER, 0 },
  139. { MOV_CH_LAYOUT_UNKNOWN, 0 },
  140. { MOV_CH_LAYOUT_TMH_10_2_STD, 0 }, // L, R, C, Vhc, Lsd, Rsd,
  141. // Ls, Rs, Vhl, Vhr, Lw, Rw,
  142. // Csd, Cs, LFE1, LFE2
  143. { MOV_CH_LAYOUT_TMH_10_2_FULL, 0 }, // L, R, C, Vhc, Lsd, Rsd,
  144. // Ls, Rs, Vhl, Vhr, Lw, Rw,
  145. // Csd, Cs, LFE1, LFE2, Lc, Rc,
  146. // HI, VI, Haptic
  147. { 0, 0 },
  148. };
  149. static const struct MovChannelLayoutMap mov_ch_layout_map_1ch[] = {
  150. { MOV_CH_LAYOUT_MONO, AV_CH_LAYOUT_MONO }, // C
  151. };
  152. static const struct MovChannelLayoutMap mov_ch_layout_map_2ch[] = {
  153. { MOV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_STEREO }, // L, R
  154. { MOV_CH_LAYOUT_STEREOHEADPHONES, AV_CH_LAYOUT_STEREO }, // L, R
  155. { MOV_CH_LAYOUT_BINAURAL, AV_CH_LAYOUT_STEREO }, // L, R
  156. { MOV_CH_LAYOUT_MIDSIDE, AV_CH_LAYOUT_STEREO }, // C, sides
  157. { MOV_CH_LAYOUT_XY, AV_CH_LAYOUT_STEREO }, // X (left), Y (right)
  158. { MOV_CH_LAYOUT_MATRIXSTEREO, AV_CH_LAYOUT_STEREO_DOWNMIX }, // Lt, Rt
  159. { MOV_CH_LAYOUT_AC3_1_0_1, AV_CH_LAYOUT_MONO | // C, LFE
  160. AV_CH_LOW_FREQUENCY },
  161. { 0, 0 },
  162. };
  163. static const struct MovChannelLayoutMap mov_ch_layout_map_3ch[] = {
  164. { MOV_CH_LAYOUT_MPEG_3_0_A, AV_CH_LAYOUT_SURROUND }, // L, R, C
  165. { MOV_CH_LAYOUT_MPEG_3_0_B, AV_CH_LAYOUT_SURROUND }, // C, L, R
  166. { MOV_CH_LAYOUT_AC3_3_0, AV_CH_LAYOUT_SURROUND }, // L, C, R
  167. { MOV_CH_LAYOUT_ITU_2_1, AV_CH_LAYOUT_2_1 }, // L, R, Cs
  168. { MOV_CH_LAYOUT_DVD_4, AV_CH_LAYOUT_2POINT1 }, // L, R, LFE
  169. { 0, 0 },
  170. };
  171. static const struct MovChannelLayoutMap mov_ch_layout_map_4ch[] = {
  172. { MOV_CH_LAYOUT_AMBISONIC_B_FORMAT, 0 }, // W, X, Y, Z
  173. { MOV_CH_LAYOUT_QUADRAPHONIC, AV_CH_LAYOUT_QUAD }, // L, R, Rls, Rrs
  174. { MOV_CH_LAYOUT_MPEG_4_0_A, AV_CH_LAYOUT_4POINT0 }, // L, R, C, Cs
  175. { MOV_CH_LAYOUT_MPEG_4_0_B, AV_CH_LAYOUT_4POINT0 }, // C, L, R, Cs
  176. { MOV_CH_LAYOUT_AC3_3_1, AV_CH_LAYOUT_4POINT0 }, // L, C, R, Cs
  177. { MOV_CH_LAYOUT_ITU_2_2, AV_CH_LAYOUT_2_2 }, // L, R, Ls, Rs
  178. { MOV_CH_LAYOUT_DVD_5, AV_CH_LAYOUT_2_1 | // L, R, LFE, Cs
  179. AV_CH_LOW_FREQUENCY },
  180. { MOV_CH_LAYOUT_AC3_2_1_1, AV_CH_LAYOUT_2_1 | // L, R, Cs, LFE
  181. AV_CH_LOW_FREQUENCY },
  182. { MOV_CH_LAYOUT_DVD_10, AV_CH_LAYOUT_3POINT1 }, // L, R, C, LFE
  183. { MOV_CH_LAYOUT_AC3_3_0_1, AV_CH_LAYOUT_3POINT1 }, // L, C, R, LFE
  184. { MOV_CH_LAYOUT_DTS_3_1, AV_CH_LAYOUT_3POINT1 }, // C, L, R, LFE
  185. { 0, 0 },
  186. };
  187. static const struct MovChannelLayoutMap mov_ch_layout_map_5ch[] = {
  188. { MOV_CH_LAYOUT_PENTAGONAL, AV_CH_LAYOUT_5POINT0_BACK }, // L, R, Rls, Rrs, C
  189. { MOV_CH_LAYOUT_MPEG_5_0_A, AV_CH_LAYOUT_5POINT0 }, // L, R, C, Ls, Rs
  190. { MOV_CH_LAYOUT_MPEG_5_0_B, AV_CH_LAYOUT_5POINT0 }, // L, R, Ls, Rs, C
  191. { MOV_CH_LAYOUT_MPEG_5_0_C, AV_CH_LAYOUT_5POINT0 }, // L, C, R, Ls, Rs
  192. { MOV_CH_LAYOUT_MPEG_5_0_D, AV_CH_LAYOUT_5POINT0 }, // C, L, R, Ls, Rs
  193. { MOV_CH_LAYOUT_DVD_6, AV_CH_LAYOUT_2_2 | // L, R, LFE, Ls, Rs
  194. AV_CH_LOW_FREQUENCY },
  195. { MOV_CH_LAYOUT_DVD_18, AV_CH_LAYOUT_2_2 | // L, R, Ls, Rs, LFE
  196. AV_CH_LOW_FREQUENCY },
  197. { MOV_CH_LAYOUT_DVD_11, AV_CH_LAYOUT_4POINT1 }, // L, R, C, LFE, Cs
  198. { MOV_CH_LAYOUT_AC3_3_1_1, AV_CH_LAYOUT_4POINT1 }, // L, C, R, Cs, LFE
  199. { MOV_CH_LAYOUT_DTS_4_1, AV_CH_LAYOUT_4POINT1 }, // C, L, R, Cs, LFE
  200. { 0, 0 },
  201. };
  202. static const struct MovChannelLayoutMap mov_ch_layout_map_6ch[] = {
  203. { MOV_CH_LAYOUT_HEXAGONAL, AV_CH_LAYOUT_HEXAGONAL }, // L, R, Rls, Rrs, C, Cs
  204. { MOV_CH_LAYOUT_DTS_6_0_C, AV_CH_LAYOUT_HEXAGONAL }, // C, Cs, L, R, Rls, Rrs
  205. { MOV_CH_LAYOUT_MPEG_5_1_A, AV_CH_LAYOUT_5POINT1 }, // L, R, C, LFE, Ls, Rs
  206. { MOV_CH_LAYOUT_MPEG_5_1_B, AV_CH_LAYOUT_5POINT1 }, // L, R, Ls, Rs, C, LFE
  207. { MOV_CH_LAYOUT_MPEG_5_1_C, AV_CH_LAYOUT_5POINT1 }, // L, C, R, Ls, Rs, LFE
  208. { MOV_CH_LAYOUT_MPEG_5_1_D, AV_CH_LAYOUT_5POINT1 }, // C, L, R, Ls, Rs, LFE
  209. { MOV_CH_LAYOUT_AUDIOUNIT_6_0, AV_CH_LAYOUT_6POINT0 }, // L, R, Ls, Rs, C, Cs
  210. { MOV_CH_LAYOUT_AAC_6_0, AV_CH_LAYOUT_6POINT0 }, // C, L, R, Ls, Rs, Cs
  211. { MOV_CH_LAYOUT_EAC3_6_0_A, AV_CH_LAYOUT_6POINT0 }, // L, C, R, Ls, Rs, Cs
  212. { MOV_CH_LAYOUT_DTS_6_0_A, AV_CH_LAYOUT_6POINT0_FRONT }, // Lc, Rc, L, R, Ls, Rs
  213. { MOV_CH_LAYOUT_DTS_6_0_B, AV_CH_LAYOUT_5POINT0_BACK | // C, L, R, Rls, Rrs, Ts
  214. AV_CH_TOP_CENTER },
  215. { 0, 0 },
  216. };
  217. static const struct MovChannelLayoutMap mov_ch_layout_map_7ch[] = {
  218. { MOV_CH_LAYOUT_MPEG_6_1_A, AV_CH_LAYOUT_6POINT1 }, // L, R, C, LFE, Ls, Rs, Cs
  219. { MOV_CH_LAYOUT_AAC_6_1, AV_CH_LAYOUT_6POINT1 }, // C, L, R, Ls, Rs, Cs, LFE
  220. { MOV_CH_LAYOUT_EAC3_6_1_A, AV_CH_LAYOUT_6POINT1 }, // L, C, R, Ls, Rs, LFE, Cs
  221. { MOV_CH_LAYOUT_DTS_6_1_D, AV_CH_LAYOUT_6POINT1 }, // C, L, R, Ls, Rs, LFE, Cs
  222. { MOV_CH_LAYOUT_AUDIOUNIT_7_0, AV_CH_LAYOUT_7POINT0 }, // L, R, Ls, Rs, C, Rls, Rrs
  223. { MOV_CH_LAYOUT_AAC_7_0, AV_CH_LAYOUT_7POINT0 }, // C, L, R, Ls, Rs, Rls, Rrs
  224. { MOV_CH_LAYOUT_EAC3_7_0_A, AV_CH_LAYOUT_7POINT0 }, // L, C, R, Ls, Rs, Rls, Rrs
  225. { MOV_CH_LAYOUT_AUDIOUNIT_7_0_FRONT, AV_CH_LAYOUT_7POINT0_FRONT }, // L, R, Ls, Rs, C, Lc, Rc
  226. { MOV_CH_LAYOUT_DTS_7_0, AV_CH_LAYOUT_7POINT0_FRONT }, // Lc, C, Rc, L, R, Ls, Rs
  227. { MOV_CH_LAYOUT_EAC3_6_1_B, AV_CH_LAYOUT_5POINT1 | // L, C, R, Ls, Rs, LFE, Ts
  228. AV_CH_TOP_CENTER },
  229. { MOV_CH_LAYOUT_EAC3_6_1_C, AV_CH_LAYOUT_5POINT1 | // L, C, R, Ls, Rs, LFE, Vhc
  230. AV_CH_TOP_FRONT_CENTER },
  231. { MOV_CH_LAYOUT_DTS_6_1_A, AV_CH_LAYOUT_6POINT1_FRONT }, // Lc, Rc, L, R, Ls, Rs, LFE
  232. { MOV_CH_LAYOUT_DTS_6_1_B, AV_CH_LAYOUT_5POINT1_BACK | // C, L, R, Rls, Rrs, Ts, LFE
  233. AV_CH_TOP_CENTER },
  234. { MOV_CH_LAYOUT_DTS_6_1_C, AV_CH_LAYOUT_6POINT1_BACK }, // C, Cs, L, R, Rls, Rrs, LFE
  235. { 0, 0 },
  236. };
  237. static const struct MovChannelLayoutMap mov_ch_layout_map_8ch[] = {
  238. { MOV_CH_LAYOUT_OCTAGONAL, AV_CH_LAYOUT_OCTAGONAL }, // L, R, Rls, Rrs, C, Cs, Ls, Rs
  239. { MOV_CH_LAYOUT_AAC_OCTAGONAL, AV_CH_LAYOUT_OCTAGONAL }, // C, L, R, Ls, Rs, Rls, Rrs, Cs
  240. { MOV_CH_LAYOUT_CUBE, AV_CH_LAYOUT_QUAD | // L, R, Rls, Rrs, Vhl, Vhr, Rlt, Rrt
  241. AV_CH_TOP_FRONT_LEFT |
  242. AV_CH_TOP_FRONT_RIGHT |
  243. AV_CH_TOP_BACK_LEFT |
  244. AV_CH_TOP_BACK_RIGHT },
  245. { MOV_CH_LAYOUT_MPEG_7_1_A, AV_CH_LAYOUT_7POINT1_WIDE }, // L, R, C, LFE, Ls, Rs, Lc, Rc
  246. { MOV_CH_LAYOUT_MPEG_7_1_B, AV_CH_LAYOUT_7POINT1_WIDE }, // C, Lc, Rc, L, R, Ls, Rs, LFE
  247. { MOV_CH_LAYOUT_EMAGIC_DEFAULT_7_1, AV_CH_LAYOUT_7POINT1_WIDE }, // L, R, Ls, Rs, C, LFE, Lc, Rc
  248. { MOV_CH_LAYOUT_EAC3_7_1_B, AV_CH_LAYOUT_7POINT1_WIDE }, // L, C, R, Ls, Rs, LFE, Lc, Rc
  249. { MOV_CH_LAYOUT_DTS_7_1, AV_CH_LAYOUT_7POINT1_WIDE }, // Lc, C, Rc, L, R, Ls, Rs, LFE
  250. { MOV_CH_LAYOUT_MPEG_7_1_C, AV_CH_LAYOUT_7POINT1 }, // L, R, C, LFE, Ls, Rs, Rls, Rrs
  251. { MOV_CH_LAYOUT_EAC3_7_1_A, AV_CH_LAYOUT_7POINT1 }, // L, C, R, Ls, Rs, LFE, Rls, Rrs
  252. { MOV_CH_LAYOUT_SMPTE_DTV, AV_CH_LAYOUT_5POINT1 | // L, R, C, LFE, Ls, Rs, Lt, Rt
  253. AV_CH_LAYOUT_STEREO_DOWNMIX },
  254. { MOV_CH_LAYOUT_EAC3_7_1_C, AV_CH_LAYOUT_5POINT1 | // L, C, R, Ls, Rs, LFE, Lsd, Rsd
  255. AV_CH_SURROUND_DIRECT_LEFT |
  256. AV_CH_SURROUND_DIRECT_RIGHT },
  257. { MOV_CH_LAYOUT_EAC3_7_1_D, AV_CH_LAYOUT_5POINT1 | // L, C, R, Ls, Rs, LFE, Lw, Rw
  258. AV_CH_WIDE_LEFT |
  259. AV_CH_WIDE_RIGHT },
  260. { MOV_CH_LAYOUT_EAC3_7_1_E, AV_CH_LAYOUT_5POINT1 | // L, C, R, Ls, Rs, LFE, Vhl, Vhr
  261. AV_CH_TOP_FRONT_LEFT |
  262. AV_CH_TOP_FRONT_RIGHT },
  263. { MOV_CH_LAYOUT_EAC3_7_1_F, AV_CH_LAYOUT_5POINT1 | // L, C, R, Ls, Rs, LFE, Cs, Ts
  264. AV_CH_BACK_CENTER |
  265. AV_CH_TOP_CENTER },
  266. { MOV_CH_LAYOUT_EAC3_7_1_G, AV_CH_LAYOUT_5POINT1 | // L, C, R, Ls, Rs, LFE, Cs, Vhc
  267. AV_CH_BACK_CENTER |
  268. AV_CH_TOP_FRONT_CENTER },
  269. { MOV_CH_LAYOUT_EAC3_7_1_H, AV_CH_LAYOUT_5POINT1 | // L, C, R, Ls, Rs, LFE, Ts, Vhc
  270. AV_CH_TOP_CENTER |
  271. AV_CH_TOP_FRONT_CENTER },
  272. { MOV_CH_LAYOUT_DTS_8_0_A, AV_CH_LAYOUT_2_2 | // Lc, Rc, L, R, Ls, Rs, Rls, Rrs
  273. AV_CH_BACK_LEFT |
  274. AV_CH_BACK_RIGHT |
  275. AV_CH_FRONT_LEFT_OF_CENTER |
  276. AV_CH_FRONT_RIGHT_OF_CENTER },
  277. { MOV_CH_LAYOUT_DTS_8_0_B, AV_CH_LAYOUT_5POINT0 | // Lc, C, Rc, L, R, Ls, Cs, Rs
  278. AV_CH_FRONT_LEFT_OF_CENTER |
  279. AV_CH_FRONT_RIGHT_OF_CENTER |
  280. AV_CH_BACK_CENTER },
  281. { 0, 0 },
  282. };
  283. static const struct MovChannelLayoutMap mov_ch_layout_map_9ch[] = {
  284. { MOV_CH_LAYOUT_DTS_8_1_A, AV_CH_LAYOUT_2_2 | // Lc, Rc, L, R, Ls, Rs, Rls, Rrs, LFE
  285. AV_CH_BACK_LEFT |
  286. AV_CH_BACK_RIGHT |
  287. AV_CH_FRONT_LEFT_OF_CENTER |
  288. AV_CH_FRONT_RIGHT_OF_CENTER |
  289. AV_CH_LOW_FREQUENCY },
  290. { MOV_CH_LAYOUT_DTS_8_1_B, AV_CH_LAYOUT_7POINT1_WIDE | // Lc, C, Rc, L, R, Ls, Cs, Rs, LFE
  291. AV_CH_BACK_CENTER },
  292. { 0, 0 },
  293. };
  294. static const struct MovChannelLayoutMap *mov_ch_layout_map[] = {
  295. mov_ch_layout_map_misc,
  296. mov_ch_layout_map_1ch,
  297. mov_ch_layout_map_2ch,
  298. mov_ch_layout_map_3ch,
  299. mov_ch_layout_map_4ch,
  300. mov_ch_layout_map_5ch,
  301. mov_ch_layout_map_6ch,
  302. mov_ch_layout_map_7ch,
  303. mov_ch_layout_map_8ch,
  304. mov_ch_layout_map_9ch,
  305. };
  306. static const enum MovChannelLayoutTag mov_ch_layouts_aac[] = {
  307. MOV_CH_LAYOUT_MONO,
  308. MOV_CH_LAYOUT_STEREO,
  309. MOV_CH_LAYOUT_AC3_1_0_1,
  310. MOV_CH_LAYOUT_MPEG_3_0_B,
  311. MOV_CH_LAYOUT_ITU_2_1,
  312. MOV_CH_LAYOUT_DVD_4,
  313. MOV_CH_LAYOUT_QUADRAPHONIC,
  314. MOV_CH_LAYOUT_MPEG_4_0_B,
  315. MOV_CH_LAYOUT_ITU_2_2,
  316. MOV_CH_LAYOUT_AC3_2_1_1,
  317. MOV_CH_LAYOUT_DTS_3_1,
  318. MOV_CH_LAYOUT_MPEG_5_0_D,
  319. MOV_CH_LAYOUT_DVD_18,
  320. MOV_CH_LAYOUT_DTS_4_1,
  321. MOV_CH_LAYOUT_MPEG_5_1_D,
  322. MOV_CH_LAYOUT_AAC_6_0,
  323. MOV_CH_LAYOUT_DTS_6_0_A,
  324. MOV_CH_LAYOUT_AAC_6_1,
  325. MOV_CH_LAYOUT_AAC_7_0,
  326. MOV_CH_LAYOUT_DTS_6_1_A,
  327. MOV_CH_LAYOUT_AAC_OCTAGONAL,
  328. MOV_CH_LAYOUT_MPEG_7_1_B,
  329. MOV_CH_LAYOUT_DTS_8_0_A,
  330. 0,
  331. };
  332. static const enum MovChannelLayoutTag mov_ch_layouts_ac3[] = {
  333. MOV_CH_LAYOUT_MONO,
  334. MOV_CH_LAYOUT_STEREO,
  335. MOV_CH_LAYOUT_AC3_1_0_1,
  336. MOV_CH_LAYOUT_AC3_3_0,
  337. MOV_CH_LAYOUT_ITU_2_1,
  338. MOV_CH_LAYOUT_DVD_4,
  339. MOV_CH_LAYOUT_AC3_3_1,
  340. MOV_CH_LAYOUT_ITU_2_2,
  341. MOV_CH_LAYOUT_AC3_2_1_1,
  342. MOV_CH_LAYOUT_AC3_3_0_1,
  343. MOV_CH_LAYOUT_MPEG_5_0_C,
  344. MOV_CH_LAYOUT_DVD_18,
  345. MOV_CH_LAYOUT_AC3_3_1_1,
  346. MOV_CH_LAYOUT_MPEG_5_1_C,
  347. 0,
  348. };
  349. static const enum MovChannelLayoutTag mov_ch_layouts_alac[] = {
  350. MOV_CH_LAYOUT_MONO,
  351. MOV_CH_LAYOUT_STEREO,
  352. MOV_CH_LAYOUT_MPEG_3_0_B,
  353. MOV_CH_LAYOUT_MPEG_4_0_B,
  354. MOV_CH_LAYOUT_MPEG_5_0_D,
  355. MOV_CH_LAYOUT_MPEG_5_1_D,
  356. MOV_CH_LAYOUT_AAC_6_1,
  357. MOV_CH_LAYOUT_MPEG_7_1_B,
  358. 0,
  359. };
  360. static const struct {
  361. enum CodecID codec_id;
  362. const enum MovChannelLayoutTag *layouts;
  363. } mov_codec_ch_layouts[] = {
  364. { CODEC_ID_AAC, mov_ch_layouts_aac },
  365. { CODEC_ID_AC3, mov_ch_layouts_ac3 },
  366. { CODEC_ID_ALAC, mov_ch_layouts_alac },
  367. { CODEC_ID_NONE, NULL },
  368. };
  369. uint64_t ff_mov_get_channel_layout(uint32_t tag, uint32_t bitmap)
  370. {
  371. int i, channels;
  372. const struct MovChannelLayoutMap *layout_map;
  373. /* use ff_mov_get_channel_label() to build a layout instead */
  374. if (tag == MOV_CH_LAYOUT_USE_DESCRIPTIONS)
  375. return 0;
  376. /* handle the use of the channel bitmap */
  377. if (tag == MOV_CH_LAYOUT_USE_BITMAP)
  378. return bitmap < 0x40000 ? bitmap : 0;
  379. /* get the layout map based on the channel count for the specified layout tag */
  380. channels = tag & 0xFFFF;
  381. if (channels > 9)
  382. channels = 0;
  383. layout_map = mov_ch_layout_map[channels];
  384. /* find the channel layout for the specified layout tag */
  385. for (i = 0; layout_map[i].tag != 0; i++) {
  386. if (layout_map[i].tag == tag)
  387. break;
  388. }
  389. return layout_map[i].layout;
  390. }
  391. uint32_t ff_mov_get_channel_label(uint32_t label)
  392. {
  393. if (label == 0)
  394. return 0;
  395. if (label <= 18)
  396. return 1U << (label - 1);
  397. if (label == 38)
  398. return AV_CH_STEREO_LEFT;
  399. if (label == 39)
  400. return AV_CH_STEREO_RIGHT;
  401. return 0;
  402. }
  403. uint32_t ff_mov_get_channel_layout_tag(enum CodecID codec_id,
  404. uint64_t channel_layout,
  405. uint32_t *bitmap)
  406. {
  407. int i, j;
  408. uint32_t tag = 0;
  409. const enum MovChannelLayoutTag *layouts = NULL;
  410. /* find the layout list for the specified codec */
  411. for (i = 0; mov_codec_ch_layouts[i].codec_id != CODEC_ID_NONE; i++) {
  412. if (mov_codec_ch_layouts[i].codec_id == codec_id)
  413. break;
  414. }
  415. if (mov_codec_ch_layouts[i].codec_id != CODEC_ID_NONE)
  416. layouts = mov_codec_ch_layouts[i].layouts;
  417. if (layouts) {
  418. int channels;
  419. const struct MovChannelLayoutMap *layout_map;
  420. /* get the layout map based on the channel count */
  421. channels = av_get_channel_layout_nb_channels(channel_layout);
  422. if (channels > 9)
  423. channels = 0;
  424. layout_map = mov_ch_layout_map[channels];
  425. /* find the layout tag for the specified channel layout */
  426. for (i = 0; layouts[i] != 0; i++) {
  427. if (layouts[i] & 0xFFFF != channels)
  428. continue;
  429. for (j = 0; layout_map[j].tag != 0; j++) {
  430. if (layout_map[j].tag == layouts[i] &&
  431. layout_map[j].layout == channel_layout)
  432. break;
  433. }
  434. if (layout_map[j].tag)
  435. break;
  436. }
  437. tag = layouts[i];
  438. }
  439. /* if no tag was found, use channel bitmap as a backup if possible */
  440. if (tag == 0 && channel_layout > 0 && channel_layout < 0x40000) {
  441. tag = MOV_CH_LAYOUT_USE_BITMAP;
  442. *bitmap = (uint32_t)channel_layout;
  443. } else
  444. *bitmap = 0;
  445. /* TODO: set channel descriptions as a secondary backup */
  446. return tag;
  447. }