1 /*******************************************************************************
2  chan.c
3 
4  libquicktime - A library for reading and writing quicktime/avi/mp4 files.
5  http://libquicktime.sourceforge.net
6 
7  Copyright (C) 2002 Heroine Virtual Ltd.
8  Copyright (C) 2002-2011 Members of the libquicktime project.
9 
10  This library is free software; you can redistribute it and/or modify it under
11  the terms of the GNU Lesser General Public License as published by the Free
12  Software Foundation; either version 2.1 of the License, or (at your option)
13  any later version.
14 
15  This library is distributed in the hope that it will be useful, but WITHOUT
16  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17  FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
18  details.
19 
20  You should have received a copy of the GNU Lesser General Public License along
21  with this library; if not, write to the Free Software Foundation, Inc., 51
22  Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 *******************************************************************************/
24 
25 #include "lqt_private.h"
26 #include <stdlib.h>
27 
28 /*
29  *  Quicktime chan atom.
30  *
31  *  I didn't find any official documentation about the channel
32  *  description atom (which is needed for multichannel support).
33  *  There is, however this document about the CAF format by Apple:
34  *
35  *  http://developer.apple.com/documentation/MusicAudio/Reference/CAFSpec/index.html
36 
37  *  The guess was, that the chan atoms in CAF and Quicktime files are the same,
38  *  and the guess turned out to be true :)
39  */
40 
41 typedef enum
42   {
43     CHANNEL_LABEL_Unknown    = 0xFFFFFFFF,   // unknown role or uspecified
44                                                 // other use for channel
45     CHANNEL_LABEL_Unused     = 0,            // channel is present, but
46                                                 // has no intended role or destination
47     CHANNEL_LABEL_UseCoordinates         = 100,  // channel is described
48                                                 // solely by the mCoordinates fields
49 
50     CHANNEL_LABEL_Left                   = 1,
51     CHANNEL_LABEL_Right                  = 2,
52     CHANNEL_LABEL_Center                 = 3,
53     CHANNEL_LABEL_LFEScreen              = 4,
54     CHANNEL_LABEL_LeftSurround           = 5,    // WAVE (.wav files): "Back Left"
55     CHANNEL_LABEL_RightSurround          = 6,    // WAVE: "Back Right"
56     CHANNEL_LABEL_LeftCenter             = 7,
57     CHANNEL_LABEL_RightCenter            = 8,
58     CHANNEL_LABEL_CenterSurround         = 9,    // WAVE: "Back Center or
59                                                     // plain "Rear Surround"
60     CHANNEL_LABEL_LeftSurroundDirect     = 10,   // WAVE: "Side Left"
61     CHANNEL_LABEL_RightSurroundDirect    = 11,   // WAVE: "Side Right"
62     CHANNEL_LABEL_TopCenterSurround      = 12,
63     CHANNEL_LABEL_VerticalHeightLeft     = 13,   // WAVE: "Top Front Left
64     CHANNEL_LABEL_VerticalHeightCenter   = 14,   // WAVE: "Top Front Center
65     CHANNEL_LABEL_VerticalHeightRight    = 15,   // WAVE: "Top Front Right
66     CHANNEL_LABEL_TopBackLeft            = 16,
67     CHANNEL_LABEL_TopBackCenter          = 17,
68     CHANNEL_LABEL_TopBackRight           = 18,
69     CHANNEL_LABEL_RearSurroundLeft       = 33,
70     CHANNEL_LABEL_RearSurroundRight      = 34,
71     CHANNEL_LABEL_LeftWide               = 35,
72     CHANNEL_LABEL_RightWide              = 36,
73     CHANNEL_LABEL_LFE2                   = 37,
74     CHANNEL_LABEL_LeftTotal              = 38,   // matrix encoded 4 channels
75     CHANNEL_LABEL_RightTotal             = 39,   // matrix encoded 4 channels
76     CHANNEL_LABEL_HearingImpaired        = 40,
77     CHANNEL_LABEL_Narration              = 41,
78     CHANNEL_LABEL_Mono                   = 42,
79     CHANNEL_LABEL_DialogCentricMix       = 43,
80 
81     CHANNEL_LABEL_CenterSurroundDirect   = 44,   // back center, non diffuse
82 
83     // first order ambisonic channels
84 
85     CHANNEL_LABEL_Ambisonic_W            = 200,
86     CHANNEL_LABEL_Ambisonic_X            = 201,
87     CHANNEL_LABEL_Ambisonic_Y            = 202,
88     CHANNEL_LABEL_Ambisonic_Z            = 203,
89 
90     // Mid/Side Recording
91 
92     CHANNEL_LABEL_MS_Mid                 = 204,
93     CHANNEL_LABEL_MS_Side                = 205,
94 
95     // X-Y Recording
96 
97     CHANNEL_LABEL_XY_X                   = 206,
98     CHANNEL_LABEL_XY_Y                   = 207,
99 
100     // other
101 
102     CHANNEL_LABEL_HeadphonesLeft         = 301,
103     CHANNEL_LABEL_HeadphonesRight        = 302,
104     CHANNEL_LABEL_ClickTrack             = 304,
105     CHANNEL_LABEL_ForeignLanguage        = 305
106   } channel_label_t;
107 
108 static struct
109   {
110   channel_label_t label;
111   char * name;
112   }
113 channel_label_names[] =
114   {
115     { CHANNEL_LABEL_Unknown,              "Unknown" },
116     { CHANNEL_LABEL_Unused,               "Unused" },
117                                                 // has no intended role or destination
118     { CHANNEL_LABEL_UseCoordinates,       "Use Coordinates" },
119 
120     { CHANNEL_LABEL_Left,                 "Left" },
121     { CHANNEL_LABEL_Right,                "Right" },
122     { CHANNEL_LABEL_Center,               "Center" },
123     { CHANNEL_LABEL_LFEScreen,            "LFE" },
124     { CHANNEL_LABEL_LeftSurround,         "Left Surround" },  // WAVE (.wav files): Back Left
125     { CHANNEL_LABEL_RightSurround,        "Right Surround" }, // WAVE: "Back Right"
126     { CHANNEL_LABEL_LeftCenter,           "Left Center" },
127     { CHANNEL_LABEL_RightCenter,          "Right Center" },
128     { CHANNEL_LABEL_CenterSurround,       "Center Surround" }, // WAVE: "Back Center or
129                                                                // plain "Rear Surround"
130     { CHANNEL_LABEL_LeftSurroundDirect,   "Side Left" },       // WAVE: "Side Left"
131     { CHANNEL_LABEL_RightSurroundDirect,  "Side Right" },      // WAVE: "Side Right"
132     { CHANNEL_LABEL_TopCenterSurround,    "Top Center Surround" },
133     { CHANNEL_LABEL_VerticalHeightLeft,   "Top Front Left" },  // WAVE: Top Front Left
134     { CHANNEL_LABEL_VerticalHeightCenter, "Top Front Center" },  // WAVE: Top Front Center
135     { CHANNEL_LABEL_VerticalHeightRight,  "Top Front Right" },   // WAVE: "Top Front Right"
136     { CHANNEL_LABEL_TopBackLeft,          "Top Back Left" },
137     { CHANNEL_LABEL_TopBackCenter,        "Top Back Center" } ,
138     { CHANNEL_LABEL_TopBackRight,         "Top Back Right" },
139     { CHANNEL_LABEL_RearSurroundLeft,     "Rear Surround Left" },
140     { CHANNEL_LABEL_RearSurroundRight,    "Rear Surround Right" },
141     { CHANNEL_LABEL_LeftWide,             "Left Wide" },
142     { CHANNEL_LABEL_RightWide,            "Right Wide" },
143     { CHANNEL_LABEL_LFE2,                 "LFE 2" },
144     { CHANNEL_LABEL_LeftTotal,            "Left Total" },    // matrix encoded 4 channels
145     { CHANNEL_LABEL_RightTotal,           "Right Total" },   // matrix encoded 4 channels
146     { CHANNEL_LABEL_HearingImpaired,      "Hearing Impaired" },
147     { CHANNEL_LABEL_Narration,            "Narration" },
148     { CHANNEL_LABEL_Mono,                 "Mono" },
149     { CHANNEL_LABEL_DialogCentricMix,     "Dialog Centric Mix" },
150 
151     { CHANNEL_LABEL_CenterSurroundDirect, "Center Surround Direct" },  // back center, non diffuse
152 
153     // first order ambisonic channels
154 
155     { CHANNEL_LABEL_Ambisonic_W, "Ambisonic W" },
156     { CHANNEL_LABEL_Ambisonic_X, "Ambisonic X" },
157     { CHANNEL_LABEL_Ambisonic_Y, "Ambisonic Y" },
158     { CHANNEL_LABEL_Ambisonic_Z, "Ambisonic Z" },
159 
160     // Mid/Side Recording
161 
162     { CHANNEL_LABEL_MS_Mid,  "MS Mid" },
163     { CHANNEL_LABEL_MS_Side,  "MS Side" },
164 
165     // X-Y Recording
166 
167     { CHANNEL_LABEL_XY_X, "Label XY X" },
168     { CHANNEL_LABEL_XY_Y, "Label XY Y" },
169 
170     // other
171 
172     { CHANNEL_LABEL_HeadphonesLeft, "Headphones Left" },
173     { CHANNEL_LABEL_HeadphonesRight, "Headphones Right" },
174     { CHANNEL_LABEL_ClickTrack,      "Click Track" },
175     { CHANNEL_LABEL_ForeignLanguage,  "Foreign Language" },
176 
177   };
178 
get_channel_name(channel_label_t label)179 static const char * get_channel_name(channel_label_t label)
180   {
181   int i;
182   for(i = 0; i < sizeof(channel_label_names)/sizeof(channel_label_names[0]); i++)
183     {
184     if(channel_label_names[i].label == label)
185       return channel_label_names[i].name;
186     }
187   return (char*)0;
188   }
189 
190 typedef enum
191   {
192     CHANNEL_BIT_Left                 = (1<<0),
193     CHANNEL_BIT_Right                = (1<<1),
194     CHANNEL_BIT_Center               = (1<<2),
195     CHANNEL_BIT_LFEScreen            = (1<<3),
196     CHANNEL_BIT_LeftSurround         = (1<<4),   // WAVE: "Back Left"
197     CHANNEL_BIT_RightSurround        = (1<<5),   // WAVE: "Back Right"
198     CHANNEL_BIT_LeftCenter           = (1<<6),
199     CHANNEL_BIT_RightCenter          = (1<<7),
200     CHANNEL_BIT_CenterSurround       = (1<<8),   // WAVE: "Back Center"
201     CHANNEL_BIT_LeftSurroundDirect   = (1<<9),   // WAVE: "Side Left"
202     CHANNEL_BIT_RightSurroundDirect  = (1<<10), // WAVE: "Side Right"
203     CHANNEL_BIT_TopCenterSurround    = (1<<11),
204     CHANNEL_BIT_VerticalHeightLeft   = (1<<12), // WAVE: "Top Front Left"
205     CHANNEL_BIT_VerticalHeightCenter = (1<<13), // WAVE: "Top Front Center"
206     CHANNEL_BIT_VerticalHeightRight  = (1<<14), // WAVE: "Top Front Right"
207     CHANNEL_BIT_TopBackLeft          = (1<<15),
208     CHANNEL_BIT_TopBackCenter        = (1<<16),
209     CHANNEL_BIT_TopBackRight         = (1<<17)
210   } channel_bit_t;
211 
212 static struct
213   {
214   channel_bit_t bit;
215   channel_label_t label;
216   }
217 channel_bits[] =
218   {
219     { CHANNEL_BIT_Left,                 CHANNEL_LABEL_Left },
220     { CHANNEL_BIT_Right,                CHANNEL_LABEL_Right },
221     { CHANNEL_BIT_Center,               CHANNEL_LABEL_Center },
222     { CHANNEL_BIT_LFEScreen,            CHANNEL_LABEL_LFEScreen },
223     { CHANNEL_BIT_LeftSurround,         CHANNEL_LABEL_LeftSurround }, // WAVE: "Back Left"
224     { CHANNEL_BIT_RightSurround,        CHANNEL_LABEL_RightSurround },// WAVE: "Back Right"
225     { CHANNEL_BIT_LeftCenter,           CHANNEL_LABEL_LeftCenter    },
226     { CHANNEL_BIT_RightCenter,          CHANNEL_LABEL_RightCenter },
227     { CHANNEL_BIT_CenterSurround,       CHANNEL_LABEL_CenterSurround }, // WAVE: "Back Center"
228     { CHANNEL_BIT_LeftSurroundDirect,   CHANNEL_LABEL_LeftSurroundDirect },   // WAVE: "Side Left"
229     { CHANNEL_BIT_RightSurroundDirect,  CHANNEL_LABEL_RightSurroundDirect }, // WAVE: "Side Right"
230     { CHANNEL_BIT_TopCenterSurround,    CHANNEL_LABEL_TopCenterSurround },
231     { CHANNEL_BIT_VerticalHeightLeft,   CHANNEL_LABEL_VerticalHeightLeft }, // WAVE: "Top Front Left"
232     { CHANNEL_BIT_VerticalHeightCenter, CHANNEL_LABEL_VerticalHeightCenter }, // WAVE: "Top Front Center"
233     { CHANNEL_BIT_VerticalHeightRight,  CHANNEL_LABEL_VerticalHeightRight }, // WAVE: "Top Front Right"
234     { CHANNEL_BIT_TopBackLeft,          CHANNEL_LABEL_TopBackLeft },
235     { CHANNEL_BIT_TopBackCenter,        CHANNEL_LABEL_TopBackCenter },
236     { CHANNEL_BIT_TopBackRight,         CHANNEL_LABEL_TopBackRight },
237   };
238 
channel_bit_2_channel_label(uint32_t bit)239 static channel_label_t channel_bit_2_channel_label(uint32_t bit)
240   {
241   int i;
242   for(i = 0; i < sizeof(channel_bits) / sizeof(channel_bits[0]); i++)
243     {
244     if(bit == channel_bits[i].bit)
245       return channel_bits[i].label;
246     }
247   return CHANNEL_LABEL_Unknown;
248   }
249 
250 static struct
251   {
252   lqt_channel_t lqt_channel;
253   channel_label_t channel_label;
254   }
255 lqt_channels[] =
256   {
257     { LQT_CHANNEL_UNKNOWN,            CHANNEL_LABEL_Unknown },
258     { LQT_CHANNEL_FRONT_LEFT,         CHANNEL_LABEL_Left },
259     { LQT_CHANNEL_FRONT_RIGHT,        CHANNEL_LABEL_Right },
260     { LQT_CHANNEL_FRONT_CENTER,       CHANNEL_LABEL_Center },
261     { LQT_CHANNEL_FRONT_CENTER_LEFT,  CHANNEL_LABEL_LeftCenter },
262     { LQT_CHANNEL_FRONT_CENTER_RIGHT, CHANNEL_LABEL_RightCenter },
263     { LQT_CHANNEL_BACK_CENTER,        CHANNEL_LABEL_CenterSurround },
264     { LQT_CHANNEL_BACK_LEFT,          CHANNEL_LABEL_LeftSurround },
265     { LQT_CHANNEL_BACK_RIGHT,         CHANNEL_LABEL_RightSurround },
266     { LQT_CHANNEL_SIDE_LEFT,          CHANNEL_LABEL_LeftSurroundDirect },
267     { LQT_CHANNEL_SIDE_RIGHT,         CHANNEL_LABEL_RightSurroundDirect },
268     { LQT_CHANNEL_LFE,                CHANNEL_LABEL_LFEScreen },
269   };
270 
channel_label_2_channel(channel_label_t channel_label)271 static lqt_channel_t channel_label_2_channel(channel_label_t channel_label)
272   {
273   int i;
274   for(i = 0; i < sizeof(lqt_channels)/sizeof(lqt_channels[0]); i++)
275     {
276     if(lqt_channels[i].channel_label == channel_label)
277       return lqt_channels[i].lqt_channel;
278     }
279   return LQT_CHANNEL_UNKNOWN;
280   }
281 
channel_2_channel_label(lqt_channel_t channel)282 static channel_label_t channel_2_channel_label(lqt_channel_t channel)
283   {
284   int i;
285   for(i = 0; i < sizeof(lqt_channels)/sizeof(lqt_channels[0]); i++)
286     {
287     if(lqt_channels[i].lqt_channel == channel)
288       return lqt_channels[i].channel_label;
289     }
290   return CHANNEL_LABEL_Unknown;
291   }
292 
293 
294 /* Layout tags */
295 
296 typedef enum
297   {
298     CHANNEL_LAYOUT_UseChannelDescriptions = (0<<16) | 0, // use the array of AudioChannelDescriptions to define the mapping.
299     CHANNEL_LAYOUT_UseChannelBitmap       = (1<<16) | 0, // use the bitmap to define the mapping.
300 
301 // 1 Channel Layout
302 
303     CHANNEL_LAYOUT_Mono                   = (100<<16) | 1, // a standard mono stream
304 
305 // 2 Channel layouts
306 
307     CHANNEL_LAYOUT_Stereo                 = (101<<16) | 2, // a standard stereo stream (L R)
308     CHANNEL_LAYOUT_StereoHeadphones       = (102<<16) | 2, // a standard stereo stream (L R) - implied headphone playback
309 
310     CHANNEL_LAYOUT_MatrixStereo           = (103<<16) | 2, // a matrix encoded stereo stream (Lt, Rt)
311     CHANNEL_LAYOUT_MidSide                = (104<<16) | 2, // mid/side recording
312     CHANNEL_LAYOUT_XY                     = (105<<16) | 2, // coincident mic pair (often 2 figure 8's)
313 
314     CHANNEL_LAYOUT_Binaural               = (106<<16) | 2, // binaural stereo (left, right)
315 
316 // Symetric arrangements - same distance between speaker locations
317 
318     CHANNEL_LAYOUT_Ambisonic_B_Format     = (107<<16) | 4, // W, X, Y, Z
319     CHANNEL_LAYOUT_Quadraphonic           = (108<<16) | 4, // front left, front right, back left, back right
320     CHANNEL_LAYOUT_Pentagonal             = (109<<16) | 5, // left, right, rear left, rear right, center
321     CHANNEL_LAYOUT_Hexagonal              = (110<<16) | 6, // left, right, rear left, rear right, center, rear
322     CHANNEL_LAYOUT_Octagonal              = (111<<16) | 8, // front left, front right, rear left, rear right,
323                                                                  // front center, rear center, side left, side right
324     CHANNEL_LAYOUT_Cube                   = (112<<16) | 8, // left, right, rear left, rear right
325                                                                  // top left, top right, top rear left, top rear right
326 
327 //  MPEG defined layouts
328 
329     CHANNEL_LAYOUT_MPEG_1_0   = CHANNEL_LAYOUT_Mono,    //  C
330     CHANNEL_LAYOUT_MPEG_2_0   = CHANNEL_LAYOUT_Stereo,  //  L R
331     CHANNEL_LAYOUT_MPEG_3_0_A = (113<<16) | 3,         // L R C
332     CHANNEL_LAYOUT_MPEG_3_0_B = (114<<16) | 3,         // C L R
333     CHANNEL_LAYOUT_MPEG_4_0_A = (115<<16) | 4,         // L R C Cs
334     CHANNEL_LAYOUT_MPEG_4_0_B = (116<<16) | 4,         // C L R Cs
335     CHANNEL_LAYOUT_MPEG_5_0_A = (117<<16) | 5,         // L R C Ls Rs
336     CHANNEL_LAYOUT_MPEG_5_0_B = (118<<16) | 5,         // L R Ls Rs C
337     CHANNEL_LAYOUT_MPEG_5_0_C = (119<<16) | 5,         // L C R Ls Rs
338     CHANNEL_LAYOUT_MPEG_5_0_D = (120<<16) | 5,         // C L R Ls Rs
339     CHANNEL_LAYOUT_MPEG_5_1_A = (121<<16) | 6,         // L R C LFE Ls Rs
340     CHANNEL_LAYOUT_MPEG_5_1_B = (122<<16) | 6,         // L R Ls Rs C LFE
341     CHANNEL_LAYOUT_MPEG_5_1_C = (123<<16) | 6,         // L C R Ls Rs LFE
342     CHANNEL_LAYOUT_MPEG_5_1_D = (124<<16) | 6,         // C L R Ls Rs LFE
343     CHANNEL_LAYOUT_MPEG_6_1_A = (125<<16) | 7,         // L R C LFE Ls Rs Cs
344     CHANNEL_LAYOUT_MPEG_7_1_A = (126<<16) | 8,         // L R C LFE Ls Rs Lc Rc
345     CHANNEL_LAYOUT_MPEG_7_1_B = (127<<16) | 8,         // C Lc Rc L R Ls Rs LFE
346     CHANNEL_LAYOUT_MPEG_7_1_C = (128<<16) | 8,         // L R C LFE Ls R Rls Rrs
347     CHANNEL_LAYOUT_Emagic_Default_7_1 = (129<<16) | 8, //  L R Ls Rs C LFE Lc Rc
348     CHANNEL_LAYOUT_SMPTE_DTV          = (130<<16) | 8, //  L R C LFE Ls Rs Lt Rt
349                                                              //  (CHANNEL_LAYOUT_ITU_5_1 plus a matrix encoded stereo mix)
350 
351 //  ITU defined layouts
352 
353     CHANNEL_LAYOUT_ITU_1_0    = CHANNEL_LAYOUT_Mono,    //  C
354     CHANNEL_LAYOUT_ITU_2_0    = CHANNEL_LAYOUT_Stereo,  //  L R
355     CHANNEL_LAYOUT_ITU_2_1    = (131<<16) | 3,         // L R Cs
356     CHANNEL_LAYOUT_ITU_2_2    = (132<<16) | 4,         // L R Ls Rs
357     CHANNEL_LAYOUT_ITU_3_0    = CHANNEL_LAYOUT_MPEG_3_0_A,  //  L R C
358     CHANNEL_LAYOUT_ITU_3_1    = CHANNEL_LAYOUT_MPEG_4_0_A,  //  L R C Cs
359     CHANNEL_LAYOUT_ITU_3_2    = CHANNEL_LAYOUT_MPEG_5_0_A,  //  L R C Ls Rs
360     CHANNEL_LAYOUT_ITU_3_2_1  = CHANNEL_LAYOUT_MPEG_5_1_A,  //  L R C LFE Ls Rs
361     CHANNEL_LAYOUT_ITU_3_4_1  = CHANNEL_LAYOUT_MPEG_7_1_C,  //  L R C LFE Ls Rs Rls Rrs
362 
363 // DVD defined layouts
364 
365     CHANNEL_LAYOUT_DVD_0  = CHANNEL_LAYOUT_Mono,    // C (mono)
366     CHANNEL_LAYOUT_DVD_1  = CHANNEL_LAYOUT_Stereo,  // L R
367     CHANNEL_LAYOUT_DVD_2  = CHANNEL_LAYOUT_ITU_2_1, // L R Cs
368     CHANNEL_LAYOUT_DVD_3  = CHANNEL_LAYOUT_ITU_2_2, // L R Ls Rs
369     CHANNEL_LAYOUT_DVD_4  = (133<<16) | 3,                // L R LFE
370     CHANNEL_LAYOUT_DVD_5  = (134<<16) | 4,                // L R LFE Cs
371     CHANNEL_LAYOUT_DVD_6  = (135<<16) | 5,                // L R LFE Ls Rs
372     CHANNEL_LAYOUT_DVD_7  = CHANNEL_LAYOUT_MPEG_3_0_A,// L R C
373     CHANNEL_LAYOUT_DVD_8  = CHANNEL_LAYOUT_MPEG_4_0_A,// L R C Cs
374     CHANNEL_LAYOUT_DVD_9  = CHANNEL_LAYOUT_MPEG_5_0_A,// L R C Ls Rs
375     CHANNEL_LAYOUT_DVD_10 = (136<<16) | 4,                // L R C LFE
376     CHANNEL_LAYOUT_DVD_11 = (137<<16) | 5,                // L R C LFE Cs
377     CHANNEL_LAYOUT_DVD_12 = CHANNEL_LAYOUT_MPEG_5_1_A,// L R C LFE Ls Rs
378 
379     // 13 through 17 are duplicates of 8 through 12.
380 
381     CHANNEL_LAYOUT_DVD_13 = CHANNEL_LAYOUT_DVD_8,   // L R C Cs
382     CHANNEL_LAYOUT_DVD_14 = CHANNEL_LAYOUT_DVD_9,   // L R C Ls Rs
383     CHANNEL_LAYOUT_DVD_15 = CHANNEL_LAYOUT_DVD_10,  // L R C LFE
384     CHANNEL_LAYOUT_DVD_16 = CHANNEL_LAYOUT_DVD_11,  // L R C LFE Cs
385     CHANNEL_LAYOUT_DVD_17 = CHANNEL_LAYOUT_DVD_12,  // L R C LFE Ls Rs
386     CHANNEL_LAYOUT_DVD_18 = (138<<16) | 5,                // L R Ls Rs LFE
387     CHANNEL_LAYOUT_DVD_19 = CHANNEL_LAYOUT_MPEG_5_0_B,// L R Ls Rs C
388     CHANNEL_LAYOUT_DVD_20 = CHANNEL_LAYOUT_MPEG_5_1_B,// L R Ls Rs C LFE
389 
390 // These layouts are recommended for Mac OS X's AudioUnit use
391 // These are the symmetrical layouts
392 
393     CHANNEL_LAYOUT_AudioUnit_4= CHANNEL_LAYOUT_Quadraphonic,
394     CHANNEL_LAYOUT_AudioUnit_5= CHANNEL_LAYOUT_Pentagonal,
395     CHANNEL_LAYOUT_AudioUnit_6= CHANNEL_LAYOUT_Hexagonal,
396     CHANNEL_LAYOUT_AudioUnit_8= CHANNEL_LAYOUT_Octagonal,
397 
398 // These are the surround-based layouts
399 
400     CHANNEL_LAYOUT_AudioUnit_5_0  = CHANNEL_LAYOUT_MPEG_5_0_B, // L R Ls Rs C
401     CHANNEL_LAYOUT_AudioUnit_6_0  = (139<<16) | 6,        // L R Ls Rs C Cs
402     CHANNEL_LAYOUT_AudioUnit_7_0  = (140<<16) | 7,        // L R Ls Rs C Rls Rrs
403     CHANNEL_LAYOUT_AudioUnit_5_1  = CHANNEL_LAYOUT_MPEG_5_1_A, // L R C LFE Ls Rs
404     CHANNEL_LAYOUT_AudioUnit_6_1  = CHANNEL_LAYOUT_MPEG_6_1_A, // L R C LFE Ls Rs Cs
405     CHANNEL_LAYOUT_AudioUnit_7_1  = CHANNEL_LAYOUT_MPEG_7_1_C, // L R C LFE Ls Rs Rls Rrs
406 
407 // These layouts are used for AAC Encoding within the MPEG-4 Specification
408 
409     CHANNEL_LAYOUT_AAC_Quadraphonic   = CHANNEL_LAYOUT_Quadraphonic, // L R Ls Rs
410     CHANNEL_LAYOUT_AAC_4_0= CHANNEL_LAYOUT_MPEG_4_0_B,  // C L R Cs
411     CHANNEL_LAYOUT_AAC_5_0= CHANNEL_LAYOUT_MPEG_5_0_D,  // C L R Ls Rs
412     CHANNEL_LAYOUT_AAC_5_1= CHANNEL_LAYOUT_MPEG_5_1_D,  // C L R Ls Rs Lfe
413     CHANNEL_LAYOUT_AAC_6_0= (141<<16) | 6,            // C L R Ls Rs Cs
414     CHANNEL_LAYOUT_AAC_6_1= (142<<16) | 7,            // C L R Ls Rs Cs Lfe
415     CHANNEL_LAYOUT_AAC_7_0= (143<<16) | 7,            // C L R Ls Rs Rls Rrs
416     CHANNEL_LAYOUT_AAC_7_1= CHANNEL_LAYOUT_MPEG_7_1_B, // C Lc Rc L R Ls Rs Lfe
417     CHANNEL_LAYOUT_AAC_Octagonal  = (144<<16) | 8,    // C L R Ls Rs Rls Rrs Cs
418     CHANNEL_LAYOUT_TMH_10_2_std   = (145<<16) | 16,   // L R C Vhc Lsd Rsd Ls Rs Vhl Vhr Lw Rw Csd Cs LFE1 LFE2
419     CHANNEL_LAYOUT_TMH_10_2_full  = (146<<16) | 21,   // TMH_10_2_std plus: Lc Rc HI VI Haptic
420     CHANNEL_LAYOUT_RESERVED_DO_NOT_USE= (147<<16)
421 } channel_layout_t;
422 
423 static struct
424   {
425   channel_layout_t layout;
426   channel_label_t * channels;
427   }
428 channel_locations[] =
429   {
430     { CHANNEL_LAYOUT_Mono, (channel_label_t[]){ CHANNEL_LABEL_Center } }, // a standard mono stream
431 
432 // 2 Channel layouts
433 
434     { CHANNEL_LAYOUT_Stereo,  (channel_label_t[]){ CHANNEL_LABEL_Left,
435                                                    CHANNEL_LABEL_Right } }, // a standard stereo stream (L R)
436 
437     { CHANNEL_LAYOUT_StereoHeadphones, (channel_label_t[]){ CHANNEL_LABEL_Left,
438                                                             CHANNEL_LABEL_Right } }, // a standard stereo stream (L R) - implied headphone playback
439     { CHANNEL_LAYOUT_MatrixStereo, (channel_label_t[]){ CHANNEL_LABEL_LeftTotal,
440                                                         CHANNEL_LABEL_RightTotal } }, // a matrix encoded stereo stream (Lt, Rt)
441 
442     { CHANNEL_LAYOUT_MidSide, (channel_label_t[]){ CHANNEL_LABEL_MS_Mid,
443                                                    CHANNEL_LABEL_MS_Side } }, // mid/side recording
444 
445     { CHANNEL_LAYOUT_XY, (channel_label_t[]){ CHANNEL_LABEL_XY_X, CHANNEL_LABEL_XY_Y } }, // coincident mic pair (often 2 figure 8's)
446 
447     { CHANNEL_LAYOUT_Binaural, (channel_label_t[]){ CHANNEL_LABEL_Left,
448                                                     CHANNEL_LABEL_Right  } }, // binaural stereo (left, right)
449 
450 // Symetric arrangements - same distance between speaker locations
451 
452     { CHANNEL_LAYOUT_Ambisonic_B_Format, (channel_label_t[]){ CHANNEL_LABEL_Ambisonic_W,
453                                                               CHANNEL_LABEL_Ambisonic_X,
454                                                               CHANNEL_LABEL_Ambisonic_Y,
455                                                               CHANNEL_LABEL_Ambisonic_Z } }, // W, X, Y, Z
456 
457     { CHANNEL_LAYOUT_Quadraphonic, (channel_label_t[]){ CHANNEL_LABEL_Left,
458                                                         CHANNEL_LABEL_Right,
459                                                         CHANNEL_LABEL_LeftSurround,
460                                                         CHANNEL_LABEL_RightSurround } }, // front left, front right, back left, back right
461 
462     { CHANNEL_LAYOUT_Pentagonal, (channel_label_t[]){ CHANNEL_LABEL_Left,
463                                                       CHANNEL_LABEL_Right,
464                                                       CHANNEL_LABEL_LeftSurround,
465                                                       CHANNEL_LABEL_RightSurround,
466                                                       CHANNEL_LABEL_Center } }, // left, right, rear left, rear right, center
467 
468     { CHANNEL_LAYOUT_Hexagonal, (channel_label_t[]){  CHANNEL_LABEL_Left,
469                                                       CHANNEL_LABEL_Right,
470                                                       CHANNEL_LABEL_LeftSurround,
471                                                       CHANNEL_LABEL_RightSurround,
472                                                       CHANNEL_LABEL_Center,
473                                                       CHANNEL_LABEL_CenterSurround } }, // left, right, rear left, rear right, center, rear
474 
475     { CHANNEL_LAYOUT_Octagonal, (channel_label_t[]){ CHANNEL_LABEL_Left,
476                                                      CHANNEL_LABEL_Right,
477                                                      CHANNEL_LABEL_LeftSurround,
478                                                      CHANNEL_LABEL_RightSurround,
479                                                      CHANNEL_LABEL_Center,
480                                                      CHANNEL_LABEL_CenterSurround,
481                                                      CHANNEL_LABEL_LeftSurroundDirect,
482                                                      CHANNEL_LABEL_RightSurroundDirect } }, // front left, front right, rear left, rear right,
483                                                                                             // front center, rear center, side left, side right
484 
485     { CHANNEL_LAYOUT_Cube, (channel_label_t[]){ CHANNEL_LABEL_Left,
486                                                 CHANNEL_LABEL_Right,
487                                                 CHANNEL_LABEL_LeftSurround,
488                                                 CHANNEL_LABEL_RightSurround,
489                                                 CHANNEL_LABEL_VerticalHeightLeft,
490                                                 CHANNEL_LABEL_VerticalHeightRight,
491                                                 CHANNEL_LABEL_TopBackLeft,
492                                                 CHANNEL_LABEL_TopBackRight } }, // left, right, rear left, rear right
493                                                                                 // top left, top right, top rear left, top rear right
494 
495 //  MPEG defined layouts
496 
497     { CHANNEL_LAYOUT_MPEG_3_0_A, (channel_label_t[]){ CHANNEL_LABEL_Left,
498                                                       CHANNEL_LABEL_Right,
499                                                       CHANNEL_LABEL_Center } },         // L R C
500 
501     { CHANNEL_LAYOUT_MPEG_4_0_A, (channel_label_t[]){ CHANNEL_LABEL_Left,
502                                                       CHANNEL_LABEL_Right,
503                                                       CHANNEL_LABEL_Center,
504                                                       CHANNEL_LABEL_CenterSurround } },         // L R C Cs
505 
506     { CHANNEL_LAYOUT_MPEG_5_0_A, (channel_label_t[]){ CHANNEL_LABEL_Left,
507                                                       CHANNEL_LABEL_Right,
508                                                       CHANNEL_LABEL_Center,
509                                                       CHANNEL_LABEL_LeftSurround,
510                                                       CHANNEL_LABEL_RightSurround } },         // L R C Ls Rs
511 
512     { CHANNEL_LAYOUT_MPEG_5_1_A, (channel_label_t[]){ CHANNEL_LABEL_Left,
513                                                       CHANNEL_LABEL_Right,
514                                                       CHANNEL_LABEL_Center,
515                                                       CHANNEL_LABEL_LFEScreen,
516                                                       CHANNEL_LABEL_LeftSurround,
517                                                       CHANNEL_LABEL_RightSurround } },         // L R C LFE Ls Rs
518 
519     { CHANNEL_LAYOUT_MPEG_6_1_A, (channel_label_t[]){ CHANNEL_LABEL_Left,
520                                                       CHANNEL_LABEL_Right,
521                                                       CHANNEL_LABEL_Center,
522                                                       CHANNEL_LABEL_LFEScreen,
523                                                       CHANNEL_LABEL_LeftSurround,
524                                                       CHANNEL_LABEL_RightSurround,
525                                                       CHANNEL_LABEL_CenterSurround } },         // L R C LFE Ls Rs Cs
526 
527     { CHANNEL_LAYOUT_MPEG_7_1_A, (channel_label_t[]){ CHANNEL_LABEL_Left,
528                                                       CHANNEL_LABEL_Right,
529                                                       CHANNEL_LABEL_Center,
530                                                       CHANNEL_LABEL_LFEScreen,
531                                                       CHANNEL_LABEL_LeftSurround,
532                                                       CHANNEL_LABEL_RightSurround,
533                                                       CHANNEL_LABEL_LeftCenter,
534                                                       CHANNEL_LABEL_RightCenter } }, // L R C LFE Ls Rs Lc Rc
535 
536     { CHANNEL_LAYOUT_MPEG_5_0_B, (channel_label_t[]){ CHANNEL_LABEL_Left,
537                                                       CHANNEL_LABEL_Right,
538                                                       CHANNEL_LABEL_LeftSurround,
539                                                       CHANNEL_LABEL_RightSurround,
540                                                       CHANNEL_LABEL_Center } },         // L R Ls Rs C
541 
542     { CHANNEL_LAYOUT_MPEG_5_1_B, (channel_label_t[]){ CHANNEL_LABEL_Left,
543                                                       CHANNEL_LABEL_Right,
544                                                       CHANNEL_LABEL_LeftSurround,
545                                                       CHANNEL_LABEL_RightSurround,
546                                                       CHANNEL_LABEL_Center,
547                                                       CHANNEL_LABEL_LFEScreen } },         // L R Ls Rs C LFE
548 
549     { CHANNEL_LAYOUT_MPEG_3_0_B,  (channel_label_t[]){ CHANNEL_LABEL_Center,
550                                                        CHANNEL_LABEL_Left,
551                                                        CHANNEL_LABEL_Right } },        // C L R
552 
553     { CHANNEL_LAYOUT_MPEG_4_0_B, (channel_label_t[]){ CHANNEL_LABEL_Center,
554                                                       CHANNEL_LABEL_Left,
555                                                       CHANNEL_LABEL_Right,
556                                                       CHANNEL_LABEL_CenterSurround } },         // C L R Cs
557 
558     { CHANNEL_LAYOUT_MPEG_5_0_D, (channel_label_t[]){ CHANNEL_LABEL_Center,
559                                                       CHANNEL_LABEL_Left,
560                                                       CHANNEL_LABEL_Right,
561                                                       CHANNEL_LABEL_LeftSurround,
562                                                       CHANNEL_LABEL_RightSurround } },         // C L R Ls Rs
563 
564     { CHANNEL_LAYOUT_MPEG_5_1_D, (channel_label_t[]){ CHANNEL_LABEL_Center,
565                                                       CHANNEL_LABEL_Left,
566                                                       CHANNEL_LABEL_Right,
567                                                       CHANNEL_LABEL_LeftSurround,
568                                                       CHANNEL_LABEL_RightSurround,
569                                                       CHANNEL_LABEL_LFEScreen } },         // C L R Ls Rs LFE
570 
571     { CHANNEL_LAYOUT_MPEG_5_0_C, (channel_label_t[]){ CHANNEL_LABEL_Left,
572                                                       CHANNEL_LABEL_Center,
573                                                       CHANNEL_LABEL_Right,
574                                                       CHANNEL_LABEL_LeftSurround,
575                                                       CHANNEL_LABEL_RightSurround } },         // L C R Ls Rs
576 
577     { CHANNEL_LAYOUT_MPEG_5_1_C, (channel_label_t[]){ CHANNEL_LABEL_Left,
578                                                       CHANNEL_LABEL_Center,
579                                                       CHANNEL_LABEL_Right,
580                                                       CHANNEL_LABEL_LeftSurround,
581                                                       CHANNEL_LABEL_RightSurround,
582                                                       CHANNEL_LABEL_LFEScreen } },         // L C R Ls Rs LFE
583 
584     { CHANNEL_LAYOUT_MPEG_7_1_B, (channel_label_t[]){ CHANNEL_LABEL_Center,
585                                                       CHANNEL_LABEL_LeftCenter,
586                                                       CHANNEL_LABEL_RightCenter,
587                                                       CHANNEL_LABEL_Left,
588                                                       CHANNEL_LABEL_Right,
589                                                       CHANNEL_LABEL_LeftSurround,
590                                                       CHANNEL_LABEL_RightSurround,
591                                                       CHANNEL_LABEL_LFEScreen  } },         // C Lc Rc L R Ls Rs LFE
592 
593     { CHANNEL_LAYOUT_MPEG_7_1_C, (channel_label_t[]){ CHANNEL_LABEL_Left,
594                                                       CHANNEL_LABEL_Right,
595                                                       CHANNEL_LABEL_Center,
596                                                       CHANNEL_LABEL_LFEScreen,
597                                                       CHANNEL_LABEL_LeftSurroundDirect,
598                                                       CHANNEL_LABEL_RightSurroundDirect,
599                                                       CHANNEL_LABEL_LeftSurround,
600                                                       CHANNEL_LABEL_RightSurround  } },         // L R C LFE Ls Rs Rls Rrs
601 
602     { CHANNEL_LAYOUT_Emagic_Default_7_1,  (channel_label_t[]){ CHANNEL_LABEL_Left,
603                                                                CHANNEL_LABEL_Right,
604                                                                CHANNEL_LABEL_LeftSurround,
605                                                                CHANNEL_LABEL_RightSurround,
606                                                                CHANNEL_LABEL_Center,
607                                                                CHANNEL_LABEL_LFEScreen,
608                                                                CHANNEL_LABEL_LeftCenter,
609                                                                CHANNEL_LABEL_RightCenter } },//  L R Ls Rs C LFE Lc Rc
610 
611     { CHANNEL_LAYOUT_SMPTE_DTV,  (channel_label_t[]){ CHANNEL_LABEL_Left,
612                                                       CHANNEL_LABEL_Right,
613                                                       CHANNEL_LABEL_Center,
614                                                       CHANNEL_LABEL_LFEScreen,
615                                                       CHANNEL_LABEL_LeftSurround,
616                                                       CHANNEL_LABEL_RightSurround,
617                                                       CHANNEL_LABEL_LeftTotal,
618                                                       CHANNEL_LABEL_RightTotal } },         //  L R C LFE Ls Rs Lt Rt
619                                                       //  (CHANNEL_LAYOUT_ITU_5_1 plus a matrix encoded stereo mix)
620 
621 //  ITU defined layouts
622 
623     { CHANNEL_LAYOUT_ITU_2_1, (channel_label_t[]){ CHANNEL_LABEL_Left,
624                                                    CHANNEL_LABEL_Right,
625                                                    CHANNEL_LABEL_CenterSurround } },            // L R Cs
626 
627     { CHANNEL_LAYOUT_ITU_2_2, (channel_label_t[]){ CHANNEL_LABEL_Left,
628                                                    CHANNEL_LABEL_Right,
629                                                    CHANNEL_LABEL_LeftSurround,
630                                                    CHANNEL_LABEL_RightSurround } },            // L R Ls Rs
631 
632 // DVD defined layouts
633 
634     { CHANNEL_LAYOUT_DVD_4, (channel_label_t[]){ CHANNEL_LABEL_Left,
635                                                  CHANNEL_LABEL_Right,
636                                                  CHANNEL_LABEL_LFEScreen } },              // L R LFE
637     { CHANNEL_LAYOUT_DVD_5, (channel_label_t[]){ CHANNEL_LABEL_Left,
638                                                  CHANNEL_LABEL_Right,
639                                                  CHANNEL_LABEL_LFEScreen,
640                                                  CHANNEL_LABEL_CenterSurround } },              // L R LFE Cs
641 
642     { CHANNEL_LAYOUT_DVD_6,  (channel_label_t[]){ CHANNEL_LABEL_Left,
643                                                   CHANNEL_LABEL_Right,
644                                                   CHANNEL_LABEL_LFEScreen,
645                                                   CHANNEL_LABEL_LeftSurround,
646                                                   CHANNEL_LABEL_RightSurround } },             // L R LFE Ls Rs
647 
648     { CHANNEL_LAYOUT_DVD_10, (channel_label_t[]){ CHANNEL_LABEL_Left,
649                                                   CHANNEL_LABEL_Right,
650                                                   CHANNEL_LABEL_Center,
651                                                   CHANNEL_LABEL_LFEScreen  } },             // L R C LFE
652 
653     { CHANNEL_LAYOUT_DVD_11,  (channel_label_t[]){ CHANNEL_LABEL_Left,
654                                                    CHANNEL_LABEL_Right,
655                                                    CHANNEL_LABEL_Center,
656                                                    CHANNEL_LABEL_LFEScreen,
657                                                    CHANNEL_LABEL_CenterSurround } },            // L R C LFE Cs
658 
659     // 13 through 17 are duplicates of 8 through 12.
660 
661     { CHANNEL_LAYOUT_DVD_18, (channel_label_t[]){ CHANNEL_LABEL_Left,
662                                                   CHANNEL_LABEL_Right,
663                                                   CHANNEL_LABEL_LeftSurround,
664                                                   CHANNEL_LABEL_RightSurround,
665                                                   CHANNEL_LABEL_LFEScreen } },             // L R Ls Rs LFE
666 
667     // These are the surround-based layouts
668 
669     { CHANNEL_LAYOUT_AudioUnit_6_0, (channel_label_t[]){ CHANNEL_LABEL_Left,
670                                                          CHANNEL_LABEL_Right,
671                                                          CHANNEL_LABEL_LeftSurround,
672                                                          CHANNEL_LABEL_RightSurround,
673                                                          CHANNEL_LABEL_Center,
674                                                          CHANNEL_LABEL_CenterSurround   } },      // L R Ls Rs C Cs
675 
676     { CHANNEL_LAYOUT_AudioUnit_7_0, (channel_label_t[]){ CHANNEL_LABEL_Left,
677                                                          CHANNEL_LABEL_Right,
678                                                          CHANNEL_LABEL_LeftSurroundDirect,
679                                                          CHANNEL_LABEL_RightSurroundDirect,
680                                                          CHANNEL_LABEL_Center,
681                                                          CHANNEL_LABEL_LeftSurround,
682                                                          CHANNEL_LABEL_RightSurround } },      // L R Ls Rs C Rls Rrs
683 
684 // These layouts are used for AAC Encoding within the MPEG-4 Specification
685 
686     { CHANNEL_LAYOUT_AAC_6_0, (channel_label_t[]){ CHANNEL_LABEL_Center,
687                                                    CHANNEL_LABEL_Left,
688                                                    CHANNEL_LABEL_Right,
689                                                    CHANNEL_LABEL_LeftSurround,
690                                                    CHANNEL_LABEL_RightSurround,
691                                                    CHANNEL_LABEL_CenterSurround  } },            // C L R Ls Rs Cs
692 
693     { CHANNEL_LAYOUT_AAC_6_1, (channel_label_t[]){ CHANNEL_LABEL_Center,
694                                                    CHANNEL_LABEL_Left,
695                                                    CHANNEL_LABEL_Right,
696                                                    CHANNEL_LABEL_LeftSurround,
697                                                    CHANNEL_LABEL_RightSurround,
698                                                    CHANNEL_LABEL_CenterSurround,
699                                                    CHANNEL_LABEL_LFEScreen  } },            // C L R Ls Rs Cs Lfe
700 
701     { CHANNEL_LAYOUT_AAC_7_0, (channel_label_t[]){ CHANNEL_LABEL_Center,
702                                                    CHANNEL_LABEL_Left,
703                                                    CHANNEL_LABEL_Right,
704                                                    CHANNEL_LABEL_LeftSurroundDirect,
705                                                    CHANNEL_LABEL_RightSurroundDirect,
706                                                    CHANNEL_LABEL_LeftSurround,
707                                                    CHANNEL_LABEL_RightSurround  } },            // C L R Ls Rs Rls Rrs
708 
709     { CHANNEL_LAYOUT_AAC_Octagonal, (channel_label_t[]){ CHANNEL_LABEL_Center,
710                                                          CHANNEL_LABEL_Left,
711                                                          CHANNEL_LABEL_Right,
712                                                          CHANNEL_LABEL_LeftSurroundDirect,
713                                                          CHANNEL_LABEL_RightSurroundDirect,
714                                                          CHANNEL_LABEL_LeftSurround,
715                                                          CHANNEL_LABEL_RightSurround,
716                                                          CHANNEL_LABEL_CenterSurround  } },      // C L R Ls Rs Rls Rrs Cs
717 
718     /* No, sorry the following 2 a to weird. The one who has such files, can program it */
719     //    { CHANNEL_LAYOUT_TMH_10_2_std, (channel_label_t[]){  } },       // L R C Vhc Lsd Rsd Ls Rs Vhl Vhr Lw Rw Csd Cs LFE1 LFE2
720     //    { CHANNEL_LAYOUT_TMH_10_2_full, (channel_label_t[]){  } },      // TMH_10_2_std plus: Lc Rc HI VI Haptic
721 
722   };
723 
get_channel_locations(uint32_t layout,int * num_channels)724 static channel_label_t * get_channel_locations(uint32_t layout, int * num_channels)
725   {
726   int i;
727 
728   *num_channels = layout & 0xffff;
729   for(i = 0; i < sizeof(channel_locations)/sizeof(channel_locations[0]); i++)
730     {
731     if(channel_locations[i].layout == layout)
732       {
733       return channel_locations[i].channels;
734       }
735     }
736   return (channel_label_t*)0;
737   }
738 
quicktime_chan_init(quicktime_chan_t * chan)739 void quicktime_chan_init(quicktime_chan_t *chan)
740   {
741 
742   }
743 
quicktime_chan_delete(quicktime_chan_t * chan)744 void quicktime_chan_delete(quicktime_chan_t *chan)
745   {
746   if(chan->ChannelDescriptions)
747     free(chan->ChannelDescriptions);
748   }
749 
quicktime_chan_dump(quicktime_chan_t * chan)750 void quicktime_chan_dump(quicktime_chan_t *chan)
751   {
752   channel_label_t * channel_labels;
753   int num_channels;
754   int i, j;
755   uint32_t mask;
756   lqt_dump("       channel description\n");
757   lqt_dump("        version                     %d\n", chan->version);
758   lqt_dump("        flags                       %ld\n", chan->flags);
759   lqt_dump("        mChannelLayoutTag:          0x%08x", chan->mChannelLayoutTag);
760 
761   if(chan->mChannelLayoutTag == CHANNEL_LAYOUT_UseChannelDescriptions)
762     {
763     lqt_dump(" [Use channel decriptions]\n");
764     }
765   else if(chan->mChannelLayoutTag == CHANNEL_LAYOUT_UseChannelBitmap)
766     {
767     lqt_dump(" [Use channel bitmap]\n");
768     }
769   else
770     {
771     channel_labels = get_channel_locations(chan->mChannelLayoutTag, &num_channels);
772 
773     lqt_dump(" [");
774 
775     if(channel_labels)
776       {
777       for(i = 0; i < num_channels; i++)
778         {
779         lqt_dump("%s", get_channel_name(channel_labels[i]));
780         if(i < num_channels-1)
781           lqt_dump(", ");
782         }
783       }
784     else
785       {
786       lqt_dump("Not available");
787       }
788     lqt_dump("]\n");
789     }
790 
791   lqt_dump("        mChannelBitmap:             0x%08x", chan->mChannelBitmap);
792 
793   if(chan->mChannelLayoutTag == CHANNEL_LAYOUT_UseChannelBitmap)
794     {
795     lqt_dump(" [");
796     j = 0;
797     mask = 1;
798     for(i = 0; i < 32; i++)
799       {
800       if(chan->mChannelBitmap & mask)
801         {
802         if(j)
803           lqt_dump(", ");
804         lqt_dump("%s", get_channel_name(channel_bit_2_channel_label(mask)));
805         j++;
806         }
807       mask <<= 1;
808       }
809     lqt_dump("]\n");
810     }
811   else
812     lqt_dump("\n");
813 
814 
815   lqt_dump("        mNumberChannelDescriptions: %d\n", chan->mNumberChannelDescriptions);
816   for(i = 0; i < chan->mNumberChannelDescriptions; i++)
817     {
818     lqt_dump("         mChannelLabel[%d]: 0x%08x [%s]\n", i,
819            chan->ChannelDescriptions[i].mChannelLabel, get_channel_name(chan->ChannelDescriptions[i].mChannelLabel));
820     lqt_dump("         mChannelFlags[%d]: 0x%08x\n", i,
821            chan->ChannelDescriptions[i].mChannelFlags);
822     lqt_dump("         mCoordinates[%d]: [%f %f %f]\n", i,
823            chan->ChannelDescriptions[i].mCoordinates[0],
824            chan->ChannelDescriptions[i].mCoordinates[1],
825            chan->ChannelDescriptions[i].mCoordinates[2]);
826     }
827   }
828 
829 
830 
quicktime_read_chan(quicktime_t * file,quicktime_chan_t * chan)831 void quicktime_read_chan(quicktime_t *file, quicktime_chan_t *chan)
832   {
833   int i;
834   chan->version = quicktime_read_char(file);
835   chan->flags = quicktime_read_int24(file);
836 
837   chan->mChannelLayoutTag = quicktime_read_int32(file);
838   chan->mChannelBitmap    = quicktime_read_int32(file);
839   chan->mNumberChannelDescriptions = quicktime_read_int32(file);
840 
841   if(chan->mNumberChannelDescriptions)
842     {
843     chan->ChannelDescriptions = calloc(chan->mNumberChannelDescriptions,
844                                        sizeof(*(chan->ChannelDescriptions)));
845 
846     for(i = 0; i < chan->mNumberChannelDescriptions; i++)
847       {
848       chan->ChannelDescriptions[i].mChannelLabel = quicktime_read_int32(file);
849       chan->ChannelDescriptions[i].mChannelFlags = quicktime_read_int32(file);
850       chan->ChannelDescriptions[i].mCoordinates[0] = quicktime_read_float32(file);
851       chan->ChannelDescriptions[i].mCoordinates[1] = quicktime_read_float32(file);
852       chan->ChannelDescriptions[i].mCoordinates[2] = quicktime_read_float32(file);
853       }
854     }
855 
856   }
857 
quicktime_write_chan(quicktime_t * file,quicktime_chan_t * chan)858 void quicktime_write_chan(quicktime_t *file, quicktime_chan_t *chan)
859   {
860   quicktime_atom_t atom;
861   int i;
862   quicktime_atom_write_header(file, &atom, "chan");
863 
864   quicktime_write_char(file, chan->version);
865   quicktime_write_int24(file, chan->flags);
866 
867   quicktime_write_int32(file, chan->mChannelLayoutTag);
868   quicktime_write_int32(file, chan->mChannelBitmap);
869   quicktime_write_int32(file, chan->mNumberChannelDescriptions);
870 
871   for(i = 0; i < chan->mNumberChannelDescriptions; i++)
872     {
873     quicktime_write_int32(file, chan->ChannelDescriptions[i].mChannelLabel);
874     quicktime_write_int32(file, chan->ChannelDescriptions[i].mChannelFlags);
875     quicktime_write_float32(file, chan->ChannelDescriptions[i].mCoordinates[0]);
876     quicktime_write_float32(file, chan->ChannelDescriptions[i].mCoordinates[1]);
877     quicktime_write_float32(file, chan->ChannelDescriptions[i].mCoordinates[2]);
878     }
879   quicktime_atom_write_footer(file, &atom);
880   }
881 
882 /* Update an atrack from a chan atom */
quicktime_get_chan(quicktime_audio_map_t * atrack)883 void quicktime_get_chan(quicktime_audio_map_t * atrack)
884   {
885   int i, num_channels;
886   uint32_t mask;
887   quicktime_chan_t * chan;
888   const channel_label_t * channel_labels;
889   chan = &atrack->track->mdia.minf.stbl.stsd.table[0].chan;
890 
891   if(chan->mChannelLayoutTag == CHANNEL_LAYOUT_UseChannelDescriptions)
892     {
893     atrack->channel_setup = calloc(chan->mNumberChannelDescriptions,
894                                    sizeof(*atrack->channel_setup));
895     atrack->channels = chan->mNumberChannelDescriptions;
896     for(i = 0; i < chan->mNumberChannelDescriptions; i++)
897       atrack->channel_setup[i] = channel_label_2_channel(chan->ChannelDescriptions[i].mChannelLabel);
898     }
899   else if(chan->mChannelLayoutTag == CHANNEL_LAYOUT_UseChannelBitmap)
900     {
901     /* Count the channels */
902     mask = 1;
903     num_channels = 0;
904     for(i = 0; i < 32; i++)
905       {
906       if(chan->mChannelBitmap & mask)
907         num_channels++;
908       mask <<= 1;
909       }
910 
911     /* Set the channels */
912     atrack->channels = num_channels;
913     atrack->channel_setup = calloc(num_channels,
914                                    sizeof(*atrack->channel_setup));
915 
916     mask = 1;
917     num_channels = 0;
918     for(i = 0; i < 32; i++)
919       {
920       if(chan->mChannelBitmap & mask)
921         {
922         atrack->channel_setup[num_channels] =
923           channel_label_2_channel(channel_bit_2_channel_label(mask));
924         num_channels++;
925         }
926       mask <<= 1;
927       }
928     }
929   else /* Predefined channel layout */
930     {
931     channel_labels = get_channel_locations(chan->mChannelLayoutTag, &num_channels);
932     atrack->channels = num_channels;
933 
934     if(channel_labels)
935       {
936       atrack->channel_setup = calloc(num_channels,
937                                      sizeof(*atrack->channel_setup));
938       for(i = 0; i < num_channels; i++)
939         atrack->channel_setup[i] = channel_label_2_channel(channel_labels[i]);
940       }
941 
942     }
943 
944   }
945 
946 
layout_equal(channel_label_t * labels,lqt_channel_t * channels,int num_channels)947 static int layout_equal(channel_label_t * labels, lqt_channel_t * channels, int num_channels)
948   {
949   int i;
950 
951   for(i = 0; i < num_channels; i++)
952     {
953     if(channels[i] != channel_label_2_channel(labels[i]))
954       return 0;
955     }
956   return 1;
957   }
958 
layout_similar(channel_label_t * labels,lqt_channel_t * channels,int num_channels)959 static int layout_similar(channel_label_t * labels, lqt_channel_t * channels, int num_channels)
960   {
961   int i, j, found;
962 
963   for(i = 0; i < num_channels; i++)
964     {
965     found = 0;
966     for(j = 0; j < num_channels; j++)
967       {
968       if(channels[i] == channel_label_2_channel(labels[j]))
969         {
970         found = 1;
971         break;
972         }
973       }
974     if(!found)
975       return 0;
976     }
977   return 1;
978   }
979 
980 /* Set the chan atom of an atrack */
quicktime_set_chan(quicktime_audio_map_t * atrack)981 void quicktime_set_chan(quicktime_audio_map_t * atrack)
982   {
983   int i, j;
984   quicktime_chan_t * chan;
985 
986   if(!atrack->channel_setup)
987     return;
988 
989   chan = &atrack->track->mdia.minf.stbl.stsd.table[0].chan;
990 
991   /* Search for a equal channel setup */
992   for(i = 0; i < sizeof(channel_locations) / sizeof(channel_locations[0]); i++)
993     {
994     if(((channel_locations[i].layout & 0xffff) == atrack->channels) &&
995        layout_equal(channel_locations[i].channels,
996                     atrack->channel_setup,
997                     atrack->channels))
998       {
999       chan->mChannelLayoutTag = channel_locations[i].layout;
1000       atrack->track->mdia.minf.stbl.stsd.table[0].has_chan = 1;
1001       return;
1002       }
1003     }
1004 
1005   /* Search for a similar channel setup */
1006   for(i = 0; i < sizeof(channel_locations) / sizeof(channel_locations[0]); i++)
1007     {
1008     if(((channel_locations[i].layout & 0xffff) == atrack->channels) &&
1009        layout_similar(channel_locations[i].channels,
1010                     atrack->channel_setup,
1011                     atrack->channels))
1012       {
1013       chan->mChannelLayoutTag = channel_locations[i].layout;
1014       atrack->track->mdia.minf.stbl.stsd.table[0].has_chan = 1;
1015 
1016       for(j = 0; j < atrack->channels; j++)
1017         atrack->channel_setup[j] = channel_label_2_channel(channel_locations[i].channels[j]);
1018       return;
1019       }
1020     }
1021 
1022   /* Nothing found, create a custom channel setup */
1023   chan->ChannelDescriptions =
1024     calloc(atrack->channels, sizeof(*(chan->ChannelDescriptions)));
1025   chan->mNumberChannelDescriptions = atrack->channels;
1026   chan->mChannelLayoutTag = CHANNEL_LAYOUT_UseChannelDescriptions;
1027   for(i = 0; i < chan->mNumberChannelDescriptions; i++)
1028     {
1029     chan->ChannelDescriptions[i].mChannelLabel =
1030       channel_2_channel_label(atrack->channel_setup[i]);
1031     }
1032   atrack->track->mdia.minf.stbl.stsd.table[0].has_chan = 1;
1033 
1034   }
1035