xref: /third_party/ffmpeg/libavformat/mov_chan.c (revision cabdff1a)
1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * Copyright (c) 2011 Justin Ruggles
3cabdff1aSopenharmony_ci *
4cabdff1aSopenharmony_ci * This file is part of FFmpeg.
5cabdff1aSopenharmony_ci *
6cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
7cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
8cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
9cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
10cabdff1aSopenharmony_ci *
11cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
12cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
13cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14cabdff1aSopenharmony_ci * Lesser General Public License for more details.
15cabdff1aSopenharmony_ci *
16cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
17cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
18cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19cabdff1aSopenharmony_ci */
20cabdff1aSopenharmony_ci
21cabdff1aSopenharmony_ci/**
22cabdff1aSopenharmony_ci * mov 'chan' tag reading/writing.
23cabdff1aSopenharmony_ci * @author Justin Ruggles
24cabdff1aSopenharmony_ci */
25cabdff1aSopenharmony_ci
26cabdff1aSopenharmony_ci#include <stdint.h>
27cabdff1aSopenharmony_ci
28cabdff1aSopenharmony_ci#include "libavutil/channel_layout.h"
29cabdff1aSopenharmony_ci#include "libavcodec/codec_id.h"
30cabdff1aSopenharmony_ci#include "mov_chan.h"
31cabdff1aSopenharmony_ci
32cabdff1aSopenharmony_cistruct MovChannelLayoutMap {
33cabdff1aSopenharmony_ci    uint32_t tag;
34cabdff1aSopenharmony_ci    uint64_t layout;
35cabdff1aSopenharmony_ci};
36cabdff1aSopenharmony_ci
37cabdff1aSopenharmony_cistatic const struct MovChannelLayoutMap mov_ch_layout_map_misc[] = {
38cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_USE_DESCRIPTIONS,   0 },
39cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_USE_BITMAP,         0 },
40cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_DISCRETEINORDER,    0 },
41cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_UNKNOWN,            0 },
42cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_TMH_10_2_STD,       0 }, // L,   R,  C,    Vhc, Lsd, Rsd,
43cabdff1aSopenharmony_ci                                             // Ls,  Rs, Vhl,  Vhr, Lw,  Rw,
44cabdff1aSopenharmony_ci                                             // Csd, Cs, LFE1, LFE2
45cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_TMH_10_2_FULL,      0 }, // L,   R,  C,    Vhc,  Lsd, Rsd,
46cabdff1aSopenharmony_ci                                             // Ls,  Rs, Vhl,  Vhr,  Lw,  Rw,
47cabdff1aSopenharmony_ci                                             // Csd, Cs, LFE1, LFE2, Lc,  Rc,
48cabdff1aSopenharmony_ci                                             // HI,  VI, Haptic
49cabdff1aSopenharmony_ci    { 0, 0 },
50cabdff1aSopenharmony_ci};
51cabdff1aSopenharmony_ci
52cabdff1aSopenharmony_cistatic const struct MovChannelLayoutMap mov_ch_layout_map_1ch[] = {
53cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_MONO,               AV_CH_LAYOUT_MONO }, // C
54cabdff1aSopenharmony_ci    { 0, 0 },
55cabdff1aSopenharmony_ci};
56cabdff1aSopenharmony_ci
57cabdff1aSopenharmony_cistatic const struct MovChannelLayoutMap mov_ch_layout_map_2ch[] = {
58cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_STEREO,             AV_CH_LAYOUT_STEREO         }, // L, R
59cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_STEREOHEADPHONES,   AV_CH_LAYOUT_STEREO         }, // L, R
60cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_BINAURAL,           AV_CH_LAYOUT_STEREO         }, // L, R
61cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_MIDSIDE,            AV_CH_LAYOUT_STEREO         }, // C, sides
62cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_XY,                 AV_CH_LAYOUT_STEREO         }, // X (left), Y (right)
63cabdff1aSopenharmony_ci
64cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_MATRIXSTEREO,       AV_CH_LAYOUT_STEREO_DOWNMIX }, // Lt, Rt
65cabdff1aSopenharmony_ci
66cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_AC3_1_0_1,          AV_CH_LAYOUT_MONO |            // C, LFE
67cabdff1aSopenharmony_ci                                        AV_CH_LOW_FREQUENCY         },
68cabdff1aSopenharmony_ci    { 0, 0 },
69cabdff1aSopenharmony_ci};
70cabdff1aSopenharmony_ci
71cabdff1aSopenharmony_cistatic const struct MovChannelLayoutMap mov_ch_layout_map_3ch[] = {
72cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_MPEG_3_0_A,         AV_CH_LAYOUT_SURROUND }, // L, R, C
73cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_MPEG_3_0_B,         AV_CH_LAYOUT_SURROUND }, // C, L, R
74cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_AC3_3_0,            AV_CH_LAYOUT_SURROUND }, // L, C, R
75cabdff1aSopenharmony_ci
76cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_ITU_2_1,            AV_CH_LAYOUT_2_1      }, // L, R, Cs
77cabdff1aSopenharmony_ci
78cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_DVD_4,              AV_CH_LAYOUT_2POINT1  }, // L, R, LFE
79cabdff1aSopenharmony_ci    { 0, 0 },
80cabdff1aSopenharmony_ci};
81cabdff1aSopenharmony_ci
82cabdff1aSopenharmony_cistatic const struct MovChannelLayoutMap mov_ch_layout_map_4ch[] = {
83cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_AMBISONIC_B_FORMAT, 0 },                    // W, X, Y, Z
84cabdff1aSopenharmony_ci
85cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_QUADRAPHONIC,       AV_CH_LAYOUT_QUAD    }, // L, R, Rls, Rrs
86cabdff1aSopenharmony_ci
87cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_MPEG_4_0_A,         AV_CH_LAYOUT_4POINT0 }, // L, R, C, Cs
88cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_MPEG_4_0_B,         AV_CH_LAYOUT_4POINT0 }, // C, L, R, Cs
89cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_AC3_3_1,            AV_CH_LAYOUT_4POINT0 }, // L, C, R, Cs
90cabdff1aSopenharmony_ci
91cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_ITU_2_2,            AV_CH_LAYOUT_2_2     }, // L, R, Ls, Rs
92cabdff1aSopenharmony_ci
93cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_DVD_5,              AV_CH_LAYOUT_2_1 |      // L, R, LFE, Cs
94cabdff1aSopenharmony_ci                                        AV_CH_LOW_FREQUENCY  },
95cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_AC3_2_1_1,          AV_CH_LAYOUT_2_1 |      // L, R, Cs, LFE
96cabdff1aSopenharmony_ci                                        AV_CH_LOW_FREQUENCY  },
97cabdff1aSopenharmony_ci
98cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_DVD_10,             AV_CH_LAYOUT_3POINT1 }, // L, R, C, LFE
99cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_AC3_3_0_1,          AV_CH_LAYOUT_3POINT1 }, // L, C, R, LFE
100cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_DTS_3_1,            AV_CH_LAYOUT_3POINT1 }, // C, L, R, LFE
101cabdff1aSopenharmony_ci    { 0, 0 },
102cabdff1aSopenharmony_ci};
103cabdff1aSopenharmony_ci
104cabdff1aSopenharmony_cistatic const struct MovChannelLayoutMap mov_ch_layout_map_5ch[] = {
105cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_PENTAGONAL,         AV_CH_LAYOUT_5POINT0_BACK }, // L, R, Rls, Rrs, C
106cabdff1aSopenharmony_ci
107cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_MPEG_5_0_A,         AV_CH_LAYOUT_5POINT0 },      // L, R, C,  Ls, Rs
108cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_MPEG_5_0_B,         AV_CH_LAYOUT_5POINT0 },      // L, R, Ls, Rs, C
109cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_MPEG_5_0_C,         AV_CH_LAYOUT_5POINT0 },      // L, C, R,  Ls, Rs
110cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_MPEG_5_0_D,         AV_CH_LAYOUT_5POINT0 },      // C, L, R,  Ls, Rs
111cabdff1aSopenharmony_ci
112cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_DVD_6,              AV_CH_LAYOUT_2_2 |           // L, R, LFE, Ls, Rs
113cabdff1aSopenharmony_ci                                        AV_CH_LOW_FREQUENCY },
114cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_DVD_18,             AV_CH_LAYOUT_2_2 |           // L, R, Ls, Rs, LFE
115cabdff1aSopenharmony_ci                                        AV_CH_LOW_FREQUENCY },
116cabdff1aSopenharmony_ci
117cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_DVD_11,             AV_CH_LAYOUT_4POINT1 },      // L, R, C, LFE, Cs
118cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_AC3_3_1_1,          AV_CH_LAYOUT_4POINT1 },      // L, C, R, Cs,  LFE
119cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_DTS_4_1,            AV_CH_LAYOUT_4POINT1 },      // C, L, R, Cs,  LFE
120cabdff1aSopenharmony_ci    { 0, 0 },
121cabdff1aSopenharmony_ci};
122cabdff1aSopenharmony_ci
123cabdff1aSopenharmony_cistatic const struct MovChannelLayoutMap mov_ch_layout_map_6ch[] = {
124cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_HEXAGONAL,          AV_CH_LAYOUT_HEXAGONAL },      // L, R,  Rls, Rrs, C,   Cs
125cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_DTS_6_0_C,          AV_CH_LAYOUT_HEXAGONAL },      // C, Cs, L,   R,   Rls, Rrs
126cabdff1aSopenharmony_ci
127cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_MPEG_5_1_A,         AV_CH_LAYOUT_5POINT1 },        // L, R, C,  LFE, Ls, Rs
128cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_MPEG_5_1_B,         AV_CH_LAYOUT_5POINT1 },        // L, R, Ls, Rs,  C,  LFE
129cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_MPEG_5_1_C,         AV_CH_LAYOUT_5POINT1 },        // L, C, R,  Ls,  Rs, LFE
130cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_MPEG_5_1_D,         AV_CH_LAYOUT_5POINT1 },        // C, L, R,  Ls,  Rs, LFE
131cabdff1aSopenharmony_ci
132cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_AUDIOUNIT_6_0,      AV_CH_LAYOUT_6POINT0 },        // L, R, Ls, Rs, C,  Cs
133cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_AAC_6_0,            AV_CH_LAYOUT_6POINT0 },        // C, L, R,  Ls, Rs, Cs
134cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_EAC3_6_0_A,         AV_CH_LAYOUT_6POINT0 },        // L, C, R,  Ls, Rs, Cs
135cabdff1aSopenharmony_ci
136cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_DTS_6_0_A,          AV_CH_LAYOUT_6POINT0_FRONT },  // Lc, Rc, L, R, Ls, Rs
137cabdff1aSopenharmony_ci
138cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_DTS_6_0_B,          AV_CH_LAYOUT_5POINT0_BACK |    // C, L, R, Rls, Rrs, Ts
139cabdff1aSopenharmony_ci                                        AV_CH_TOP_CENTER },
140cabdff1aSopenharmony_ci    { 0, 0 },
141cabdff1aSopenharmony_ci};
142cabdff1aSopenharmony_ci
143cabdff1aSopenharmony_cistatic const struct MovChannelLayoutMap mov_ch_layout_map_7ch[] = {
144cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_MPEG_6_1_A,          AV_CH_LAYOUT_6POINT1 },        // L, R, C, LFE, Ls, Rs,  Cs
145cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_AAC_6_1,             AV_CH_LAYOUT_6POINT1 },        // C, L, R, Ls,  Rs, Cs,  LFE
146cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_EAC3_6_1_A,          AV_CH_LAYOUT_6POINT1 },        // L, C, R, Ls,  Rs, LFE, Cs
147cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_DTS_6_1_D,           AV_CH_LAYOUT_6POINT1 },        // C, L, R, Ls,  Rs, LFE, Cs
148cabdff1aSopenharmony_ci
149cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_AUDIOUNIT_7_0,       AV_CH_LAYOUT_7POINT0 },        // L, R, Ls, Rs, C,  Rls, Rrs
150cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_AAC_7_0,             AV_CH_LAYOUT_7POINT0 },        // C, L, R,  Ls, Rs, Rls, Rrs
151cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_EAC3_7_0_A,          AV_CH_LAYOUT_7POINT0 },        // L, C, R,  Ls, Rs, Rls, Rrs
152cabdff1aSopenharmony_ci
153cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_AUDIOUNIT_7_0_FRONT, AV_CH_LAYOUT_7POINT0_FRONT },  // L,  R, Ls, Rs, C, Lc, Rc
154cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_DTS_7_0,             AV_CH_LAYOUT_7POINT0_FRONT },  // Lc, C, Rc, L,  R, Ls, Rs
155cabdff1aSopenharmony_ci
156cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_EAC3_6_1_B,          AV_CH_LAYOUT_5POINT1 |         // L, C, R, Ls, Rs, LFE, Ts
157cabdff1aSopenharmony_ci                                         AV_CH_TOP_CENTER },
158cabdff1aSopenharmony_ci
159cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_EAC3_6_1_C,          AV_CH_LAYOUT_5POINT1 |         // L, C, R, Ls, Rs, LFE, Vhc
160cabdff1aSopenharmony_ci                                         AV_CH_TOP_FRONT_CENTER },
161cabdff1aSopenharmony_ci
162cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_DTS_6_1_A,           AV_CH_LAYOUT_6POINT1_FRONT },  // Lc, Rc, L, R, Ls, Rs, LFE
163cabdff1aSopenharmony_ci
164cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_DTS_6_1_B,           AV_CH_LAYOUT_5POINT1_BACK |    // C, L, R, Rls, Rrs, Ts, LFE
165cabdff1aSopenharmony_ci                                         AV_CH_TOP_CENTER },
166cabdff1aSopenharmony_ci
167cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_DTS_6_1_C,           AV_CH_LAYOUT_6POINT1_BACK },   // C, Cs, L, R, Rls, Rrs, LFE
168cabdff1aSopenharmony_ci    { 0, 0 },
169cabdff1aSopenharmony_ci};
170cabdff1aSopenharmony_ci
171cabdff1aSopenharmony_cistatic const struct MovChannelLayoutMap mov_ch_layout_map_8ch[] = {
172cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_OCTAGONAL,           AV_CH_LAYOUT_OCTAGONAL },      // L, R, Rls, Rrs, C,  Cs,  Ls,  Rs
173cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_AAC_OCTAGONAL,       AV_CH_LAYOUT_OCTAGONAL },      // C, L, R,   Ls,  Rs, Rls, Rrs, Cs
174cabdff1aSopenharmony_ci
175cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_CUBE,                AV_CH_LAYOUT_QUAD     |        // L, R, Rls, Rrs, Vhl, Vhr, Rlt, Rrt
176cabdff1aSopenharmony_ci                                         AV_CH_TOP_FRONT_LEFT  |
177cabdff1aSopenharmony_ci                                         AV_CH_TOP_FRONT_RIGHT |
178cabdff1aSopenharmony_ci                                         AV_CH_TOP_BACK_LEFT   |
179cabdff1aSopenharmony_ci                                         AV_CH_TOP_BACK_RIGHT },
180cabdff1aSopenharmony_ci
181cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_MPEG_7_1_A,          AV_CH_LAYOUT_7POINT1_WIDE },   // L,  R,  C,  LFE, Ls, Rs,  Lc, Rc
182cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_MPEG_7_1_B,          AV_CH_LAYOUT_7POINT1_WIDE },   // C,  Lc, Rc, L,   R,  Ls,  Rs, LFE
183cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_EMAGIC_DEFAULT_7_1,  AV_CH_LAYOUT_7POINT1_WIDE },   // L,  R,  Ls, Rs,  C,  LFE, Lc, Rc
184cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_EAC3_7_1_B,          AV_CH_LAYOUT_7POINT1_WIDE },   // L,  C,  R,  Ls,  Rs, LFE, Lc, Rc
185cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_DTS_7_1,             AV_CH_LAYOUT_7POINT1_WIDE },   // Lc, C,  Rc, L,   R,  Ls,  Rs, LFE
186cabdff1aSopenharmony_ci
187cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_MPEG_7_1_C,          AV_CH_LAYOUT_7POINT1 },        // L, R, C, LFE, Ls, Rs,  Rls, Rrs
188cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_EAC3_7_1_A,          AV_CH_LAYOUT_7POINT1 },        // L, C, R, Ls,  Rs, LFE, Rls, Rrs
189cabdff1aSopenharmony_ci
190cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_SMPTE_DTV,           AV_CH_LAYOUT_5POINT1 |         // L, R, C, LFE, Ls, Rs, Lt, Rt
191cabdff1aSopenharmony_ci                                         AV_CH_LAYOUT_STEREO_DOWNMIX },
192cabdff1aSopenharmony_ci
193cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_EAC3_7_1_C,          AV_CH_LAYOUT_5POINT1        |  // L, C, R, Ls, Rs, LFE, Lsd, Rsd
194cabdff1aSopenharmony_ci                                         AV_CH_SURROUND_DIRECT_LEFT  |
195cabdff1aSopenharmony_ci                                         AV_CH_SURROUND_DIRECT_RIGHT },
196cabdff1aSopenharmony_ci
197cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_EAC3_7_1_D,          AV_CH_LAYOUT_5POINT1 |         // L, C, R, Ls, Rs, LFE, Lw, Rw
198cabdff1aSopenharmony_ci                                         AV_CH_WIDE_LEFT      |
199cabdff1aSopenharmony_ci                                         AV_CH_WIDE_RIGHT },
200cabdff1aSopenharmony_ci
201cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_EAC3_7_1_E,          AV_CH_LAYOUT_5POINT1 |         // L, C, R, Ls, Rs, LFE, Vhl, Vhr
202cabdff1aSopenharmony_ci                                         AV_CH_TOP_FRONT_LEFT |
203cabdff1aSopenharmony_ci                                         AV_CH_TOP_FRONT_RIGHT },
204cabdff1aSopenharmony_ci
205cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_EAC3_7_1_F,          AV_CH_LAYOUT_5POINT1 |         // L, C, R, Ls, Rs, LFE, Cs, Ts
206cabdff1aSopenharmony_ci                                         AV_CH_BACK_CENTER    |
207cabdff1aSopenharmony_ci                                         AV_CH_TOP_CENTER },
208cabdff1aSopenharmony_ci
209cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_EAC3_7_1_G,          AV_CH_LAYOUT_5POINT1 |         // L, C, R, Ls, Rs, LFE, Cs, Vhc
210cabdff1aSopenharmony_ci                                         AV_CH_BACK_CENTER    |
211cabdff1aSopenharmony_ci                                         AV_CH_TOP_FRONT_CENTER },
212cabdff1aSopenharmony_ci
213cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_EAC3_7_1_H,          AV_CH_LAYOUT_5POINT1 |         // L, C, R, Ls, Rs, LFE, Ts, Vhc
214cabdff1aSopenharmony_ci                                         AV_CH_TOP_CENTER     |
215cabdff1aSopenharmony_ci                                         AV_CH_TOP_FRONT_CENTER },
216cabdff1aSopenharmony_ci
217cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_DTS_8_0_A,           AV_CH_LAYOUT_2_2           |   // Lc, Rc, L, R, Ls, Rs, Rls, Rrs
218cabdff1aSopenharmony_ci                                         AV_CH_BACK_LEFT            |
219cabdff1aSopenharmony_ci                                         AV_CH_BACK_RIGHT           |
220cabdff1aSopenharmony_ci                                         AV_CH_FRONT_LEFT_OF_CENTER |
221cabdff1aSopenharmony_ci                                         AV_CH_FRONT_RIGHT_OF_CENTER },
222cabdff1aSopenharmony_ci
223cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_DTS_8_0_B,           AV_CH_LAYOUT_5POINT0        |  // Lc, C, Rc, L, R, Ls, Cs, Rs
224cabdff1aSopenharmony_ci                                         AV_CH_FRONT_LEFT_OF_CENTER  |
225cabdff1aSopenharmony_ci                                         AV_CH_FRONT_RIGHT_OF_CENTER |
226cabdff1aSopenharmony_ci                                         AV_CH_BACK_CENTER },
227cabdff1aSopenharmony_ci    { 0, 0 },
228cabdff1aSopenharmony_ci};
229cabdff1aSopenharmony_ci
230cabdff1aSopenharmony_cistatic const struct MovChannelLayoutMap mov_ch_layout_map_9ch[] = {
231cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_DTS_8_1_A,           AV_CH_LAYOUT_2_2            | // Lc, Rc, L, R, Ls, Rs, Rls, Rrs, LFE
232cabdff1aSopenharmony_ci                                         AV_CH_BACK_LEFT             |
233cabdff1aSopenharmony_ci                                         AV_CH_BACK_RIGHT            |
234cabdff1aSopenharmony_ci                                         AV_CH_FRONT_LEFT_OF_CENTER  |
235cabdff1aSopenharmony_ci                                         AV_CH_FRONT_RIGHT_OF_CENTER |
236cabdff1aSopenharmony_ci                                         AV_CH_LOW_FREQUENCY },
237cabdff1aSopenharmony_ci
238cabdff1aSopenharmony_ci    { MOV_CH_LAYOUT_DTS_8_1_B,           AV_CH_LAYOUT_7POINT1_WIDE   | // Lc, C, Rc, L, R, Ls, Cs, Rs, LFE
239cabdff1aSopenharmony_ci                                         AV_CH_BACK_CENTER },
240cabdff1aSopenharmony_ci    { 0, 0 },
241cabdff1aSopenharmony_ci};
242cabdff1aSopenharmony_ci
243cabdff1aSopenharmony_cistatic const struct MovChannelLayoutMap * const mov_ch_layout_map[] = {
244cabdff1aSopenharmony_ci    mov_ch_layout_map_misc,
245cabdff1aSopenharmony_ci    mov_ch_layout_map_1ch,
246cabdff1aSopenharmony_ci    mov_ch_layout_map_2ch,
247cabdff1aSopenharmony_ci    mov_ch_layout_map_3ch,
248cabdff1aSopenharmony_ci    mov_ch_layout_map_4ch,
249cabdff1aSopenharmony_ci    mov_ch_layout_map_5ch,
250cabdff1aSopenharmony_ci    mov_ch_layout_map_6ch,
251cabdff1aSopenharmony_ci    mov_ch_layout_map_7ch,
252cabdff1aSopenharmony_ci    mov_ch_layout_map_8ch,
253cabdff1aSopenharmony_ci    mov_ch_layout_map_9ch,
254cabdff1aSopenharmony_ci};
255cabdff1aSopenharmony_ci
256cabdff1aSopenharmony_cistatic const enum MovChannelLayoutTag mov_ch_layouts_aac[] = {
257cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_MONO,
258cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_STEREO,
259cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_AC3_1_0_1,
260cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_MPEG_3_0_B,
261cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_ITU_2_1,
262cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_DVD_4,
263cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_QUADRAPHONIC,
264cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_MPEG_4_0_B,
265cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_ITU_2_2,
266cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_AC3_2_1_1,
267cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_DTS_3_1,
268cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_MPEG_5_0_D,
269cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_DVD_18,
270cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_DTS_4_1,
271cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_MPEG_5_1_D,
272cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_AAC_6_0,
273cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_DTS_6_0_A,
274cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_AAC_6_1,
275cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_AAC_7_0,
276cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_DTS_6_1_A,
277cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_AAC_OCTAGONAL,
278cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_MPEG_7_1_B,
279cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_DTS_8_0_A,
280cabdff1aSopenharmony_ci    0,
281cabdff1aSopenharmony_ci};
282cabdff1aSopenharmony_ci
283cabdff1aSopenharmony_cistatic const enum MovChannelLayoutTag mov_ch_layouts_ac3[] = {
284cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_MONO,
285cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_STEREO,
286cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_AC3_1_0_1,
287cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_AC3_3_0,
288cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_ITU_2_1,
289cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_DVD_4,
290cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_AC3_3_1,
291cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_ITU_2_2,
292cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_AC3_2_1_1,
293cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_AC3_3_0_1,
294cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_MPEG_5_0_C,
295cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_DVD_18,
296cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_AC3_3_1_1,
297cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_MPEG_5_1_C,
298cabdff1aSopenharmony_ci    0,
299cabdff1aSopenharmony_ci};
300cabdff1aSopenharmony_ci
301cabdff1aSopenharmony_cistatic const enum MovChannelLayoutTag mov_ch_layouts_alac[] = {
302cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_MONO,
303cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_STEREO,
304cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_MPEG_3_0_B,
305cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_MPEG_4_0_B,
306cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_MPEG_5_0_D,
307cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_MPEG_5_1_D,
308cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_AAC_6_1,
309cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_MPEG_7_1_B,
310cabdff1aSopenharmony_ci    0,
311cabdff1aSopenharmony_ci};
312cabdff1aSopenharmony_ci
313cabdff1aSopenharmony_cistatic const enum MovChannelLayoutTag mov_ch_layouts_wav[] = {
314cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_MONO,
315cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_STEREO,
316cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_MATRIXSTEREO,
317cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_MPEG_3_0_A,
318cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_QUADRAPHONIC,
319cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_MPEG_5_0_A,
320cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_MPEG_5_1_A,
321cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_MPEG_6_1_A,
322cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_MPEG_7_1_A,
323cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_MPEG_7_1_C,
324cabdff1aSopenharmony_ci    MOV_CH_LAYOUT_SMPTE_DTV,
325cabdff1aSopenharmony_ci    0,
326cabdff1aSopenharmony_ci};
327cabdff1aSopenharmony_ci
328cabdff1aSopenharmony_cistatic const struct {
329cabdff1aSopenharmony_ci    enum AVCodecID codec_id;
330cabdff1aSopenharmony_ci    const enum MovChannelLayoutTag *layouts;
331cabdff1aSopenharmony_ci} mov_codec_ch_layouts[] = {
332cabdff1aSopenharmony_ci    { AV_CODEC_ID_AAC,     mov_ch_layouts_aac      },
333cabdff1aSopenharmony_ci    { AV_CODEC_ID_AC3,     mov_ch_layouts_ac3      },
334cabdff1aSopenharmony_ci    { AV_CODEC_ID_ALAC,    mov_ch_layouts_alac     },
335cabdff1aSopenharmony_ci    { AV_CODEC_ID_PCM_U8,    mov_ch_layouts_wav    },
336cabdff1aSopenharmony_ci    { AV_CODEC_ID_PCM_S8,    mov_ch_layouts_wav    },
337cabdff1aSopenharmony_ci    { AV_CODEC_ID_PCM_S16LE, mov_ch_layouts_wav    },
338cabdff1aSopenharmony_ci    { AV_CODEC_ID_PCM_S16BE, mov_ch_layouts_wav    },
339cabdff1aSopenharmony_ci    { AV_CODEC_ID_PCM_S24LE, mov_ch_layouts_wav    },
340cabdff1aSopenharmony_ci    { AV_CODEC_ID_PCM_S24BE, mov_ch_layouts_wav    },
341cabdff1aSopenharmony_ci    { AV_CODEC_ID_PCM_S32LE, mov_ch_layouts_wav    },
342cabdff1aSopenharmony_ci    { AV_CODEC_ID_PCM_S32BE, mov_ch_layouts_wav    },
343cabdff1aSopenharmony_ci    { AV_CODEC_ID_PCM_F32LE, mov_ch_layouts_wav    },
344cabdff1aSopenharmony_ci    { AV_CODEC_ID_PCM_F32BE, mov_ch_layouts_wav    },
345cabdff1aSopenharmony_ci    { AV_CODEC_ID_PCM_F64LE, mov_ch_layouts_wav    },
346cabdff1aSopenharmony_ci    { AV_CODEC_ID_PCM_F64BE, mov_ch_layouts_wav    },
347cabdff1aSopenharmony_ci    { AV_CODEC_ID_NONE,    NULL                    },
348cabdff1aSopenharmony_ci};
349cabdff1aSopenharmony_ci
350cabdff1aSopenharmony_ci/**
351cabdff1aSopenharmony_ci * Get the channel layout for the specified channel layout tag.
352cabdff1aSopenharmony_ci *
353cabdff1aSopenharmony_ci * @param[in]  tag     channel layout tag
354cabdff1aSopenharmony_ci * @param[out] bitmap  channel bitmap (only used if needed)
355cabdff1aSopenharmony_ci * @return             channel layout
356cabdff1aSopenharmony_ci */
357cabdff1aSopenharmony_cistatic uint64_t mov_get_channel_layout(uint32_t tag, uint32_t bitmap)
358cabdff1aSopenharmony_ci{
359cabdff1aSopenharmony_ci    int i, channels;
360cabdff1aSopenharmony_ci    const struct MovChannelLayoutMap *layout_map;
361cabdff1aSopenharmony_ci
362cabdff1aSopenharmony_ci    /* use ff_mov_get_channel_label() to build a layout instead */
363cabdff1aSopenharmony_ci    if (tag == MOV_CH_LAYOUT_USE_DESCRIPTIONS)
364cabdff1aSopenharmony_ci        return 0;
365cabdff1aSopenharmony_ci
366cabdff1aSopenharmony_ci    /* handle the use of the channel bitmap */
367cabdff1aSopenharmony_ci    if (tag == MOV_CH_LAYOUT_USE_BITMAP)
368cabdff1aSopenharmony_ci        return bitmap < 0x40000 ? bitmap : 0;
369cabdff1aSopenharmony_ci
370cabdff1aSopenharmony_ci    /* get the layout map based on the channel count for the specified layout tag */
371cabdff1aSopenharmony_ci    channels = tag & 0xFFFF;
372cabdff1aSopenharmony_ci    if (channels > 9)
373cabdff1aSopenharmony_ci        channels = 0;
374cabdff1aSopenharmony_ci    layout_map = mov_ch_layout_map[channels];
375cabdff1aSopenharmony_ci
376cabdff1aSopenharmony_ci    /* find the channel layout for the specified layout tag */
377cabdff1aSopenharmony_ci    for (i = 0; layout_map[i].tag != 0; i++) {
378cabdff1aSopenharmony_ci        if (layout_map[i].tag == tag)
379cabdff1aSopenharmony_ci            break;
380cabdff1aSopenharmony_ci    }
381cabdff1aSopenharmony_ci    return layout_map[i].layout;
382cabdff1aSopenharmony_ci}
383cabdff1aSopenharmony_ci
384cabdff1aSopenharmony_cistatic uint64_t mov_get_channel_mask(uint32_t label)
385cabdff1aSopenharmony_ci{
386cabdff1aSopenharmony_ci    if (label == 0)
387cabdff1aSopenharmony_ci        return 0;
388cabdff1aSopenharmony_ci    if (label <= 18)
389cabdff1aSopenharmony_ci        return 1U << (label - 1);
390cabdff1aSopenharmony_ci    if (label == 35)
391cabdff1aSopenharmony_ci        return AV_CH_WIDE_LEFT;
392cabdff1aSopenharmony_ci    if (label == 36)
393cabdff1aSopenharmony_ci        return AV_CH_WIDE_RIGHT;
394cabdff1aSopenharmony_ci    if (label == 37)
395cabdff1aSopenharmony_ci        return AV_CH_LOW_FREQUENCY_2;
396cabdff1aSopenharmony_ci    if (label == 38)
397cabdff1aSopenharmony_ci        return AV_CH_STEREO_LEFT;
398cabdff1aSopenharmony_ci    if (label == 39)
399cabdff1aSopenharmony_ci        return AV_CH_STEREO_RIGHT;
400cabdff1aSopenharmony_ci    return 0;
401cabdff1aSopenharmony_ci}
402cabdff1aSopenharmony_ci
403cabdff1aSopenharmony_cistatic uint32_t mov_get_channel_label(enum AVChannel channel)
404cabdff1aSopenharmony_ci{
405cabdff1aSopenharmony_ci    if (channel < 0)
406cabdff1aSopenharmony_ci        return 0;
407cabdff1aSopenharmony_ci    if (channel <= AV_CHAN_TOP_BACK_RIGHT)
408cabdff1aSopenharmony_ci        return channel + 1;
409cabdff1aSopenharmony_ci    if (channel == AV_CHAN_WIDE_LEFT)
410cabdff1aSopenharmony_ci        return 35;
411cabdff1aSopenharmony_ci    if (channel == AV_CHAN_WIDE_RIGHT)
412cabdff1aSopenharmony_ci        return 36;
413cabdff1aSopenharmony_ci    if (channel == AV_CHAN_LOW_FREQUENCY_2)
414cabdff1aSopenharmony_ci        return 37;
415cabdff1aSopenharmony_ci    if (channel == AV_CHAN_STEREO_LEFT)
416cabdff1aSopenharmony_ci        return 38;
417cabdff1aSopenharmony_ci    if (channel == AV_CHAN_STEREO_RIGHT)
418cabdff1aSopenharmony_ci        return 39;
419cabdff1aSopenharmony_ci    return 0;
420cabdff1aSopenharmony_ci}
421cabdff1aSopenharmony_ci
422cabdff1aSopenharmony_ciint ff_mov_get_channel_layout_tag(const AVCodecParameters *par,
423cabdff1aSopenharmony_ci                                  uint32_t *layout,
424cabdff1aSopenharmony_ci                                  uint32_t *bitmap,
425cabdff1aSopenharmony_ci                                  uint32_t **pchannel_desc)
426cabdff1aSopenharmony_ci{
427cabdff1aSopenharmony_ci    int i, j;
428cabdff1aSopenharmony_ci    uint32_t tag = 0;
429cabdff1aSopenharmony_ci    const enum MovChannelLayoutTag *layouts = NULL;
430cabdff1aSopenharmony_ci
431cabdff1aSopenharmony_ci    /* find the layout list for the specified codec */
432cabdff1aSopenharmony_ci    for (i = 0; mov_codec_ch_layouts[i].codec_id != AV_CODEC_ID_NONE; i++) {
433cabdff1aSopenharmony_ci        if (mov_codec_ch_layouts[i].codec_id == par->codec_id)
434cabdff1aSopenharmony_ci            break;
435cabdff1aSopenharmony_ci    }
436cabdff1aSopenharmony_ci    if (mov_codec_ch_layouts[i].codec_id != AV_CODEC_ID_NONE)
437cabdff1aSopenharmony_ci        layouts = mov_codec_ch_layouts[i].layouts;
438cabdff1aSopenharmony_ci
439cabdff1aSopenharmony_ci    if (layouts) {
440cabdff1aSopenharmony_ci        int channels;
441cabdff1aSopenharmony_ci        const struct MovChannelLayoutMap *layout_map;
442cabdff1aSopenharmony_ci
443cabdff1aSopenharmony_ci        /* get the layout map based on the channel count */
444cabdff1aSopenharmony_ci        channels = par->ch_layout.nb_channels;
445cabdff1aSopenharmony_ci        if (channels > 9)
446cabdff1aSopenharmony_ci            channels = 0;
447cabdff1aSopenharmony_ci        layout_map = mov_ch_layout_map[channels];
448cabdff1aSopenharmony_ci
449cabdff1aSopenharmony_ci        /* find the layout tag for the specified channel layout */
450cabdff1aSopenharmony_ci        for (i = 0; layouts[i] != 0; i++) {
451cabdff1aSopenharmony_ci            if ((layouts[i] & 0xFFFF) != channels)
452cabdff1aSopenharmony_ci                continue;
453cabdff1aSopenharmony_ci            for (j = 0; layout_map[j].tag != 0; j++) {
454cabdff1aSopenharmony_ci                if (layout_map[j].tag    == layouts[i] &&
455cabdff1aSopenharmony_ci                    (par->ch_layout.order == AV_CHANNEL_ORDER_NATIVE &&
456cabdff1aSopenharmony_ci                     layout_map[j].layout == par->ch_layout.u.mask))
457cabdff1aSopenharmony_ci                    break;
458cabdff1aSopenharmony_ci            }
459cabdff1aSopenharmony_ci            if (layout_map[j].tag)
460cabdff1aSopenharmony_ci                break;
461cabdff1aSopenharmony_ci        }
462cabdff1aSopenharmony_ci        tag = layouts[i];
463cabdff1aSopenharmony_ci    }
464cabdff1aSopenharmony_ci
465cabdff1aSopenharmony_ci    *layout = tag;
466cabdff1aSopenharmony_ci    *bitmap = 0;
467cabdff1aSopenharmony_ci    *pchannel_desc = NULL;
468cabdff1aSopenharmony_ci
469cabdff1aSopenharmony_ci    /* if no tag was found, use channel bitmap or description as a backup if possible */
470cabdff1aSopenharmony_ci    if (tag == 0) {
471cabdff1aSopenharmony_ci        uint32_t *channel_desc;
472cabdff1aSopenharmony_ci        if (par->ch_layout.order == AV_CHANNEL_ORDER_NATIVE &&
473cabdff1aSopenharmony_ci            par->ch_layout.u.mask < 0x40000) {
474cabdff1aSopenharmony_ci            *layout = MOV_CH_LAYOUT_USE_BITMAP;
475cabdff1aSopenharmony_ci            *bitmap = (uint32_t)par->ch_layout.u.mask;
476cabdff1aSopenharmony_ci            return 0;
477cabdff1aSopenharmony_ci        } else if (par->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC)
478cabdff1aSopenharmony_ci            return AVERROR(ENOSYS);
479cabdff1aSopenharmony_ci
480cabdff1aSopenharmony_ci        channel_desc = av_malloc_array(par->ch_layout.nb_channels, sizeof(*channel_desc));
481cabdff1aSopenharmony_ci        if (!channel_desc)
482cabdff1aSopenharmony_ci            return AVERROR(ENOMEM);
483cabdff1aSopenharmony_ci
484cabdff1aSopenharmony_ci        for (i = 0; i < par->ch_layout.nb_channels; i++) {
485cabdff1aSopenharmony_ci            channel_desc[i] =
486cabdff1aSopenharmony_ci                mov_get_channel_label(av_channel_layout_channel_from_index(&par->ch_layout, i));
487cabdff1aSopenharmony_ci
488cabdff1aSopenharmony_ci            if (channel_desc[i] == 0) {
489cabdff1aSopenharmony_ci                av_free(channel_desc);
490cabdff1aSopenharmony_ci                return AVERROR(ENOSYS);
491cabdff1aSopenharmony_ci            }
492cabdff1aSopenharmony_ci        }
493cabdff1aSopenharmony_ci
494cabdff1aSopenharmony_ci        *pchannel_desc = channel_desc;
495cabdff1aSopenharmony_ci    }
496cabdff1aSopenharmony_ci
497cabdff1aSopenharmony_ci    return 0;
498cabdff1aSopenharmony_ci}
499cabdff1aSopenharmony_ci
500cabdff1aSopenharmony_ciint ff_mov_read_chan(AVFormatContext *s, AVIOContext *pb, AVStream *st,
501cabdff1aSopenharmony_ci                     int64_t size)
502cabdff1aSopenharmony_ci{
503cabdff1aSopenharmony_ci    uint32_t layout_tag, bitmap, num_descr;
504cabdff1aSopenharmony_ci    uint64_t label_mask, mask = 0;
505cabdff1aSopenharmony_ci    int i;
506cabdff1aSopenharmony_ci
507cabdff1aSopenharmony_ci    if (size < 12)
508cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
509cabdff1aSopenharmony_ci
510cabdff1aSopenharmony_ci    layout_tag = avio_rb32(pb);
511cabdff1aSopenharmony_ci    bitmap     = avio_rb32(pb);
512cabdff1aSopenharmony_ci    num_descr  = avio_rb32(pb);
513cabdff1aSopenharmony_ci
514cabdff1aSopenharmony_ci    av_log(s, AV_LOG_DEBUG, "chan: layout=%"PRIu32" "
515cabdff1aSopenharmony_ci           "bitmap=%"PRIu32" num_descr=%"PRIu32"\n",
516cabdff1aSopenharmony_ci           layout_tag, bitmap, num_descr);
517cabdff1aSopenharmony_ci
518cabdff1aSopenharmony_ci    if (size < 12ULL + num_descr * 20ULL)
519cabdff1aSopenharmony_ci        return 0;
520cabdff1aSopenharmony_ci
521cabdff1aSopenharmony_ci    label_mask = 0;
522cabdff1aSopenharmony_ci    for (i = 0; i < num_descr; i++) {
523cabdff1aSopenharmony_ci        uint32_t label;
524cabdff1aSopenharmony_ci        if (pb->eof_reached) {
525cabdff1aSopenharmony_ci            av_log(s, AV_LOG_ERROR,
526cabdff1aSopenharmony_ci                   "reached EOF while reading channel layout\n");
527cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
528cabdff1aSopenharmony_ci        }
529cabdff1aSopenharmony_ci        label     = avio_rb32(pb);          // mChannelLabel
530cabdff1aSopenharmony_ci        avio_rb32(pb);                      // mChannelFlags
531cabdff1aSopenharmony_ci        avio_rl32(pb);                      // mCoordinates[0]
532cabdff1aSopenharmony_ci        avio_rl32(pb);                      // mCoordinates[1]
533cabdff1aSopenharmony_ci        avio_rl32(pb);                      // mCoordinates[2]
534cabdff1aSopenharmony_ci        size -= 20;
535cabdff1aSopenharmony_ci        if (layout_tag == 0) {
536cabdff1aSopenharmony_ci            uint64_t mask_incr = mov_get_channel_mask(label);
537cabdff1aSopenharmony_ci            if (mask_incr == 0) {
538cabdff1aSopenharmony_ci                label_mask = 0;
539cabdff1aSopenharmony_ci                break;
540cabdff1aSopenharmony_ci            }
541cabdff1aSopenharmony_ci            label_mask |= mask_incr;
542cabdff1aSopenharmony_ci        }
543cabdff1aSopenharmony_ci    }
544cabdff1aSopenharmony_ci    if (layout_tag == 0) {
545cabdff1aSopenharmony_ci        if (label_mask)
546cabdff1aSopenharmony_ci            mask = label_mask;
547cabdff1aSopenharmony_ci    } else
548cabdff1aSopenharmony_ci        mask = mov_get_channel_layout(layout_tag, bitmap);
549cabdff1aSopenharmony_ci
550cabdff1aSopenharmony_ci    if (mask) {
551cabdff1aSopenharmony_ci        av_channel_layout_uninit(&st->codecpar->ch_layout);
552cabdff1aSopenharmony_ci        av_channel_layout_from_mask(&st->codecpar->ch_layout, mask);
553cabdff1aSopenharmony_ci    }
554cabdff1aSopenharmony_ci    avio_skip(pb, size - 12);
555cabdff1aSopenharmony_ci
556cabdff1aSopenharmony_ci    return 0;
557cabdff1aSopenharmony_ci}
558