1 /* Copyright (c) MediaArea.net SARL. All Rights Reserved.
2 *
3 * Use of this source code is governed by a BSD-style license that can
4 * be found in the License.html file in the root of the source tree.
5 */
6
7 //---------------------------------------------------------------------------
8 // Pre-compilation
9 #include "MediaInfo/PreComp.h"
10 #ifdef __BORLANDC__
11 #pragma hdrstop
12 #endif
13 //---------------------------------------------------------------------------
14
15 //---------------------------------------------------------------------------
16 #include "MediaInfo/Setup.h"
17 //---------------------------------------------------------------------------
18
19 //---------------------------------------------------------------------------
20 #if defined(MEDIAINFO_MPEGH3DA_YES)
21 //---------------------------------------------------------------------------
22
23 //---------------------------------------------------------------------------
24 #include "MediaInfo/Audio/File_Mpegh3da.h"
25 #include "MediaInfo/MediaInfo_Config_MediaInfo.h"
26 #include <cmath>
27
28 using namespace ZenLib;
29 using namespace std;
30 //---------------------------------------------------------------------------
31
32 namespace MediaInfoLib
33 {
34
35 //***************************************************************************
36 // Info
37 //***************************************************************************
38
39 extern const size_t Aac_sampling_frequency_Size_Usac; // USAC expands Aac_sampling_frequency[]
40 extern const int32u Aac_sampling_frequency[];
41 struct coreSbrFrameLengthIndex_mapping
42 {
43 int8u sbrRatioIndex;
44 int8u outputFrameLengthDivided256;
45 };
46 extern const size_t coreSbrFrameLengthIndex_Mapping_Size;
47 extern coreSbrFrameLengthIndex_mapping coreSbrFrameLengthIndex_Mapping[];
48 extern int8u Aac_Channels_Get(int8u ChannelLayout);
49 extern string Aac_Channels_GetString(int8u ChannelLayout);
50 extern string Aac_ChannelConfiguration_GetString(int8u ChannelLayout);
51 extern string Aac_ChannelConfiguration2_GetString(int8u ChannelLayout);
52 extern string Aac_ChannelLayout_GetString(const Aac_OutputChannel* const OutputChannels, size_t OutputChannels_Size);
53 extern string Aac_ChannelLayout_GetString(int8u ChannelLayout, bool IsMpegh3da=false);
54 extern string Aac_ChannelLayout_GetString(const vector<Aac_OutputChannel>& OutputChannels);
55 extern string Aac_ChannelMode_GetString(int8u ChannelLayout, bool IsMpegh3da=false);
56 extern string Aac_ChannelMode_GetString(const vector<Aac_OutputChannel>& OutputChannels);
57 extern string Aac_OutputChannelPosition_GetString(int8u OutputChannelPosition);
58
59 //---------------------------------------------------------------------------
60 static const char* const Mpegh3da_Profile[]=
61 {
62 "Main",
63 "High",
64 "LC",
65 "BL",
66 };
67 static size_t Mpegh3da_Profile_Size=sizeof(Mpegh3da_Profile)/sizeof(const char* const);
Mpegh3da_Profile_Get(int8u mpegh3daProfileLevelIndication)68 extern string Mpegh3da_Profile_Get(int8u mpegh3daProfileLevelIndication)
69 {
70 if (!mpegh3daProfileLevelIndication)
71 return string();
72 if (mpegh3daProfileLevelIndication>=5*Mpegh3da_Profile_Size)
73 return Ztring::ToZtring(mpegh3daProfileLevelIndication).To_UTF8(); // Raw value
74 return string(Mpegh3da_Profile[(mpegh3daProfileLevelIndication-1)/5])+"@L"+char('1'+((mpegh3daProfileLevelIndication-1)%5));
75 }
76
77 //---------------------------------------------------------------------------
78 static const char* const Mpegh3da_MHASPacketType[]=
79 {
80 "FILLDATA",
81 "MPEGH3DACFG",
82 "MPEGH3DAFRAME",
83 "AUDIOSCENEINFO",
84 "",
85 "",
86 "SYNC",
87 "SYNCGAP",
88 "MARKER",
89 "CRC16",
90 "CRC32",
91 "DESCRIPTOR",
92 "USERINTERACTION",
93 "LOUDNESS_DRC",
94 "BUFFERINFO",
95 "GLOBAL_CRC16",
96 "GLOBAL_CRC32",
97 "AUDIOTRUNCATION",
98 "GENDATA",
99 };
100 static const size_t Mpegh3da_MHASPacketType_Size=sizeof(Mpegh3da_MHASPacketType)/sizeof(const char* const);
101
102 //---------------------------------------------------------------------------
103 static const char* const Mpegh3da_contentKind[]=
104 {
105 "",
106 "Complete Main",
107 "Dialogue",
108 "Music",
109 "Effect",
110 "Mixed",
111 "LFE",
112 "Voiceover",
113 "Spoken Subtitle",
114 "Visually Impaired or Audio Description",
115 "Commentary",
116 "Hearing Impaired",
117 "Emergency",
118 };
119 static const size_t Mpegh3da_contentKind_Size=sizeof(Mpegh3da_contentKind)/sizeof(const char* const);
120
121 //---------------------------------------------------------------------------
122 static const char* const Mpegh3da_groupPresetKind[]=
123 {
124 "",
125 "Integrated TV Loudspeaker",
126 "High Quality Loudspeaker",
127 "Mobile Loudspeakers",
128 "Mobile Headphones",
129 "Hearing Impaired (light)",
130 "Hearing Impaired (heavy)",
131 "Visually Impaired or Audio Description",
132 "Spoken Subtitles",
133 "Loudness or DRC",
134 };
135 static const size_t Mpegh3da_groupPresetKind_Size=sizeof(Mpegh3da_groupPresetKind)/sizeof(const char* const);
136
137 //---------------------------------------------------------------------------
138 static const char* const Mpegh3da_signalGroupType[]=
139 {
140 "Channels",
141 "Object",
142 "SAOC",
143 "HOA",
144 };
145 static const size_t Mpegh3da_signalGroupType_Size=sizeof(Mpegh3da_signalGroupType)/sizeof(const char* const);
146
147 //---------------------------------------------------------------------------
148 static const char* const Mpegh3da_marker_byte[]=
149 {
150 "",
151 "Configuration change marker",
152 "Random access or Immediate playout marker",
153 "Program boundary marker",
154 };
155 static const size_t Mpegh3da_marker_byte_Size=sizeof(Mpegh3da_marker_byte)/sizeof(const char* const);
156
157 //---------------------------------------------------------------------------
158 static const char* const Mpegh3da_usacElementType[4]=
159 {
160 "SCE",
161 "CPE",
162 "LFE",
163 "EXT",
164 };
165
166 //---------------------------------------------------------------------------
167 static const char* const Mpegh3da_usacExtElementType[]=
168 {
169 "FILL",
170 "MPEGS",
171 "SAOC",
172 "AUDIOPREROLL",
173 "UNI_DRC",
174 "OBJ_METADATA",
175 "SAOC_3D",
176 "HOA",
177 "FMT_CNVRTR",
178 "MCT",
179 "TCC",
180 "HOA_ENH_LAYER",
181 "HREP",
182 "ENHANCED_OBJ_METADATA",
183 };
184 static const size_t Mpegh3da_usacExtElementType_Size=sizeof(Mpegh3da_usacExtElementType)/sizeof(const char* const);
185
186 //---------------------------------------------------------------------------
187 static const char* const Mpegh3da_usacConfigExtType[]=
188 {
189 "FILL",
190 "DOWNMIX",
191 "LOUDNESS_INFO",
192 "AUDIOSCENE_INFO",
193 "HOA_MATRIX",
194 "ICG",
195 "SIG_GROUP_INFO",
196 "COMPATIBLE_PROFILE_LEVEL_SET",
197 };
198 static const size_t Mpegh3da_usacConfigExtType_Size=sizeof(Mpegh3da_usacConfigExtType)/sizeof(const char* const);
199
200 //---------------------------------------------------------------------------
201 static const size_t Mpegh3da_SpeakerInfo_Size=43;
202 static const speaker_info Mpegh3da_SpeakerInfo[Mpegh3da_SpeakerInfo_Size]=
203 {
204 {CH_M_L030, 30, false, 0, false, false},
205 {CH_M_R030, 30, true , 0, false, false},
206 {CH_M_000 , 0, false, 0, false, false},
207 {CH_LFE , 0, false, 15, true , true},
208 {CH_M_L110, 110, false, 0, false, false},
209 {CH_M_R110, 110, true , 0, false, false},
210 {CH_M_L022, 22, false, 0, false, false},
211 {CH_M_R022, 22, true , 0, false, false},
212 {CH_M_L135, 135, false, 0, false, false},
213 {CH_M_R135, 135, true , 0, false, false},
214 {CH_M_180 , 180, false, 0, false, false},
215 {CH_M_LSD , 135, false, 0, false, false},
216 {CH_M_RSD , 135, true , 0, false, false},
217 {CH_M_L090, 90, false, 0, false, false},
218 {CH_M_R090, 90, true , 0, false, false},
219 {CH_M_L060, 60, false, 0, false, false},
220 {CH_M_R060, 60, true , 0, false, false},
221 {CH_U_L030, 30, false, 35, false, false},
222 {CH_U_R030, 30, true , 35, false, false},
223 {CH_U_000 , 0, false, 35, false, false},
224 {CH_U_L135, 135, false, 35, false, false},
225 {CH_U_R135, 135, true , 35, false, false},
226 {CH_U_180 , 180, false, 35, false, false},
227 {CH_U_L090, 90, false, 35, false, false},
228 {CH_U_R090, 90, true , 35, false, false},
229 {CH_T_000 , 0, false, 90, false, false},
230 {CH_LFE2 , 45, false, 15, true , true},
231 {CH_L_L045, 45, false, 15, true , false},
232 {CH_L_R045, 45, true , 15, true , false},
233 {CH_L_000 , 0, false, 15, true , false},
234 {CH_U_L110, 110, false, 35, false, false},
235 {CH_U_R110, 110, true , 35, false, false},
236 {CH_U_L045, 45, false, 35, false, false},
237 {CH_U_R045, 45, true , 35, false, false},
238 {CH_M_L045, 45, false, 0, false, false},
239 {CH_M_R045, 45, true , 0, false, false},
240 {CH_LFE3 , 45, true , 15, true , true},
241 {CH_M_LSCR, 2, false, 0, false, false},
242 {CH_M_RSCR, 2, true , 0, false, false},
243 {CH_M_LSCH, 1, false, 0, false, false},
244 {CH_M_RSCH, 1, true , 0, false, false},
245 {CH_M_L150, 150, false, 0, false, false},
246 {CH_M_R150, 150, true , 0, false, false},
247 };
248
249 //***************************************************************************
250 // Constructor/Destructor
251 //***************************************************************************
252
253 //---------------------------------------------------------------------------
File_Mpegh3da()254 File_Mpegh3da::File_Mpegh3da()
255 :File_Usac()
256 {
257 //Configuration
258 #if MEDIAINFO_TRACE
259 Trace_Layers_Update(8); //Stream
260 #endif //MEDIAINFO_TRACE
261
262 //In
263 MustParse_mhaC=false;
264 MustParse_mpegh3daFrame=false;
265
266 //Temp
267 audioSceneInfoID=0;
268 isMainStream=(int8u)-1;
269 }
270
271 //***************************************************************************
272 // Streams management
273 //***************************************************************************
274
275 //---------------------------------------------------------------------------
Streams_Fill()276 void File_Mpegh3da::Streams_Fill()
277 {
278 Stream_Prepare(Stream_Audio);
279 Fill(Stream_Audio, 0, Audio_Format, "MPEG-H 3D Audio");
280 string Format_Profile=Mpegh3da_Profile_Get(mpegh3daProfileLevelIndication);
281 for (size_t Pos=0; Pos<mpegh3daCompatibleProfileLevelSet.size(); Pos++)
282 {
283 Format_Profile+=", ";
284 Format_Profile+=Mpegh3da_Profile_Get(mpegh3daCompatibleProfileLevelSet[Pos]);
285 }
286 Fill(Stream_Audio, 0, Audio_Format_Profile, Format_Profile);
287 Fill(Stream_Audio, 0, Audio_SamplingRate, usacSamplingFrequency);
288 Fill(Stream_Audio, 0, Audio_SamplesPerFrame, coreSbrFrameLengthIndex_Mapping[coreSbrFrameLengthIndex].outputFrameLengthDivided256<<8);
289 if (isMainStream!=(int8u)-1)
290 Fill(Stream_Audio, 0, "Type", isMainStream?"Main":"Auxiliary");
291 Fill_SetOptions(Stream_Audio, 0, "Type", "N NTY");
292 for (set<int32u>::iterator Label=MHASPacketLabels.begin(); Label!=MHASPacketLabels.end(); ++Label)
293 Fill(Stream_Audio, 0, "Label", *Label);
294 Fill_SetOptions(Stream_Audio, 0, "Label", "N NTY");
295 Ztring LabelString=Retrieve(Stream_Audio, 0, "Label");
296 const Ztring& Type=Retrieve_Const(Stream_Audio, 0, "Type");
297 if (!LabelString.empty() && !Type.empty())
298 {
299 if (!LabelString.empty())
300 LabelString+=__T(' ');
301 LabelString+=__T('(')+Type+__T(')');
302 }
303 if (LabelString.empty())
304 Fill(Stream_Audio, 0, "Label/String", LabelString);
305 Fill_SetOptions(Stream_Audio, 0, "Label/String", "Y NTN");
306 if (audioSceneInfoID)
307 Fill(Stream_Audio, 0, "AudioSceneInfoID", audioSceneInfoID);
308 Streams_Fill_ChannelLayout(string(), referenceLayout);
309 if (!GroupPresets.empty())
310 {
311 Fill(Stream_Audio, 0, "GroupPresetCount", GroupPresets.size());
312 Fill_SetOptions(Stream_Audio, 0, "GroupPresetCount", "N NIY");
313 }
314 if (!SwitchGroups.empty())
315 {
316 Fill(Stream_Audio, 0, "SwitchGroupCount", SwitchGroups.size());
317 Fill_SetOptions(Stream_Audio, 0, "SwitchGroupCount", "N NIY");
318 }
319 if (!Groups.empty())
320 {
321 Fill(Stream_Audio, 0, "GroupCount", Groups.size());
322 Fill_SetOptions(Stream_Audio, 0, "GroupCount", "N NIY");
323 }
324 if (!SignalGroups.empty())
325 {
326 Fill(Stream_Audio, 0, "SignalGroupCount", SignalGroups.size());
327 Fill_SetOptions(Stream_Audio, 0, "SignalGroupCount", "N NIY");
328 }
329
330 // Filling
331 if (!Mpegh3da_drcInstructionsUniDrc_Data[0].empty())
332 {
333 drcInstructionsUniDrc_Data=Mpegh3da_drcInstructionsUniDrc_Data[0].begin()->second;
334 Fill_DRC();
335 drcInstructionsUniDrc_Data.clear();
336 }
337 /*
338 if (!Mpegh3da_loudnessInfo_Data[0].empty() && !GroupPresets.empty())
339 {
340 int8u ID=(int8u)-1;
341 for (size_t i=0; i<GroupPresets.size(); i++)
342 {
343 const group_preset& P=GroupPresets[i];
344 if (P.ID<ID)
345 ID=P.ID;
346 if (Mpegh3da_loudnessInfo_Data[3][ID].Data[0].empty())
347 {
348 Mpegh3da_loudnessInfo_Data[3][ID].Data[0]=Mpegh3da_loudnessInfo_Data[0].begin()->second.Data[0];
349 Mpegh3da_loudnessInfo_Data[0].begin()->second.Data[0].clear();
350 }
351 }
352 }
353 */
354 bool NoLoudnesConch;
355 if (!Mpegh3da_loudnessInfo_Data[0].empty())
356 {
357 loudnessInfo_Data[0]=Mpegh3da_loudnessInfo_Data[0].begin()->second.Data[0];
358 loudnessInfo_Data[1]=Mpegh3da_loudnessInfo_Data[0].begin()->second.Data[1];
359 loudnessInfoSet_Present=true;
360 Fill_Loudness(NULL);
361 loudnessInfo_Data[0].clear();
362 loudnessInfo_Data[1].clear();
363 NoLoudnesConch=true;
364 }
365 else
366 NoLoudnesConch=false;
367
368 for (size_t i=0; i<GroupPresets.size(); i++)
369 {
370 const group_preset& P=GroupPresets[i];
371
372 string Summary;
373 if (!P.Description.empty())
374 Summary+=P.Description.begin()->second;
375 if (Summary.empty())
376 Summary="Yes";
377
378 string p=string("GroupPreset")+Ztring::ToZtring(i).To_UTF8();
379 Fill(Stream_Audio, 0, p.c_str(), Summary);
380 Fill(Stream_Audio, 0, (p+" Pos").c_str(), i);
381 Fill_SetOptions(Stream_Audio, 0, (p+" Pos").c_str(), "N NIY");
382 Fill(Stream_Audio, 0, (p+" ID").c_str(), P.ID);
383 for (map<string, string>::const_iterator Desc=P.Description.begin(); Desc!=P.Description.end(); ++Desc)
384 {
385 Ztring Language=MediaInfoLib::Config.Iso639_1_Get(Ztring().From_UTF8(Desc->first));
386 if (Language.empty())
387 Language=Ztring().From_UTF8(Desc->first);
388 Fill(Stream_Audio, 0, (p+" Title").c_str(), '('+MediaInfoLib::Config.Language_Get_Translate(__T("Language_"), Language).To_UTF8() + ") "+Desc->second);
389 }
390 if (P.Kind<Mpegh3da_groupPresetKind_Size)
391 Fill(Stream_Audio, 0, (p+" Kind").c_str(), Mpegh3da_groupPresetKind[P.Kind]);
392 if (!Mpegh3da_drcInstructionsUniDrc_Data[3].empty())
393 {
394 std::map<int8u, std::map<int16u, drc_info> >::iterator drcInstructionsUniDrc=Mpegh3da_drcInstructionsUniDrc_Data[3].find(P.ID);
395 if (drcInstructionsUniDrc!=Mpegh3da_drcInstructionsUniDrc_Data[3].end())
396 {
397 drcInstructionsUniDrc_Data=drcInstructionsUniDrc->second;
398 Fill_DRC(p.c_str());
399 drcInstructionsUniDrc_Data.clear();
400 }
401 }
402 if (!Mpegh3da_loudnessInfo_Data[3].empty())
403 {
404 std::map<int8u, loudness_info_data>::iterator Loudness=Mpegh3da_loudnessInfo_Data[3].find(P.ID);
405 if (Loudness!=Mpegh3da_loudnessInfo_Data[3].end())
406 {
407 loudnessInfo_Data[0]=Loudness->second.Data[0];
408 loudnessInfoSet_Present=true;
409 Fill_Loudness(p.c_str(), NoLoudnesConch);
410 loudnessInfo_Data[0].clear();
411 }
412 }
413 /* Disabled for the moment, need more details about how to show it
414 ZtringList IDs;
415 if (P.Conditions.size()==1 && P.Conditions[0].ReferenceID==127 && !P.Conditions[0].ConditionOnOff)
416 {
417 Fill(Stream_Audio, 0, (p+" LinkedTo_Group_Pos").c_str(), "Full user interactivity");
418 Fill_SetOptions(Stream_Audio, 0, (p+" LinkedTo_Group_Pos").c_str(), "N NTY");
419 Fill(Stream_Audio, 0, (p+" LinkedTo_Group_Pos/String").c_str(), "Full user interactivity");
420 Fill_SetOptions(Stream_Audio, 0, (p+" LinkedTo_Group_Pos/String").c_str(), "Y NTN");
421 }
422 else
423 {
424 ZtringList GroupPos, GroupNum;
425 for (size_t i=0; i<P.Conditions.size(); i++)
426 {
427 for (size_t j=0; j<Groups.size(); j++)
428 if (Groups[j].ID==P.Conditions[i].ReferenceID)
429 {
430 GroupPos.push_back(Ztring::ToZtring(j));
431 GroupNum.push_back(Ztring::ToZtring(j+1));
432 }
433 }
434 GroupPos.Separator_Set(0, __T(" + "));
435 Fill(Stream_Audio, 0, (p+" LinkedTo_Group_Pos").c_str(), GroupPos.Read());
436 Fill_SetOptions(Stream_Audio, 0, (p+" LinkedTo_Group_Pos").c_str(), "N NTY");
437 GroupNum.Separator_Set(0, __T(" + "));
438 Fill(Stream_Audio, 0, (p+" LinkedTo_Group_Pos/String").c_str(), GroupNum.Read());
439 Fill_SetOptions(Stream_Audio, 0, (p+" LinkedTo_Group_Pos/String").c_str(), "Y NTN");
440 }
441 */
442 }
443
444 for (size_t i=0; i<SwitchGroups.size(); i++)
445 {
446 const switch_group& S=SwitchGroups[i];
447
448 string Summary;
449 if (!S.Description.empty())
450 Summary+=S.Description.begin()->second;
451 if (Summary.empty())
452 Summary="Yes";
453
454 string s=string("SwitchGroup")+Ztring::ToZtring(i).To_UTF8();
455 Fill(Stream_Audio, 0, s.c_str(), Summary);
456 Fill(Stream_Audio, 0, (s+" Pos").c_str(), i);
457 Fill_SetOptions(Stream_Audio, 0, (s+" Pos").c_str(), "N NIY");
458 Fill(Stream_Audio, 0, (s+" ID").c_str(), S.ID);
459 for (map<string, string>::const_iterator Desc=S.Description.begin(); Desc!=S.Description.end(); ++Desc)
460 {
461 Ztring Language=MediaInfoLib::Config.Iso639_1_Get(Ztring().From_UTF8(Desc->first));
462 if (Language.empty())
463 Language=Ztring().From_UTF8(Desc->first);
464 Fill(Stream_Audio, 0, (s+" Title").c_str(), '('+MediaInfoLib::Config.Language_Get_Translate(__T("Language_"), Language).To_UTF8() + ") "+Desc->second);
465 }
466 Fill(Stream_Audio, 0, (s+" Allow").c_str(), S.allowOnOff?"Yes":"No");
467 if (S.allowOnOff)
468 Fill(Stream_Audio, 0, (s+" Default").c_str(), S.defaultOnOff?"Yes":"No");
469 Fill(Stream_Audio, 0, (s+" DefaultGroupID").c_str(), S.DefaultGroupID);
470
471 ZtringList GroupPos, GroupNum;
472 for (size_t i=0; i<S.MemberID.size(); i++)
473 {
474 for (size_t j=0; j<Groups.size(); j++)
475 if (Groups[j].ID==S.MemberID[i])
476 {
477 GroupPos.push_back(Ztring::ToZtring(j));
478 GroupNum.push_back(Ztring::ToZtring(j+1));
479 }
480 }
481 GroupPos.Separator_Set(0, __T(" + "));
482 Fill(Stream_Audio, 0, (s+" LinkedTo_Group_Pos").c_str(), GroupPos.Read());
483 Fill_SetOptions(Stream_Audio, 0, (s+" LinkedTo_Group_Pos").c_str(), "N NTY");
484 GroupNum.Separator_Set(0, __T(" + "));
485 Fill(Stream_Audio, 0, (s+" LinkedTo_Group_Pos/String").c_str(), GroupNum.Read());
486 Fill_SetOptions(Stream_Audio, 0, (s+" LinkedTo_Group_Pos/String").c_str(), "Y NTN");
487 }
488
489 for (size_t i=0; i<Groups.size(); i++)
490 {
491 const group& G=Groups[i];
492
493 string Summary;
494 if (!G.Description.empty())
495 Summary+=G.Description.begin()->second;
496 if (Summary.empty())
497 Summary="Yes";
498
499 string g=string("Group")+Ztring::ToZtring(i).To_UTF8();
500 Fill(Stream_Audio, 0, g.c_str(), Summary);
501 Fill(Stream_Audio, 0, (g+" Pos").c_str(), i);
502 Fill_SetOptions(Stream_Audio, 0, (g+" Pos").c_str(), "N NIY");
503 Fill(Stream_Audio, 0, (g+" ID").c_str(), G.ID);
504 for (map<string, string>::const_iterator Desc=G.Description.begin(); Desc!=G.Description.end(); ++Desc)
505 {
506 Ztring Language=MediaInfoLib::Config.Iso639_1_Get(Ztring().From_UTF8(Desc->first));
507 if (Language.empty())
508 Language=Ztring().From_UTF8(Desc->first);
509 Fill(Stream_Audio, 0, (g+" Title").c_str(), '('+MediaInfoLib::Config.Language_Get_Translate(__T("Language_"), Language).To_UTF8() + ") "+Desc->second);
510 }
511 if (!G.Language.empty())
512 {
513 Fill(Stream_Audio, 0, (g+" Language").c_str(), G.Language);
514 Fill(Stream_Audio, 0, (g+" Language/String").c_str(), MediaInfoLib::Config.Iso639_Translate(Ztring().From_UTF8(G.Language)));
515 Fill_SetOptions(Stream_Audio, 0, (g+" Language").c_str(), "N NTY");
516 Fill_SetOptions(Stream_Audio, 0, (g+" Language/String").c_str(), "Y NTN");
517 }
518 if (G.Kind<Mpegh3da_contentKind_Size)
519 Fill(Stream_Audio, 0, (g+" Kind").c_str(), Mpegh3da_contentKind[G.Kind]);
520 Fill(Stream_Audio, 0, (g+" Allow").c_str(), G.allowOnOff?"Yes":"No");
521 if (G.allowOnOff)
522 Fill(Stream_Audio, 0, (g+" Default").c_str(), G.defaultOnOff?"Yes":"No");
523 if (!Mpegh3da_drcInstructionsUniDrc_Data[1].empty())
524 {
525 std::map<int8u, std::map<int16u, drc_info> >::iterator drcInstructionsUniDrc=Mpegh3da_drcInstructionsUniDrc_Data[1].find(G.ID);
526 if (drcInstructionsUniDrc!=Mpegh3da_drcInstructionsUniDrc_Data[1].end())
527 {
528 drcInstructionsUniDrc_Data=drcInstructionsUniDrc->second;
529 Fill_DRC(g.c_str());
530 drcInstructionsUniDrc_Data.clear();
531 }
532 }
533 if (!Mpegh3da_loudnessInfo_Data[1].empty())
534 {
535 std::map<int8u, loudness_info_data>::iterator Loudness=Mpegh3da_loudnessInfo_Data[1].find(G.ID);
536 if (Loudness!=Mpegh3da_loudnessInfo_Data[1].end())
537 {
538 loudnessInfo_Data[0]=Loudness->second.Data[0];
539 loudnessInfoSet_Present=true;
540 Fill_Loudness(g.c_str(), NoLoudnesConch);
541 loudnessInfo_Data[0].clear();
542 }
543 }
544 if (!Mpegh3da_drcInstructionsUniDrc_Data[2].empty()) // Not sure
545 {
546 std::map<int8u, std::map<int16u, drc_info> >::iterator drcInstructionsUniDrc=Mpegh3da_drcInstructionsUniDrc_Data[2].find(G.ID);
547 if (drcInstructionsUniDrc!=Mpegh3da_drcInstructionsUniDrc_Data[2].end())
548 {
549 drcInstructionsUniDrc_Data=drcInstructionsUniDrc->second;
550 Fill_DRC(g.c_str());
551 drcInstructionsUniDrc_Data.clear();
552 }
553 }
554 if (!Mpegh3da_loudnessInfo_Data[2].empty()) // Not sure
555 {
556 std::map<int8u, loudness_info_data>::iterator Loudness=Mpegh3da_loudnessInfo_Data[2].find(G.ID);
557 if (Loudness!=Mpegh3da_loudnessInfo_Data[2].end())
558 {
559 loudnessInfo_Data[0]=Loudness->second.Data[0];
560 loudnessInfoSet_Present=true;
561 Fill_Loudness(g.c_str(), NoLoudnesConch);
562 loudnessInfo_Data[0].clear();
563 }
564 }
565
566 ZtringList GroupPos, GroupNum;
567 for (size_t i=0; i<G.MemberID.size(); i++)
568 {
569 size_t Signal_Count=0;
570 for (size_t j=0; j<SignalGroups.size(); j++)
571 {
572 const signal_group& E=SignalGroups[j];
573 if (Signal_Count==G.MemberID[i])
574 {
575 GroupPos.push_back(Ztring::ToZtring(j));
576 GroupNum.push_back(Ztring::ToZtring(j+1));
577 }
578 if (Aac_Channels_Get(E.Layout.ChannelLayout))
579 Signal_Count+=Aac_Channels_Get(E.Layout.ChannelLayout);
580 else if (E.Layout.numSpeakers)
581 Signal_Count+=E.Layout.numSpeakers;
582 }
583 }
584 GroupPos.Separator_Set(0, __T(" + "));
585 Fill(Stream_Audio, 0, (g+" LinkedTo_SignalGroup_Pos").c_str(), GroupPos.Read());
586 Fill_SetOptions(Stream_Audio, 0, (g+" LinkedTo_SignalGroup_Pos").c_str(), "N NTY");
587 GroupNum.Separator_Set(0, __T(" + "));
588 Fill(Stream_Audio, 0, (g+" LinkedTo_SignalGroup_Pos/String").c_str(), GroupNum.Read());
589 Fill_SetOptions(Stream_Audio, 0, (g+" LinkedTo_SignalGroup_Pos/String").c_str(), "Y NTN");
590 }
591
592 for (size_t i=0; i<SignalGroups.size(); i++)
593 {
594 const signal_group& E=SignalGroups[i];
595
596 string e=string("SignalGroup")+Ztring::ToZtring(i).To_UTF8();
597 Fill(Stream_Audio, 0, e.c_str(), "Yes");
598 Fill(Stream_Audio, 0, (e+" Pos").c_str(), i);
599 Fill_SetOptions(Stream_Audio, 0, (e+" Pos").c_str(), "N NIY");
600 if (E.Type<Mpegh3da_signalGroupType_Size)
601 Fill(Stream_Audio, 0, (e+" Type").c_str(), Mpegh3da_signalGroupType[E.Type]);
602 Streams_Fill_ChannelLayout(e+' ', E.Layout, E.Type);
603
604 string Summary;
605 switch (E.Type)
606 {
607 case 0 : //Channels
608 Summary+=Retrieve_Const(Stream_Audio, 0, (e+" Channel(s)/String").c_str()).To_UTF8();
609 break;
610 case 1 : // Objects
611 Summary+=Retrieve_Const(Stream_Audio, 0, (e+" NumberOfObjects/String").c_str()).To_UTF8();
612 break;
613 default:
614 Summary+=Mpegh3da_signalGroupType[E.Type];
615 }
616 if (!Summary.empty())
617 Fill(Stream_Audio, 0, e.c_str(), Summary, true, true);
618 }
619 }
620
621 //---------------------------------------------------------------------------
Streams_Finish()622 void File_Mpegh3da::Streams_Finish()
623 {
624 }
625
626 //***************************************************************************
627 // Buffer - Global
628 //***************************************************************************
629
630 //---------------------------------------------------------------------------
Read_Buffer_Continue()631 void File_Mpegh3da::Read_Buffer_Continue()
632 {
633 if (MustParse_mhaC)
634 {
635 mhaC();
636 MustParse_mhaC=false;
637 MustParse_mpegh3daFrame=true;
638 Skip_XX(Element_Size-Element_Offset, "Unknown");
639 return;
640 }
641 if (MustParse_mpegh3daFrame)
642 {
643 mpegh3daFrame();
644 }
645 }
646
647 //***************************************************************************
648 // Buffer - Per element
649 //***************************************************************************
650
651 //---------------------------------------------------------------------------
Header_Parse()652 void File_Mpegh3da::Header_Parse()
653 {
654 //Parsing
655 int32u MHASPacketType, MHASPacketLabel, MHASPacketLength;
656 BS_Begin();
657 escapedValue(MHASPacketType, 3, 8, 8, "MHASPacketType");
658 escapedValue(MHASPacketLabel, 2, 8, 32, "MHASPacketLabel");
659 escapedValue(MHASPacketLength, 11, 24, 24, "MHASPacketLength");
660 BS_End();
661
662 FILLING_BEGIN();
663 if (MHASPacketLabel)
664 MHASPacketLabels.insert(MHASPacketLabel);
665 Header_Fill_Code(MHASPacketType, MHASPacketType<Mpegh3da_MHASPacketType_Size?Ztring().From_UTF8(Mpegh3da_MHASPacketType[MHASPacketType]):Ztring().From_CC3(MHASPacketType));
666 Header_Fill_Size(Element_Offset+MHASPacketLength);
667 FILLING_END();
668 }
669
670 //---------------------------------------------------------------------------
Data_Parse()671 void File_Mpegh3da::Data_Parse()
672 {
673 //Parsing
674 switch (Element_Code)
675 {
676 case 1 : mpegh3daConfig(); break;
677 case 2 : mpegh3daFrame(); break;
678 case 3 : BS_Begin(); mae_AudioSceneInfo(); BS_End(); break;
679 case 6 : Sync(); break;
680 case 8 : Marker(); break;
681 case 9 : Crc16(); break;
682 case 14 : BufferInfo(); break;
683 case 17 : audioTruncationInfo(); break;
684 default : Skip_XX(Element_Size-Element_Offset, "Data");
685 }
686
687 if (!Trusted_Get())
688 Fill(Stream_Audio, 0, "NOK", "NOK", Unlimited, true, true);
689 }
690
691 //***************************************************************************
692 // Elements
693 //***************************************************************************
694
695 //---------------------------------------------------------------------------
mpegh3daConfig()696 void File_Mpegh3da::mpegh3daConfig()
697 {
698 Element_Begin1("mpegh3daConfig");
699 BS_Begin();
700 int8u usacSamplingFrequencyIndex;
701 Get_S1(8, mpegh3daProfileLevelIndication, "mpegh3daProfileLevelIndication"); Param_Info1(Mpegh3da_Profile_Get(mpegh3daProfileLevelIndication));
702 Get_S1 (5, usacSamplingFrequencyIndex, "usacSamplingFrequencyIndex");
703 if (usacSamplingFrequencyIndex==0x1f)
704 Get_S3 (24, usacSamplingFrequency, "usacSamplingFrequency");
705 else
706 {
707 if (usacSamplingFrequencyIndex<Aac_sampling_frequency_Size_Usac)
708 usacSamplingFrequency=Aac_sampling_frequency[usacSamplingFrequencyIndex];
709 else
710 usacSamplingFrequency=0;
711 }
712 Get_S1 (3, coreSbrFrameLengthIndex, "coreSbrFrameLengthIndex");
713 Skip_SB( "cfg_reserved");
714 Skip_SB( "receiverDelayCompensation");
715 SpeakerConfig3d(referenceLayout);
716 FrameworkConfig3d();
717 mpegh3daDecoderConfig();
718 TEST_SB_SKIP( "usacConfigExtensionPresent");
719 mpegh3daConfigExtension();
720 TEST_SB_END();
721 BS_End();
722 Element_End0();
723
724 FILLING_BEGIN();
725 //Filling
726 if (!Status[IsAccepted])
727 Accept("MPEG-H 3D Audio");
728 FILLING_END();
729 }
730
731 //---------------------------------------------------------------------------
SpeakerConfig3d(speaker_layout & Layout)732 void File_Mpegh3da::SpeakerConfig3d(speaker_layout& Layout)
733 {
734 int8u speakerLayoutType;
735 Element_Begin1("SpeakerConfig3d");
736 Get_S1(2, speakerLayoutType, "speakerLayoutType");
737 if (speakerLayoutType==0)
738 {
739 Get_S1 (6, Layout.ChannelLayout, "CICPspeakerLayoutIdx"); Param_Info2(Aac_Channels_Get(Layout.ChannelLayout), " channels");
740 }
741 else
742 {
743 int32u numSpeakers;
744 escapedValue(numSpeakers, 5, 8, 16, "numSpeakers");
745 numSpeakers++;
746 Layout.numSpeakers=numSpeakers;
747
748 if (speakerLayoutType==1)
749 {
750 Layout.CICPspeakerIdxs.resize(numSpeakers);
751 for (size_t Pos=0; Pos<numSpeakers; Pos++)
752 {
753 int8u CICPspeakerIdx;
754 Get_S1(7, CICPspeakerIdx, "CICPspeakerIdx");
755 Layout.CICPspeakerIdxs[Pos]=(Aac_OutputChannel)CICPspeakerIdx;
756 }
757 }
758 else if (speakerLayoutType==2)
759 {
760 mpegh3daFlexibleSpeakerConfig(Layout);
761 }
762 }
763 Element_End0();
764
765 FILLING_BEGIN();
766 //Finish
767 if (Status[IsAccepted])
768 Finish("MPEG-H 3D Audio");
769 FILLING_END();
770 }
771
772 //---------------------------------------------------------------------------
mpegh3daFlexibleSpeakerConfig(speaker_layout & Layout)773 void File_Mpegh3da::mpegh3daFlexibleSpeakerConfig(speaker_layout& Layout)
774 {
775 bool angularPrecision;
776 Element_Begin1("mpegh3daFlexibleSpeakerConfig");
777 Get_SB(angularPrecision, "angularPrecision");
778 for (size_t Pos=0; Pos<Layout.numSpeakers; Pos++)
779 {
780 Layout.SpeakersInfo.push_back(speaker_info());
781 speaker_info& SpeakerInfo=Layout.SpeakersInfo[Layout.SpeakersInfo.size()-1];
782 mpegh3daSpeakerDescription(SpeakerInfo, angularPrecision);
783 if (SpeakerInfo.AzimuthAngle && SpeakerInfo.AzimuthAngle!=180)
784 {
785 bool alsoAddSymmetricPair;
786 Get_SB (alsoAddSymmetricPair, "alsoAddSymmetricPair");
787 if (alsoAddSymmetricPair)
788 Pos++;
789 }
790 }
791 Element_End0();
792 }
793
794 //---------------------------------------------------------------------------
mpegh3daSpeakerDescription(speaker_info & SpeakerInfo,bool angularPrecision)795 void File_Mpegh3da::mpegh3daSpeakerDescription(speaker_info& SpeakerInfo, bool angularPrecision)
796 {
797 Element_Begin1("mpegh3daSpeakerDescription");
798 TESTELSE_SB_SKIP( "isCICPspeakerIdx");
799 {
800 int8u CICPspeakerIdx;
801 Get_S1 (7, CICPspeakerIdx, "CICPspeakerIdx");
802 if (CICPspeakerIdx<Mpegh3da_SpeakerInfo_Size)
803 SpeakerInfo=Mpegh3da_SpeakerInfo[CICPspeakerIdx];
804 else
805 SpeakerInfo.CICPspeakerIdx=(Aac_OutputChannel)CICPspeakerIdx;
806 }
807 TESTELSE_SB_ELSE( "isCICPspeakerIdx");
808 int8u ElevationClass;
809 Get_S1(2, ElevationClass, "ElevationClass");
810
811 switch (ElevationClass)
812 {
813 case 0:
814 SpeakerInfo.ElevationAngle=0;
815 break;
816 case 1:
817 SpeakerInfo.ElevationAngle=35;
818 SpeakerInfo.ElevationDirection=false;
819 break;
820 case 2:
821 SpeakerInfo.ElevationAngle=15;
822 SpeakerInfo.ElevationDirection=true;
823 break;
824 case 3:
825 int8u ElevationAngleIdx;
826 Get_S1(angularPrecision?7:5, ElevationAngleIdx, "ElevationAngleIdx");
827 SpeakerInfo.ElevationAngle=ElevationAngleIdx*(angularPrecision?1:5);
828
829 if (SpeakerInfo.ElevationAngle)
830 Get_SB(SpeakerInfo.ElevationDirection, "ElevationDirection");
831 break;
832 }
833
834 int8u AzimuthAngleIdx;
835 Get_S1(angularPrecision?8:6, AzimuthAngleIdx, "AzimuthAngleIdx");
836 SpeakerInfo.AzimuthAngle=AzimuthAngleIdx*(angularPrecision?1:5);
837
838 if (SpeakerInfo.AzimuthAngle && SpeakerInfo.AzimuthAngle!=180)
839 Get_SB(SpeakerInfo.AzimuthDirection, "AzimuthDirection");
840
841 Get_SB(SpeakerInfo.isLFE, "isLFE");
842
843 SpeakerInfo.CICPspeakerIdx=(Aac_OutputChannel)-1;
844 TESTELSE_SB_END();
845 Element_End0();
846 }
847
848 //---------------------------------------------------------------------------
mpegh3daFrame()849 void File_Mpegh3da::mpegh3daFrame()
850 {
851 Skip_XX(Element_Size, "mpegh3daFrame");
852
853 FILLING_BEGIN();
854 //Filling
855 if (Status[IsAccepted])
856 Finish("MPEG-H 3D Audio");
857 FILLING_END();
858 }
859
860 //---------------------------------------------------------------------------
Sync()861 void File_Mpegh3da::Sync()
862 {
863 //Parsing
864 Skip_B1( "syncword");
865 }
866
867 //---------------------------------------------------------------------------
Marker()868 void File_Mpegh3da::Marker()
869 {
870 //Parsing
871 Info_B1(marker_byte, "marker_byte"); Param_Info1C(marker_byte<Mpegh3da_marker_byte_Size, Mpegh3da_marker_byte[marker_byte]);
872 }
873
874 //---------------------------------------------------------------------------
Crc16()875 void File_Mpegh3da::Crc16()
876 {
877 //Parsing
878 Skip_B2( "mhasParity16Data");
879 }
880
881 //---------------------------------------------------------------------------
BufferInfo()882 void File_Mpegh3da::BufferInfo()
883 {
884 //Parsing
885 BS_Begin();
886 bool mhas_buffer_fullness_present;
887 Get_SB (mhas_buffer_fullness_present, "mhas_buffer_fullness_present");
888 if (mhas_buffer_fullness_present)
889 {
890 int32u mhas_buffer_fullness;
891 escapedValue(mhas_buffer_fullness, 15, 39, 71, "mhas_buffer_fullness");
892 }
893 BS_End();
894 }
895
896 //---------------------------------------------------------------------------
FrameworkConfig3d()897 void File_Mpegh3da::FrameworkConfig3d()
898 {
899 numAudioChannels=0;
900 numAudioObjects=0;
901 numSAOCTransportChannels=0;
902 numHOATransportChannels=0;
903
904 Element_Begin1("FrameworkConfig3d");
905 Element_Begin1("Signals3d");
906 Get_S1(5, bsNumSignalGroups, "bsNumSignalGroups");
907 bsNumSignalGroups++; Param_Info2(bsNumSignalGroups, " signals");
908 SignalGroups.resize(bsNumSignalGroups);
909 for (int8u Pos=0; Pos<bsNumSignalGroups; Pos++)
910 {
911 signal_group& E=SignalGroups[Pos];
912 Element_Begin1("signalGroup");
913 Get_S1(3, E.Type, "signalGroupType");
914 escapedValue(E.bsNumberOfSignals, 5, 8, 16, "bsNumberOfSignals");
915 E.bsNumberOfSignals++;
916
917 if (E.Type==SignalGroupTypeChannels)
918 {
919 numAudioChannels+=E.bsNumberOfSignals;
920 TESTELSE_SB_SKIP( "differsFromReferenceLayout");
921 SpeakerConfig3d(E.Layout);
922 TESTELSE_SB_ELSE( "differsFromReferenceLayout");
923 E.Layout=referenceLayout;
924 TESTELSE_SB_END();
925 }
926 else if (E.Type==SignalGroupTypeObject)
927 {
928 numAudioObjects+=E.bsNumberOfSignals;
929 E.Layout.numSpeakers=E.bsNumberOfSignals;
930 }
931 else if (E.Type==SignalGroupTypeSAOC)
932 {
933 numSAOCTransportChannels+=E.bsNumberOfSignals;
934 TEST_SB_SKIP( "saocDmxLayoutPresent");
935 SpeakerConfig3d(E.Layout);
936 TEST_SB_END();
937 }
938 else if (E.Type==SignalGroupTypeHOA)
939 {
940 numHOATransportChannels+=E.bsNumberOfSignals;
941 E.Layout.numSpeakers=E.bsNumberOfSignals;
942 }
943 Element_End0();
944 }
945 Element_End0();
946 Element_End0();
947 }
948
949 //---------------------------------------------------------------------------
mpegh3daDecoderConfig()950 void File_Mpegh3da::mpegh3daDecoderConfig()
951 {
952 Elements.clear();
953
954 Element_Begin1("mpegh3daDecoderConfig");
955 escapedValue(numElements, 4, 8, 16, "numElements");
956 numElements++;
957
958 bool elementLengthPresent;
959 Get_SB (elementLengthPresent, "elementLengthPresent");
960
961 for (size_t Pos=0; Pos<numElements; Pos++)
962 {
963 Element_Begin1("Element");
964 int8u usacElementType;
965 Get_S1(2, usacElementType, "usacElementType"); Element_Info1(Mpegh3da_usacElementType[usacElementType]);
966 switch (usacElementType)
967 {
968 case ID_USAC_SCE:
969 mpegh3daSingleChannelElementConfig(coreSbrFrameLengthIndex_Mapping[coreSbrFrameLengthIndex].sbrRatioIndex);
970 Elements.push_back(usac_element(ID_USAC_SCE));
971 break;
972 case ID_USAC_CPE:
973 mpegh3daChannelPairElementConfig(coreSbrFrameLengthIndex_Mapping[coreSbrFrameLengthIndex].sbrRatioIndex);
974 Elements.push_back(usac_element(ID_USAC_CPE));
975 break;
976 case ID_USAC_LFE:
977 Elements.push_back(usac_element(ID_USAC_LFE));
978 break;
979 case ID_USAC_EXT:
980 mpegh3daExtElementConfig();
981 Elements.push_back(usac_element(ID_USAC_EXT));
982 break;
983 }
984 Element_End0();
985 }
986 Element_End0();
987 }
988
989 //---------------------------------------------------------------------------
mpegh3daSingleChannelElementConfig(int8u sbrRatioIndex)990 void File_Mpegh3da::mpegh3daSingleChannelElementConfig(int8u sbrRatioIndex)
991 {
992 Element_Begin1("mpegh3daSingleChannelElementConfig");
993 mpegh3daCoreConfig();
994 if (sbrRatioIndex)
995 SbrConfig();
996 Element_End0();
997 }
998
999 //---------------------------------------------------------------------------
mpegh3daChannelPairElementConfig(int8u sbrRatioIndex)1000 void File_Mpegh3da::mpegh3daChannelPairElementConfig(int8u sbrRatioIndex)
1001 {
1002 int32u nBits=floor(log2(numAudioChannels+numAudioObjects+numHOATransportChannels+numSAOCTransportChannels-1))+1;
1003 int8u stereoConfigIndex=0;
1004 int8u qceIndex;
1005 Element_Begin1("mpegh3daChannelPairElementConfig");
1006 bool enhancedNoiseFilling=mpegh3daCoreConfig();
1007 if(enhancedNoiseFilling)
1008 Skip_SB( "igfIndependentTiling");
1009
1010 if (sbrRatioIndex)
1011 {
1012 SbrConfig();
1013 Get_S1(2, stereoConfigIndex, "stereoConfigIndex");
1014 }
1015
1016 if (stereoConfigIndex) {
1017 Mps212Config(stereoConfigIndex);
1018 }
1019
1020 Get_S1(2, qceIndex, "qceIndex");
1021 if (qceIndex)
1022 {
1023 TEST_SB_SKIP( "shiftIndex0");
1024 Skip_BS(nBits, "shiftChannel0");
1025 TEST_SB_END();
1026 }
1027
1028 TEST_SB_SKIP( "shiftIndex1");
1029 Skip_BS(nBits, "shiftChannel1");
1030 TEST_SB_END();
1031
1032 if (sbrRatioIndex==0 && qceIndex==0)
1033 Skip_SB( "lpdStereoIndex");
1034 Element_End0();
1035 }
1036
1037 //---------------------------------------------------------------------------
mpegh3daExtElementConfig()1038 void File_Mpegh3da::mpegh3daExtElementConfig()
1039 {
1040 Element_Begin1("mpegh3daExtElementConfig");
1041 int32u usacExtElementType;
1042 escapedValue(usacExtElementType, 4, 8, 16, "usacExtElementType"); Element_Level--; Element_Info1C(usacExtElementType<Mpegh3da_usacExtElementType_Size, Mpegh3da_usacExtElementType[usacExtElementType]); Element_Level++;
1043
1044 int32u usacExtElementConfigLength;
1045 escapedValue(usacExtElementConfigLength, 4, 8, 16, "usacExtElementConfigLength");
1046
1047 int32u usacExtElementDefaultLength=0;
1048 TEST_SB_SKIP( "usacExtElementDefaultLengthPresent");
1049 escapedValue(usacExtElementDefaultLength, 8, 16, 0, "usacExtElementDefaultLength"); //TODO: check if call is valid
1050 usacExtElementDefaultLength++;
1051 TEST_SB_END();
1052
1053 Skip_SB( "usacExtElementPayloadFrag");
1054
1055 size_t Remain_Before=BS->Remain();
1056 switch (usacExtElementType)
1057 {
1058 case ID_EXT_ELE_FILL:
1059 break; // No configuration element
1060 //case ID_EXT_ELE_MPEGS:
1061 //TODO: SpatialSpecificConfig();
1062 //break;
1063 //case ID_EXT_ELE_SAOC:
1064 //TODO: SAOCSpecificConfig();
1065 //break;
1066 case ID_EXT_ELE_AUDIOPREROLL:
1067 break; // No configuration element
1068 case ID_EXT_ELE_UNI_DRC:
1069 //if (referenceLayout.ChannelLayout!=19) //TEMP
1070 mpegh3daUniDrcConfig();
1071 break;
1072 case ID_EXT_ELE_OBJ_METADATA:
1073 ObjectMetadataConfig();
1074 break;
1075 //case ID_EXT_ELE_SAOC_3D:
1076 // SAOC3DSpecificConfig();
1077 // break;
1078 //case ID_EXT_ELE_HOA:
1079 //HOAConfig();
1080 //break;
1081 case ID_EXT_ELE_FMT_CNVRTR:
1082 break; // No configuration element
1083 //case ID_EXT_ELE_MCT:
1084 //MCTConfig();
1085 //break;
1086 case ID_EXT_ELE_TCC:
1087 TccConfig();
1088 break;
1089 //case ID_EXT_ELE_HOA_ENH_LAYER:
1090 //HOAEnhConfig();
1091 //break;
1092 //case ID_EXT_ELE_HREP:
1093 //HREPConfig(current_signal_group);
1094 //break;
1095 //case ID_EXT_ELE_ENHANCED_OBJ_METADATA:
1096 //EnhancedObjectMetadataConfig();
1097 //break;
1098 break;
1099 default:
1100 if (usacExtElementConfigLength)
1101 Skip_BS(usacExtElementConfigLength*8, "reserved");
1102 break;
1103 }
1104 if (BS->Remain()+usacExtElementConfigLength*8>Remain_Before)
1105 {
1106 size_t Size=BS->Remain()+usacExtElementConfigLength*8-Remain_Before;
1107 int8u Padding=1;
1108 if (Size<8)
1109 Peek_S1((int8u)Size, Padding);
1110
1111 if (Padding && Remain_Before!=BS->Remain() && usacExtElementType!=ID_EXT_ELE_OBJ_METADATA)
1112 Fill(Stream_Audio, 0, "NOK", "NOK", Unlimited, true, true);
1113 Skip_BS(Size, Padding?"(Unknown)":"Padding");
1114 }
1115
1116 Element_End0();
1117 }
1118
1119 //---------------------------------------------------------------------------
mpegh3daCoreConfig()1120 bool File_Mpegh3da::mpegh3daCoreConfig()
1121 {
1122 bool enhancedNoiseFilling;
1123 Element_Begin1("mpegh3daCoreConfig");
1124 Skip_SB( "tw_mdct");
1125 Skip_SB( "fullbandLpd");
1126 Skip_SB( "noiseFilling");
1127 TEST_SB_GET(enhancedNoiseFilling, "enhancedNoiseFilling");
1128 Skip_SB( "igfUseEnf");
1129 Skip_SB( "igfUseHighRes");
1130 Skip_SB( "igfUseWhitening");
1131 Skip_SB( "igfAfterTnsSynth");
1132 Skip_S1(5, "igfStartIndex");
1133 Skip_S1(4, "igfStopIndex");
1134 TEST_SB_END();
1135 Element_End0();
1136
1137 return enhancedNoiseFilling;
1138 }
1139
1140 //---------------------------------------------------------------------------
mpegh3daUniDrcConfig()1141 void File_Mpegh3da::mpegh3daUniDrcConfig()
1142 {
1143 Element_Begin1("mpegh3daUniDrcConfig");
1144 int8u drcCoefficientsUniDrcCount;
1145 Get_S1(3, drcCoefficientsUniDrcCount, "drcCoefficientsUniDrcCount");
1146
1147 int8u drcInstructionsUniDrcCount;
1148 Get_S1(6, drcInstructionsUniDrcCount, "drcInstructionsUniDrcCount");
1149
1150 Element_Begin1("mpegh3daUniDrcChannelLayout");
1151 Get_S1 (7, baseChannelCount, "baseChannelCount");
1152 Element_End0();
1153 if (!drcCoefficientsUniDrcCount)
1154 Fill(Stream_Audio, 0, "TEMP_drcCoefficientsUniDrcCount", drcCoefficientsUniDrcCount); //TEMP
1155
1156 for (int8u Pos=0; Pos<drcCoefficientsUniDrcCount; Pos++)
1157 drcCoefficientsUniDrc(); // in File_USAC.cpp
1158
1159 for (int8u Pos=0; Pos<drcInstructionsUniDrcCount; Pos++)
1160 {
1161 int8u drcInstructionsType;
1162 Get_S1(Peek_SB()?2:1, drcInstructionsType, "drcInstructionsType");
1163
1164 int8u ID;
1165 if (drcInstructionsType==2)
1166 Get_S1 (7, ID, "mae_groupID");
1167 else if (drcInstructionsType==3)
1168 Get_S1 (5, ID, "mae_groupPresetID");
1169 else
1170 ID=0;
1171
1172 drcInstructionsUniDrc(false, true); // in File_USAC.cpp
1173 Mpegh3da_drcInstructionsUniDrc_Data[drcInstructionsType][ID][drcInstructionsUniDrc_Data.begin()->first]=drcInstructionsUniDrc_Data.begin()->second;
1174 drcInstructionsUniDrc_Data.clear();
1175 }
1176
1177 TEST_SB_SKIP( "uniDrcConfigExtPresent");
1178 uniDrcConfigExtension(); // in File_USAC.cpp
1179 TEST_SB_END();
1180
1181 TEST_SB_SKIP( "loudnessInfoSetPresent");
1182 mpegh3daLoudnessInfoSet();
1183 TEST_SB_END();
1184 Element_End0();
1185 }
1186
1187 //---------------------------------------------------------------------------
downmixConfig()1188 void File_Mpegh3da::downmixConfig()
1189 {
1190 Element_Begin1("downmixConfig");
1191 int8u downmixConfigType;
1192 Get_S1 (2, downmixConfigType, "downmixConfigType");
1193 switch (downmixConfigType)
1194 {
1195 case 0:
1196 case 2:
1197 {
1198 bool passiveDownmixFlag;
1199 Get_SB (passiveDownmixFlag, "passiveDownmixFlag");
1200 if (!passiveDownmixFlag)
1201 Skip_S1(3, "phaseAlignStrength");
1202 Skip_SB( "immersiveDownmixFlag");
1203 }
1204 break;
1205 }
1206 switch (downmixConfigType)
1207 {
1208 case 1:
1209 case 2:
1210 {
1211 Skip_S1(5, "DownmixMatrixSet - TODO");
1212 }
1213 break;
1214 }
1215 Element_End0();
1216 }
1217
1218 //---------------------------------------------------------------------------
mpegh3daLoudnessInfoSet()1219 void File_Mpegh3da::mpegh3daLoudnessInfoSet()
1220 {
1221 Element_Begin1("mpegh3daLoudnessInfoSet");
1222 int8u loudnessInfoCount;
1223 Get_S1(6, loudnessInfoCount, "loudnessInfoCount");
1224 for(int8u Pos=0; Pos<loudnessInfoCount; Pos++)
1225 {
1226 int8u loudnessInfoType;
1227 Get_S1(2, loudnessInfoType, "loudnessInfoType");
1228
1229 int8u ID;
1230 if (loudnessInfoType==1 || loudnessInfoType==2)
1231 Get_S1 (7, ID, "mae_groupID");
1232 else if (loudnessInfoType==3)
1233 Get_S1 (5, ID, "mae_groupPresetID");
1234 else
1235 ID=0;
1236
1237 bool IsNOK=loudnessInfo(false); // in File_USAC.cpp
1238 Mpegh3da_loudnessInfo_Data[loudnessInfoType][ID].Data[0][loudnessInfo_Data[0].begin()->first]=loudnessInfo_Data[0].begin()->second;
1239 loudnessInfo_Data[0].clear();
1240 if (IsNOK)
1241 {
1242 Element_End0();
1243 return;
1244 }
1245 }
1246
1247 TEST_SB_SKIP( "loudnessInfoAlbumPresent");
1248 int8u loudnessInfoAlbumCount;
1249 Get_S1(6, loudnessInfoAlbumCount, "loudnessInfoAlbumCount");
1250 for (int8u Pos=0; Pos<loudnessInfoAlbumCount; Pos++)
1251 {
1252 loudnessInfo(true); // in File_USAC.cpp
1253 Mpegh3da_loudnessInfo_Data[0][0].Data[1][loudnessInfo_Data[1].begin()->first]=loudnessInfo_Data[1].begin()->second;
1254 loudnessInfo_Data[1].clear();
1255 }
1256 TEST_SB_END();
1257
1258 TEST_SB_SKIP( "loudnessInfoSetExtensionPresent");
1259 loudnessInfoSetExtension(); // in File_USAC.cpp
1260 TEST_SB_END();
1261 Element_End0();
1262 }
1263
1264 //---------------------------------------------------------------------------
ObjectMetadataConfig()1265 void File_Mpegh3da::ObjectMetadataConfig()
1266 {
1267 Element_Begin1("ObjectMetadataConfig");
1268 Skip_SB( "lowDelayMetadataCoding");
1269 TESTELSE_SB_SKIP( "hasCoreLength");
1270 TESTELSE_SB_ELSE( "hasCoreLength");
1271 Skip_S1(6, "frameLength");
1272 TESTELSE_SB_END();
1273
1274 TEST_SB_SKIP("hasScreenRelativeObjects");
1275 size_t num_objects=num_objects_Get();
1276 for (int16u Pos=0; Pos<num_objects; Pos++)
1277 {
1278 Skip_SB( "isScreenRelativeObject");
1279 }
1280 TEST_SB_END();
1281 Skip_SB( "hasDynamicObjectPriority");
1282 Skip_SB( "hasUniformSpread");
1283 Element_End0();
1284 }
1285
1286 //---------------------------------------------------------------------------
SAOC3DSpecificConfig()1287 void File_Mpegh3da::SAOC3DSpecificConfig()
1288 {
1289 int8u bsSamplingFrequencyIndex, bsNumSaocDmxChannels, bsNumSaocDmxObjects, bsNumSaocObjects;
1290 int32u NumSaocChannels=0, NumInputSignals=0;
1291 Element_Begin1("SAOC3DSpecificConfig");
1292 Get_S1(4, bsSamplingFrequencyIndex, "bsSamplingFrequencyIndex");
1293 if (bsSamplingFrequencyIndex==15)
1294 Skip_S3(24, "bsSamplingFrequency");
1295
1296 Skip_S1(3, "bsFreqRes");
1297 Skip_SB( "bsDoubleFrameLengthFlag");
1298 Get_S1(5, bsNumSaocDmxChannels, "bsNumSaocDmxChannels");
1299 Get_S1(5, bsNumSaocDmxObjects, "bsNumSaocDmxObjects");
1300 Skip_SB( "bsDecorrelationMethod");
1301
1302 if (bsNumSaocDmxChannels)
1303 {
1304 speaker_layout saocChannelLayout;
1305 SpeakerConfig3d(saocChannelLayout);
1306 NumSaocChannels=SAOC3DgetNumChannels(saocChannelLayout);
1307 NumInputSignals+=NumSaocChannels;
1308 }
1309
1310 Get_S1(8, bsNumSaocObjects , "bsNumSaocObjects");
1311 NumInputSignals+=bsNumSaocObjects;
1312
1313 for (int8u Pos=0; Pos<NumSaocChannels; Pos++)
1314 {
1315 for(int8u Pos2=Pos+1; Pos2<NumSaocChannels; Pos2++)
1316 Skip_SB( "bsRelatedTo");
1317 }
1318
1319 for (int8u Pos=NumSaocChannels; Pos<NumInputSignals; Pos++)
1320 {
1321 for(int8u Pos2=Pos+1; Pos2<NumInputSignals; Pos2++)
1322 Skip_SB( "bsRelatedTo");
1323 }
1324
1325 Skip_SB( "bsOneIOC");
1326 TEST_SB_SKIP( "bsSaocDmxMethod");
1327 SAOC3DgetNumChannels(referenceLayout);
1328 TEST_SB_END();
1329
1330 TEST_SB_SKIP( "bsDualMode");
1331 Skip_S1(5, "bsBandsLow");
1332 TEST_SB_END();
1333
1334 TEST_SB_SKIP( "bsDcuFlag");
1335 Skip_SB( "bsDcuMandatory");
1336 TEST_SB_SKIP( "bsDcuDynamic");
1337 Skip_SB( "bsDcuMode");
1338 Skip_S1(4, "bsDcuParam");
1339 TEST_SB_END();
1340 TEST_SB_END();
1341 Skip_S1(BS->Remain()%8, "byte_align");
1342 //TODO: SAOC3DExtensionConfig();
1343 Element_End0();
1344 }
1345
1346 //---------------------------------------------------------------------------
SAOC3DgetNumChannels(speaker_layout Layout)1347 int32u File_Mpegh3da::SAOC3DgetNumChannels(speaker_layout Layout)
1348 {
1349 int32u ToReturn=Layout.numSpeakers;
1350
1351 for (int32u Pos=0; Pos<Layout.numSpeakers; Pos++)
1352 {
1353 if (Layout.SpeakersInfo.size()>Pos && Layout.SpeakersInfo[Pos].isLFE)
1354 ToReturn--;
1355 }
1356
1357 return ToReturn;
1358 }
1359
1360 //---------------------------------------------------------------------------
MCTConfig()1361 void File_Mpegh3da::MCTConfig()
1362 {
1363 Element_Begin1("MCTConfig");
1364 for(int32u chan=0; chan<numAudioChannels; ++chan) // bsNumberOfSignals[grp] but which grp?
1365 {
1366 Skip_SB( "mctChanMask");
1367 }
1368 Element_End0();
1369 }
1370
1371 //---------------------------------------------------------------------------
TccConfig()1372 void File_Mpegh3da::TccConfig()
1373 {
1374 Element_Begin1("TccConfig");
1375 for(int32u Pos=0; Pos<numElements; Pos++)
1376 {
1377 if(Elements.size()>Pos && (Elements[Pos].Type==ID_USAC_SCE || Elements[Pos].Type==ID_USAC_CPE))
1378 Skip_S1(2, "tccMode");
1379 }
1380 Element_End0();
1381 }
1382
1383 //---------------------------------------------------------------------------
EnhancedObjectMetadataConfig()1384 void File_Mpegh3da::EnhancedObjectMetadataConfig()
1385 {
1386 Element_Begin1("EnhancedObjectMetadataConfig");
1387 bool hasCommonGroupExcludedSectors=false;
1388 TEST_SB_SKIP( "hasDiffuseness");
1389 Skip_SB( "hasCommonGroupDiffuseness");
1390 TEST_SB_END();
1391
1392 TEST_SB_SKIP( "hasExcludedSectors");
1393 TEST_SB_GET(hasCommonGroupExcludedSectors, "hasCommonGroupExcludedSectors");
1394 Skip_SB( "useOnlyPredefinedSectors");
1395 TEST_SB_END();
1396 TEST_SB_END();
1397
1398 TEST_SB_SKIP( "hasClosestSpeakerCondition");
1399 Skip_S1(7, "closestSpeakerThresholdAngle");
1400 TEST_SB_END();
1401
1402 size_t num_objects=num_objects_Get();
1403 for (int8u Pos=0; Pos<num_objects; Pos++)
1404 {
1405 TEST_SB_SKIP( "hasDivergence");
1406 Skip_S1(6, "divergenceAzimuthRange");
1407 TEST_SB_END();
1408
1409 if (!hasCommonGroupExcludedSectors)
1410 Skip_SB( "useOnlyPredefinedSectors");
1411 }
1412 Element_End0();
1413 }
1414
1415 //---------------------------------------------------------------------------
mpegh3daConfigExtension()1416 void File_Mpegh3da::mpegh3daConfigExtension()
1417 {
1418 Element_Begin1("mpegh3daConfigExtension");
1419 int32u numConfigExtensions;
1420 escapedValue(numConfigExtensions, 2, 4, 8, "numConfigExtensions");
1421 numConfigExtensions++;
1422
1423 for (int32u Pos=0; Pos<numConfigExtensions; Pos++)
1424 {
1425 Element_Begin1("configExtension");
1426 int32u usacConfigExtType;
1427 escapedValue(usacConfigExtType, 4, 8, 16, "usacConfigExtType"); Element_Info1C(usacConfigExtType<Mpegh3da_usacConfigExtType_Size, Mpegh3da_usacConfigExtType[usacConfigExtType]);
1428
1429 int32u usacConfigExtLength;
1430 escapedValue(usacConfigExtLength, 4, 8, 16, "usacConfigExtLength");
1431 if (!usacConfigExtLength)
1432 {
1433 Element_End0();
1434 continue;
1435 }
1436
1437 size_t Remain_Before=BS->Remain();
1438 switch ((UsacConfigExtType)usacConfigExtType)
1439 {
1440 case ID_CONFIG_EXT_FILL:
1441 while (usacConfigExtLength)
1442 {
1443 usacConfigExtLength--;
1444 Skip_S1(8, "fill_byte"); // should be '10100101'
1445 }
1446 break;
1447 case ID_CONFIG_EXT_DOWNMIX:
1448 downmixConfig();
1449 break;
1450 case ID_CONFIG_EXT_LOUDNESS_INFO:
1451 mpegh3daLoudnessInfoSet();
1452 break;
1453 case ID_CONFIG_EXT_AUDIOSCENE_INFO:
1454 mae_AudioSceneInfo();
1455 break;
1456 //case ID_CONFIG_EXT_HOA_MATRIX:
1457 // HoaRenderingMatrixSet();
1458 // break;
1459 case ID_CONFIG_EXT_ICG:
1460 ICGConfig();
1461 break;
1462 case ID_CONFIG_EXT_SIG_GROUP_INFO:
1463 SignalGroupInformation();
1464 break;
1465 case ID_CONFIG_EXT_COMPATIBLE_PROFILE_LEVEL_SET:
1466 CompatibleProfileLevelSet();
1467 break;
1468 default:
1469 Skip_BS(usacConfigExtLength*8, "reserved");
1470 }
1471 if (BS->Remain()+usacConfigExtLength*8>Remain_Before)
1472 {
1473 size_t Size=BS->Remain()+usacConfigExtLength*8-Remain_Before;
1474 int8u Padding=1;
1475 if (Size<8)
1476 Peek_S1((int8u)Size, Padding);
1477
1478 if (Padding && Remain_Before!=BS->Remain() && usacConfigExtType!=ID_CONFIG_EXT_DOWNMIX && usacConfigExtType!=ID_CONFIG_EXT_HOA_MATRIX)
1479 Fill(Stream_Audio, 0, "NOK", "NOK", Unlimited, true, true);
1480 Skip_BS(Size, Padding?"(Unknown)":"Padding");
1481 }
1482 Element_End0();
1483 }
1484 Element_End0();
1485 }
1486
1487 //---------------------------------------------------------------------------
SignalGroupInformation()1488 void File_Mpegh3da::SignalGroupInformation()
1489 {
1490 Element_Begin1("SignalGroupInformation");
1491 for (int8u Pos=0; Pos<bsNumSignalGroups+1; Pos++)
1492 {
1493 Skip_S1(3, "groupPriority");
1494 Skip_SB( "fixedPosition");
1495 }
1496 Element_End0();
1497 }
1498
1499 //---------------------------------------------------------------------------
CompatibleProfileLevelSet()1500 void File_Mpegh3da::CompatibleProfileLevelSet()
1501 {
1502 Element_Begin1("CompatibleProfileLevelSet");
1503 int8u bsNumCompatibleSets;
1504 Get_S1 (4, bsNumCompatibleSets, "bsNumCompatibleSets");
1505 Skip_S1(4, "reserved");
1506 mpegh3daCompatibleProfileLevelSet.resize(bsNumCompatibleSets+1);
1507 for (int8u Pos=0; Pos<=bsNumCompatibleSets; Pos++)
1508 {
1509 Get_S1(8, mpegh3daCompatibleProfileLevelSet[Pos], "CompatibleSetIndication"); Param_Info1(Mpegh3da_Profile_Get(mpegh3daCompatibleProfileLevelSet[Pos]));
1510 }
1511 Element_End0();
1512 }
1513
1514 //---------------------------------------------------------------------------
HoaRenderingMatrixSet()1515 void File_Mpegh3da::HoaRenderingMatrixSet()
1516 {
1517 Element_Begin1("HoaRenderingMatrixSet - TODO");
1518 Skip_S1(5, "numOfHoaRenderingMatrices");
1519 Element_End0();
1520 }
1521
1522 //---------------------------------------------------------------------------
ICGConfig()1523 void File_Mpegh3da::ICGConfig()
1524 {
1525 Element_Begin1("ICGConfig");
1526 TEST_SB_SKIP( "ICPresent");
1527 for (int32u Pos=0; Pos<numElements; Pos++)
1528 {
1529 if (Elements.size()>Pos && Elements[Pos].Type==ID_USAC_CPE)
1530 Skip_SB( "ICinCPE");
1531 }
1532
1533 TEST_SB_SKIP( "ICGPreAppliedPresent");
1534 for (int32u Pos=0; Pos<numElements; Pos++)
1535 {
1536 if (Elements.size()>Pos && Elements[Pos].Type==ID_USAC_CPE)
1537 Skip_SB( "ICGPreAppliedCPE");
1538 }
1539 TEST_SB_END();
1540 TEST_SB_END();
1541 Element_End0();
1542 }
1543
1544 //---------------------------------------------------------------------------
mae_AudioSceneInfo()1545 void File_Mpegh3da::mae_AudioSceneInfo()
1546 {
1547 Groups.clear();
1548 SwitchGroups.clear();
1549 GroupPresets.clear();
1550
1551 Element_Begin1("mae_AudioSceneInfo");
1552 bool mae_isMainStream;
1553 TESTELSE_SB_GET (mae_isMainStream, "mae_isMainStream");
1554 TEST_SB_SKIP( "mae_audioSceneInfoIDPresent");
1555 Get_S1 (8, audioSceneInfoID, "mae_audioSceneInfoID");
1556 TEST_SB_END();
1557 int8u mae_numGroups;
1558 Get_S1(7, mae_numGroups, "mae_numGroups");
1559 mae_GroupDefinition(mae_numGroups);
1560 int8u mae_numSwitchGroups;
1561 Get_S1(5, mae_numSwitchGroups, "mae_numSwitchGroups");
1562 mae_SwitchGroupDefinition(mae_numSwitchGroups);
1563 int8u mae_numGroupPresets;
1564 Get_S1(5, mae_numGroupPresets, "mae_numGroupPresets");
1565 mae_GroupPresetDefinition(mae_numGroupPresets);
1566 mae_Data(mae_numGroups, mae_numGroupPresets);
1567 Skip_S1(7, "mae_metaDataElementIDmaxAvail");
1568 TESTELSE_SB_ELSE( "mae_isMainStream");
1569 Skip_S1(7, "mae_bsMetaDataElementIDoffset");
1570 Skip_S1(7, "mae_metaDataElementIDmaxAvail");
1571 TESTELSE_SB_END();
1572 Element_End0();
1573
1574 isMainStream=mae_isMainStream;
1575 }
1576
1577 //---------------------------------------------------------------------------
mae_GroupDefinition(int8u numGroups)1578 void File_Mpegh3da::mae_GroupDefinition(int8u numGroups)
1579 {
1580 Element_Begin1("mae_GroupDefinition");
1581 Groups.resize(numGroups);
1582 for (int8u Pos=0; Pos<numGroups; Pos++)
1583 {
1584 Element_Begin1("mae_group");
1585 group& G=Groups[Pos];
1586 Get_S1 (7, G.ID, "mae_groupID");
1587 Element_Info1(Ztring::ToZtring(G.ID));
1588 Get_SB (G.allowOnOff, "mae_allowOnOff");
1589 Get_SB (G.defaultOnOff, "mae_defaultOnOff");
1590
1591 TEST_SB_SKIP( "mae_allowPositionInteractivity");
1592 Skip_S1(7, "mae_interactivityMinAzOffset");
1593 Skip_S1(7, "mae_interactivityMaxAzOffset");
1594 Skip_S1(5, "mae_interactivityMinElOffset");
1595 Skip_S1(5, "mae_interactivityMaxElOffset");
1596 Skip_S1(4, "mae_interactivityMinDistFactor");
1597 Skip_S1(4, "mae_interactivityMaxDistFactor");
1598 TEST_SB_END();
1599
1600 TEST_SB_SKIP( "mae_allowGainInteractivity");
1601 Skip_S1(6, "mae_interactivityMinGain");
1602 Skip_S1(5, "mae_interactivityMaxGain");
1603 TEST_SB_END();
1604
1605 int8u mae_bsGroupNumMembers;
1606 Get_S1(7, mae_bsGroupNumMembers, "mae_bsGroupNumMembers");
1607 mae_bsGroupNumMembers++;
1608 G.MemberID.resize(mae_bsGroupNumMembers);
1609 TESTELSE_SB_SKIP( "mae_hasConjunctMembers");
1610 int8u mae_startID;
1611 Get_S1 (7, mae_startID, "mae_startID");
1612 for (int8u Pos2=0; Pos2<mae_bsGroupNumMembers; Pos2++)
1613 G.MemberID[Pos2]=mae_startID++;
1614 TESTELSE_SB_ELSE( "mae_hasConjunctMembers");
1615 for (int8u Pos2=0; Pos2<mae_bsGroupNumMembers; Pos2++)
1616 Get_S1 (7, G.MemberID[Pos2], "mae_metaDataElementID");
1617 TESTELSE_SB_END();
1618 Element_End0();
1619 }
1620 Element_End0();
1621 }
1622
1623 //---------------------------------------------------------------------------
mae_SwitchGroupDefinition(int8u numSwitchGroups)1624 void File_Mpegh3da::mae_SwitchGroupDefinition(int8u numSwitchGroups)
1625 {
1626 Element_Begin1("mae_SwitchGroupDefinition");
1627 SwitchGroups.resize(numSwitchGroups);
1628 for(int8u Pos=0; Pos<numSwitchGroups; Pos++)
1629 {
1630 Element_Begin1("mae_switchGroup");
1631 switch_group& S=SwitchGroups[Pos];
1632 Get_S1 (5, S.ID, "mae_switchGroupID");
1633 Element_Info1(Ztring::ToZtring(S.ID));
1634
1635 TESTELSE_SB_GET(S.allowOnOff, "mae_switchGroupAllowOnOff");
1636 Get_SB (S.defaultOnOff, "mae_switchGroupDefaultOnOff");
1637 TESTELSE_SB_ELSE( "mae_switchGroupAllowOnOff");
1638 S.defaultOnOff=false;
1639 TESTELSE_SB_END();
1640
1641 int8u mae_bsSwitchGroupNumMembers;
1642 Get_S1(5, mae_bsSwitchGroupNumMembers, "mae_bsSwitchGroupNumMembers");
1643 mae_bsSwitchGroupNumMembers++;
1644 S.MemberID.resize(mae_bsSwitchGroupNumMembers);
1645 for (int8u Pos2=0; Pos2<mae_bsSwitchGroupNumMembers; Pos2++)
1646 Get_S1 (7, S.MemberID[Pos2], "mae_switchGroupMemberID");
1647
1648 Get_S1 (7, S.DefaultGroupID, "mae_switchGroupDefaultGroupID");
1649 Element_End0();
1650 }
1651 Element_End0();
1652 }
1653
1654 //---------------------------------------------------------------------------
mae_GroupPresetDefinition(int8u numGroupPresets)1655 void File_Mpegh3da::mae_GroupPresetDefinition(int8u numGroupPresets)
1656 {
1657 Element_Begin1("mae_GroupPresetDefinition");
1658 GroupPresets.resize(numGroupPresets);
1659 for (int8u Pos=0; Pos<numGroupPresets; Pos++)
1660 {
1661 Element_Begin1("mae_groupPreset");
1662 group_preset& P=GroupPresets[Pos];
1663 Get_S1 (5, P.ID, "mae_groupPresetID");
1664 Element_Info1(Ztring::ToZtring(P.ID));
1665 Get_S1 (5, P.Kind, "mae_groupPresetKind");
1666
1667 int8u mae_bsGroupPresetNumConditions;
1668 Get_S1 (4, mae_bsGroupPresetNumConditions, "mae_bsGroupPresetNumConditions");
1669 mae_bsGroupPresetNumConditions++;
1670 P.Conditions.resize(mae_bsGroupPresetNumConditions);
1671 for (int8u Pos2=0; Pos2<mae_bsGroupPresetNumConditions; Pos2++)
1672 {
1673 Element_Begin1("mae_groupPreset");
1674 Get_S1 (7, P.Conditions[Pos2].ReferenceID, "mae_groupPresetReferenceID");
1675 Element_Info1(P.Conditions[Pos2].ReferenceID);
1676 TEST_SB_GET (P.Conditions[Pos2].ConditionOnOff, "mae_groupPresetConditionOnOff");
1677 Skip_SB( "mae_groupPresetDisableGainInteractivity");
1678 TEST_SB_SKIP( "mae_groupPresetGainFlag");
1679 Skip_S1(8, "mae_groupPresetGain");
1680 TEST_SB_END();
1681 Skip_SB( "mae_groupPresetDisablePositionInteractivity");
1682 TEST_SB_SKIP( "mae_groupPresetPositionFlag");
1683 Skip_S1(8, "mae_groupPresetAzOffset");
1684 Skip_S1(6, "mae_groupPresetElOffset");
1685 Skip_S1(4, "mae_groupPresetDistFactor");
1686 TEST_SB_END();
1687 TEST_SB_END();
1688 Element_End0();
1689 }
1690 Element_End0();
1691 }
1692 Element_End0();
1693 }
1694
1695 //---------------------------------------------------------------------------
mae_Data(int8u numGroups,int8u numGroupPresets)1696 void File_Mpegh3da::mae_Data(int8u numGroups, int8u numGroupPresets)
1697 {
1698 Element_Begin1("mae_Data");
1699 int8u mae_numDataSets;
1700 Get_S1(4, mae_numDataSets, "mae_numDataSets");
1701 for (int8u Pos=0; Pos<mae_numDataSets; Pos++)
1702 {
1703 Element_Begin1("mae_data");
1704 int8u mae_dataType;
1705 Get_S1(4, mae_dataType, "mae_dataType");
1706 int16u mae_dataLength;
1707 Get_S2(16, mae_dataLength, "mae_dataLength");
1708
1709 size_t Remain_Before=BS->Remain();
1710 switch ((MaeDataType)mae_dataType)
1711 {
1712 case ID_MAE_GROUP_DESCRIPTION:
1713 case ID_MAE_SWITCHGROUP_DESCRIPTION:
1714 case ID_MAE_GROUP_PRESET_DESCRIPTION:
1715 mae_Description((MaeDataType)mae_dataType);
1716 break;
1717 case ID_MAE_GROUP_CONTENT:
1718 mae_ContentData();
1719 break;
1720 case ID_MAE_GROUP_COMPOSITE:
1721 mae_CompositePair();
1722 break;
1723 case ID_MAE_SCREEN_SIZE:
1724 mae_ProductionScreenSizeData();
1725 break;
1726 case ID_MAE_DRC_UI_INFO:
1727 mae_DrcUserInterfaceInfo(mae_dataLength);
1728 break;
1729 case ID_MAE_SCREEN_SIZE_EXTENSION:
1730 mae_ProductionScreenSizeDataExtension();
1731 break;
1732 case ID_MAE_GROUP_PRESET_EXTENSION:
1733 mae_GroupPresetDefinitionExtension(numGroupPresets);
1734 break;
1735 case ID_MAE_LOUDNESS_COMPENSATION:
1736 mae_LoudnessCompensationData(numGroups, numGroupPresets);
1737 break;
1738 default:
1739 Skip_BS(mae_dataLength*8, "reserved");
1740 }
1741 if (BS->Remain()+mae_dataLength*8>Remain_Before)
1742 {
1743 size_t Size=BS->Remain()+mae_dataLength*8-Remain_Before;
1744 int8u Padding=1;
1745 if (Size<8)
1746 Peek_S1((int8u)Size, Padding);
1747
1748 if (Padding)
1749 Fill(Stream_Audio, 0, "NOK", "NOK", Unlimited, true, true);
1750 Skip_BS(Size, Padding?"(Unknown)":"Padding");
1751 }
1752 Element_End0();
1753 }
1754 Element_End0();
1755 }
1756
1757 //---------------------------------------------------------------------------
mae_Description(MaeDataType type)1758 void File_Mpegh3da::mae_Description(MaeDataType type)
1759 {
1760 Element_Info1("mae_Description");
1761 Element_Begin1("mae_Description");
1762 int8u mae_bsNumDescriptionBlocks;
1763 Get_S1(7, mae_bsNumDescriptionBlocks, "mae_bsNumDescriptionBlocks");
1764 mae_bsNumDescriptionBlocks++;
1765 for (int8u Pos=0; Pos<mae_bsNumDescriptionBlocks; Pos++)
1766 {
1767 Element_Begin1("mae_descriptionGroup");
1768 int8u ID;
1769 switch (type)
1770 {
1771 case ID_MAE_GROUP_DESCRIPTION:
1772 Get_S1 (7, ID, "mae_descriptionGroupID");
1773 break;
1774 case ID_MAE_SWITCHGROUP_DESCRIPTION:
1775 Get_S1 (5, ID, "mae_descriptionSwitchGroupID");
1776 break;
1777 case ID_MAE_GROUP_PRESET_DESCRIPTION:
1778 Get_S1 (5, ID, "mae_descriptionGroupPresetID");
1779 break;
1780 default:;
1781 }
1782 Element_Info1(ID);
1783
1784 int8u mae_bsNumDescLanguages;
1785 Get_S1(4, mae_bsNumDescLanguages, "mae_bsNumDescLanguages");
1786 mae_bsNumDescLanguages++;
1787 for (int8u Pos2=0; Pos2<mae_bsNumDescLanguages; Pos2++)
1788 {
1789 Element_Begin1("mae_bsDescription");
1790 int32u mae_bsDescriptionLanguage;
1791 Get_S3 (24, mae_bsDescriptionLanguage, "mae_bsDescriptionLanguage");
1792 string Language;
1793 for (int i=16; i>=0; i-=8)
1794 {
1795 char LanguageChar=char(mae_bsDescriptionLanguage>>i);
1796 if (LanguageChar)
1797 Language+=LanguageChar;
1798 }
1799 Param_Info1(Language);
1800 Element_Info1(Language);
1801
1802 int8u mae_bsDescriptionDataLength;
1803 Get_S1(8, mae_bsDescriptionDataLength, "mae_bsDescriptionDataLength");
1804 mae_bsDescriptionDataLength++;
1805 string Description;
1806 Description.reserve(mae_bsDescriptionDataLength);
1807 for (int8u Pos3=0; Pos3<mae_bsDescriptionDataLength; Pos3++)
1808 {
1809 int8u mae_descriptionData;
1810 Get_S1 (8, mae_descriptionData, "mae_descriptionData");
1811 Description+=(char)mae_descriptionData;
1812 }
1813 Param_Info1(Ztring().From_UTF8(Description));
1814 Element_Info1(Ztring().From_UTF8(Description));
1815 switch (type)
1816 {
1817 case ID_MAE_GROUP_DESCRIPTION:
1818 for (size_t i=0; i<Groups.size(); i++)
1819 if (Groups[i].ID==ID)
1820 Groups[i].Description[Language]=Description;
1821 break;
1822 case ID_MAE_SWITCHGROUP_DESCRIPTION:
1823 for (size_t i=0; i<SwitchGroups.size(); i++)
1824 if (SwitchGroups[i].ID==ID)
1825 SwitchGroups[i].Description[Language]=Description;
1826 break;
1827 case ID_MAE_GROUP_PRESET_DESCRIPTION:
1828 for (size_t i=0; i<GroupPresets.size(); i++)
1829 if (GroupPresets[i].ID==ID)
1830 GroupPresets[i].Description[Language]=Description;
1831 break;
1832 default: ;
1833 }
1834 Element_End0();
1835 }
1836 Element_End0();
1837 }
1838 Element_End0();
1839 }
1840
1841 //---------------------------------------------------------------------------
mae_ContentData()1842 void File_Mpegh3da::mae_ContentData()
1843 {
1844 Element_Info1("mae_ContentData");
1845 Element_Begin1("mae_ContentData");
1846 int8u mae_bsNumContentDataBlocks;
1847 Get_S1(7, mae_bsNumContentDataBlocks, "mae_bsNumContentDataBlocks");
1848 for (int8u Pos=0; Pos<mae_bsNumContentDataBlocks+1; Pos++)
1849 {
1850 Element_Begin1("mae_ContentDataGroup");
1851 int8u ID, Kind;
1852 Get_S1 (7, ID, "mae_ContentDataGroupID");
1853 Element_Info1(ID);
1854 Get_S1 (4, Kind, "mae_contentKind");
1855 Param_Info1C(Kind<Mpegh3da_contentKind_Size, Mpegh3da_contentKind[Kind]);
1856 Element_Info1C(Kind<Mpegh3da_contentKind_Size, Mpegh3da_contentKind[Kind]);
1857 string Language;
1858 TEST_SB_SKIP( "mae_hasContentLanguage");
1859 int32u mae_contentLanguage;
1860 Get_S3 (24, mae_contentLanguage, "mae_contentLanguage");
1861 for (int i=16; i>=0; i-=8)
1862 {
1863 char LanguageChar=char(mae_contentLanguage>>i);
1864 if (LanguageChar)
1865 Language+=LanguageChar;
1866 }
1867 Param_Info1(Language);
1868 Element_Info1(Language);
1869 TEST_SB_END();
1870
1871 for (size_t i=0; i<Groups.size(); i++)
1872 if (Groups[i].ID==ID)
1873 {
1874 Groups[i].Language=Language;
1875 Groups[i].Kind=Kind;
1876 }
1877 Element_End0();
1878 }
1879 Element_End0();
1880 }
1881
1882 //---------------------------------------------------------------------------
mae_CompositePair()1883 void File_Mpegh3da::mae_CompositePair()
1884 {
1885 Element_Begin1("mae_CompositePair");
1886 int8u mae_bsNumCompositePairs;
1887 Get_S1(7, mae_bsNumCompositePairs, "mae_bsNumCompositePairs");
1888 for (int8u Pos=0; Pos<mae_bsNumCompositePairs+1; Pos++)
1889 {
1890 Skip_S1(7, "mae_CompositeElementID0");
1891 Skip_S1(7, "mae_CompositeElementID1");
1892 }
1893 Element_End0();
1894 }
1895
1896 //---------------------------------------------------------------------------
mae_ProductionScreenSizeData()1897 void File_Mpegh3da::mae_ProductionScreenSizeData()
1898 {
1899 Element_Begin1("mae_ProductionScreenSizeData");
1900 TEST_SB_SKIP( "hasNonStandardScreenSize");
1901 Skip_S2(9, "bsScreenSizeAz");
1902 Skip_S2(9, "bsScreenSizeTopEl");
1903 Skip_S2(9, "bsScreenSizeBottomEl");
1904 TEST_SB_END();
1905 Element_End0();
1906 }
1907
1908 //---------------------------------------------------------------------------
mae_DrcUserInterfaceInfo(int16u dataLength)1909 void File_Mpegh3da::mae_DrcUserInterfaceInfo(int16u dataLength)
1910 {
1911 Element_Begin1("mae_DrcUserInterfaceInfo");
1912 int8u version;
1913 Get_S1(2, version, "version");
1914 if (version==0)
1915 {
1916 int8u bsNumTargetLoudnessConditions;
1917 Get_S1(3, bsNumTargetLoudnessConditions, "bsNumTargetLoudnessConditions");
1918 int16u bsNumTargetLoudnessConditions_Real;
1919 if (dataLength>2)
1920 bsNumTargetLoudnessConditions_Real=(dataLength*8-(2+3))/(6+16);
1921 else
1922 bsNumTargetLoudnessConditions_Real=0;
1923 if (bsNumTargetLoudnessConditions!=bsNumTargetLoudnessConditions_Real)
1924 Param_Info1("Error");
1925 for (int16u Pos=0; Pos<bsNumTargetLoudnessConditions_Real; Pos++)
1926 {
1927 Skip_S1(6, "bsTargetLoudnessValueUpper");
1928 Skip_S2(16, "drcSetEffectAvailable");
1929 }
1930 }
1931 else
1932 {
1933 Skip_BS((dataLength-2)*8, "reserved");
1934 }
1935 Element_End0();
1936 }
1937
1938 //---------------------------------------------------------------------------
mae_ProductionScreenSizeDataExtension()1939 void File_Mpegh3da::mae_ProductionScreenSizeDataExtension()
1940 {
1941 Element_Begin1("mae_ProductionScreenSizeDataExtension");
1942 TEST_SB_SKIP( "mae_overwriteProductionScreenSizeData");
1943 Skip_S2(10, "bsScreenSizeLeftAz");
1944 Skip_S2(10, "bsScreenSizeRightAz");
1945 TEST_SB_END();
1946 int8u mae_NumPresetProductionScreens;
1947 Get_S1(5, mae_NumPresetProductionScreens, "mae_NumPresetProductionScreens");
1948 for (int8u Pos=0; Pos< mae_NumPresetProductionScreens; Pos++)
1949 {
1950 Skip_S1(5, "mae_productionScreenGroupPresetID");
1951 TEST_SB_SKIP( "mae_hasNonStandardScreenSize");
1952 TESTELSE_SB_SKIP( "isCenteredInAzimuth");
1953 Skip_S2(9, "bsScreenSizeAz");
1954 TESTELSE_SB_ELSE( "isCenteredInAzimuth");
1955 Skip_S2(10, "bsScreenSizeLeftAz");
1956 Skip_S2(10, "bsScreenSizeRightAz");
1957 TESTELSE_SB_END();
1958 Skip_S2(9, "bsScreenSizeTopEl");
1959 Skip_S2(9, "bsScreenSizeBottomEl");
1960 TEST_SB_END();
1961 }
1962 Element_End0();
1963 }
1964
1965
1966 //---------------------------------------------------------------------------
mae_GroupPresetDefinitionExtension(int8u numGroupPresets)1967 void File_Mpegh3da::mae_GroupPresetDefinitionExtension(int8u numGroupPresets)
1968 {
1969 Element_Begin1("mae_GroupPresetDefinitionExtension");
1970 for (int8u Pos=0; Pos<numGroupPresets; Pos++)
1971 {
1972 TEST_SB_SKIP( "mae_hasSwitchGroupConditions");
1973 int8u Temp=Pos<GroupPresets.size()?GroupPresets[Pos].Conditions.size():0;
1974 for(int8u Pos2=0; Pos2<Temp; Pos2++)
1975 Skip_SB( "mae_isSwitchGroupCondition");
1976 TEST_SB_END();
1977
1978 TEST_SB_SKIP( "mae_hasDownmixIdGroupPresetExtensions");
1979 int8u mae_numDownmixIdGroupPresetExtensions;
1980 Get_S1(5, mae_numDownmixIdGroupPresetExtensions, "mae_numDownmixIdGroupPresetExtensions");
1981 for (int8u Pos2=1; Pos2<mae_numDownmixIdGroupPresetExtensions+1; Pos2++)
1982 {
1983 Skip_S1(7, "mae_groupPresetDownmixId");
1984
1985 int8u mae_bsGroupPresetNumConditions;
1986 Get_S1(4, mae_bsGroupPresetNumConditions, "mae_bsGroupPresetNumConditions");
1987 for (int8u Pos3=0; Pos3<mae_bsGroupPresetNumConditions+1; Pos3++)
1988 {
1989 TESTELSE_SB_SKIP( "mae_isSwitchGroupCondition");
1990 Skip_S1(5, "mae_groupPresetSwitchGroupID");
1991 TESTELSE_SB_ELSE( "mae_isSwitchGroupCondition");
1992 Skip_S1(7, "mae_groupPresetGroupID");
1993 TESTELSE_SB_END();
1994 TEST_SB_SKIP( "mae_groupPresetConditionOnOff");
1995 Skip_SB( "mae_groupPresetDisableGainInteractivity");
1996 TEST_SB_SKIP( "mae_groupPresetGainFlag");
1997 Skip_S1(8, "mae_groupPresetGain");
1998 TEST_SB_END();
1999 Skip_SB( "mae_groupPresetDisablePositionInteractivity");
2000 TEST_SB_SKIP( "mae_groupPresetPositionFlag");
2001 Skip_S1(8, "mae_groupPresetAzOffset");
2002 Skip_S1(6, "mae_groupPresetElOffset");
2003 Skip_S1(4, "mae_groupPresetDistFactor");
2004 TEST_SB_END();
2005 TEST_SB_END();
2006 }
2007 }
2008 TEST_SB_END();
2009 }
2010 Element_End0();
2011 }
2012
2013 //---------------------------------------------------------------------------
mae_LoudnessCompensationData(int8u numGroups,int8u numGroupPresets)2014 void File_Mpegh3da::mae_LoudnessCompensationData(int8u numGroups, int8u numGroupPresets)
2015 {
2016 Element_Begin1("mae_LoudnessCompensationData");
2017 TEST_SB_SKIP( "mae_loudnessCompGroupLoudnessPresent");
2018 for (int8u Pos=0; Pos<numGroups; Pos++)
2019 Skip_S1(8, "mae_bsLoudnessCompGroupLoudness");
2020 TEST_SB_END();
2021
2022 TEST_SB_SKIP( "mae_loudnessCompDefaultParamsPresent");
2023 for (int8u Pos=0; Pos<numGroups; Pos++)
2024 Skip_SB( "mae_loudnessCompDefaultIncludeGroup");
2025
2026 TEST_SB_SKIP( "mae_loudnessCompDefaultMinMaxGainPresent");
2027 Skip_S1(4, "mae_bsLoudnessCompDefaultMinGain");
2028 Skip_S1(4, "mae_bsLoudnessCompDefaultMaxGain");
2029 TEST_SB_END();
2030 TEST_SB_END();
2031
2032 for (int8u Pos=0; Pos<numGroupPresets; Pos++)
2033 {
2034 TEST_SB_SKIP( "mae_loudnessCompPresetParamsPresent");
2035 for (int8u Pos2=0; Pos2<numGroups; Pos2++)
2036 Skip_SB( "mae_loudnessCompPresetIncludeGroup");
2037
2038 TEST_SB_SKIP( "mae_loudnessCompPresetMinMaxGainPresent");
2039 Skip_S1(4, "mae_bsLoudnessCompPresetMinGain");
2040 Skip_S1(4, "mae_bsLoudnessCompPresetMaxGain");
2041 TEST_SB_END();
2042 TEST_SB_END();
2043 }
2044 Element_End0();
2045 }
2046
2047 //---------------------------------------------------------------------------
audioTruncationInfo()2048 void File_Mpegh3da::audioTruncationInfo()
2049 {
2050 Element_Begin1("audioTruncationInfo");
2051 BS_Begin();
2052 Skip_SB( "isActive");
2053 Skip_SB( "ati_reserved");
2054 Skip_SB( "truncFromBegin");
2055 Skip_S2(13, "nTruncSamples");
2056 BS_End();
2057 Element_End0();
2058 }
2059
2060 //---------------------------------------------------------------------------
mhaC()2061 void File_Mpegh3da::mhaC()
2062 {
2063 Element_Begin1("MHADecoderConfigurationRecord");
2064 Skip_B1( "configurationVersion");
2065 Skip_B1( "mpegh3daProfileLevelIndication");
2066 Skip_B1( "referenceChannelLayout");
2067 Skip_B2( "mpegh3daConfigLength");
2068 mpegh3daConfig();
2069 Element_End0();
2070 }
2071
2072 //***************************************************************************
2073 // Helpers
2074 //***************************************************************************
2075
2076 //---------------------------------------------------------------------------
num_objects_Get()2077 size_t File_Mpegh3da::num_objects_Get()
2078 {
2079 size_t num_signals_InElements=0;
2080 for (size_t i=0; i<Elements.size(); i++)
2081 if (Elements[i].Type==ID_USAC_SCE || Elements[i].Type==ID_USAC_CPE)
2082 num_signals_InElements++;
2083 size_t num_signals_InSignals=0;
2084 for (size_t i=0; i<SignalGroups.size(); i++)
2085 {
2086 if (num_signals_InElements==num_signals_InSignals)
2087 {
2088 return SignalGroups[i].bsNumberOfSignals;
2089 break;
2090 }
2091 num_signals_InSignals+=SignalGroups[i].bsNumberOfSignals;
2092 }
2093
2094 return 0; //Problem
2095 }
2096
2097
2098 //---------------------------------------------------------------------------
Streams_Fill_ChannelLayout(const string & Prefix,const speaker_layout & Layout,int8u speakerLayoutType)2099 void File_Mpegh3da::Streams_Fill_ChannelLayout(const string& Prefix, const speaker_layout& Layout, int8u speakerLayoutType)
2100 {
2101 if (Aac_Channels_Get(Layout.ChannelLayout))
2102 {
2103 Fill(Stream_Audio, 0, (Prefix+"Channel(s)").c_str(), Aac_Channels_GetString(Layout.ChannelLayout));
2104 if (!Prefix.empty())
2105 Fill_SetOptions(Stream_Audio, 0, (Prefix + "Channel(s)").c_str(), "N NTY");
2106 if (!Prefix.empty())
2107 {
2108 string ChannelString=MediaInfoLib::Config.Language_Get(Ztring().From_UTF8(Aac_Channels_GetString(Layout.ChannelLayout)), __T(" channel")).To_UTF8();
2109 string ChannelMode=Aac_ChannelMode_GetString(Layout.ChannelLayout, true);
2110 if (ChannelMode.size()>3 || (ChannelMode.size()==3 && ChannelMode[2]!='0'))
2111 ChannelString+=" ("+Aac_ChannelMode_GetString(Layout.ChannelLayout, true)+")";
2112 Fill(Stream_Audio, 0, (Prefix+"Channel(s)/String").c_str(), ChannelString);
2113 Fill_SetOptions(Stream_Audio, 0, (Prefix + "Channel(s)/String").c_str(), "Y NTN");
2114 }
2115 Fill(Stream_Audio, 0, (Prefix+"ChannelPositions").c_str(), Aac_ChannelConfiguration_GetString(Layout.ChannelLayout));
2116 if (!Prefix.empty())
2117 Fill_SetOptions(Stream_Audio, 0, (Prefix+"ChannelPositions").c_str(), "N YTY");
2118 Fill(Stream_Audio, 0, (Prefix+"ChannelPositions/String2").c_str(), Aac_ChannelConfiguration2_GetString(Layout.ChannelLayout));
2119 if (!Prefix.empty())
2120 Fill_SetOptions(Stream_Audio, 0, (Prefix+"ChannelPositions/String2").c_str(), "N YTY");
2121 Fill(Stream_Audio, 0, (Prefix+"ChannelMode").c_str(), Aac_ChannelMode_GetString(Layout.ChannelLayout, true));
2122 Fill_SetOptions(Stream_Audio, 0, (Prefix+"ChannelMode").c_str(), "N NTY");
2123 Fill(Stream_Audio, 0, (Prefix+"ChannelLayout").c_str(), Aac_ChannelLayout_GetString(Layout.ChannelLayout, true));
2124 }
2125 else if (Layout.numSpeakers)
2126 {
2127 if (speakerLayoutType==1) // Objects
2128 {
2129 Fill(Stream_Audio, 0, (Prefix+"NumberOfObjects").c_str(), Layout.numSpeakers);
2130 Fill_SetOptions(Stream_Audio, 0, (Prefix+"NumberOfObjects").c_str(), "N YTY");
2131 Fill(Stream_Audio, 0, (Prefix + "NumberOfObjects/String").c_str(), MediaInfoLib::Config.Language_Get(Ztring::ToZtring(Layout.numSpeakers), __T(" object")));
2132 Fill_SetOptions(Stream_Audio, 0, (Prefix+"NumberOfObjects/String").c_str(), "Y YTN");
2133 }
2134 else
2135 {
2136 Fill(Stream_Audio, 0, (Prefix+"Channel(s)").c_str(), Layout.numSpeakers);
2137 Fill_SetOptions(Stream_Audio, 0, (Prefix+"Channel(s)").c_str(), "N YTY");
2138 Fill(Stream_Audio, 0, (Prefix + "Channel(s)/String").c_str(), MediaInfoLib::Config.Language_Get(Ztring::ToZtring(Layout.numSpeakers), __T(" channel")));
2139 Fill_SetOptions(Stream_Audio, 0, (Prefix+"Channel(s)/String").c_str(), "Y YTN");
2140 }
2141 if (!Layout.CICPspeakerIdxs.empty())
2142 {
2143 Fill(Stream_Audio, 0, (Prefix+"ChannelMode").c_str(), Aac_ChannelMode_GetString(Layout.CICPspeakerIdxs));
2144 Fill(Stream_Audio, 0, (Prefix+"ChannelLayout").c_str(), Aac_ChannelLayout_GetString(Layout.CICPspeakerIdxs));
2145 }
2146 else
2147 {
2148 vector<Aac_OutputChannel> CICPspeakerIdxs;
2149 string ChannelLayout;
2150 for (size_t i=0; i<Layout.SpeakersInfo.size(); i++)
2151 {
2152 if (i)
2153 ChannelLayout+=' ';
2154 if (Layout.SpeakersInfo[i].CICPspeakerIdx!=(Aac_OutputChannel)-1)
2155 {
2156 ChannelLayout+=Aac_ChannelLayout_GetString(&Layout.SpeakersInfo[i].CICPspeakerIdx, 1);
2157 CICPspeakerIdxs.push_back(Layout.SpeakersInfo[i].CICPspeakerIdx);
2158 }
2159 else
2160 {
2161 if (Layout.SpeakersInfo[i].ElevationAngle==0)
2162 ChannelLayout+='M';
2163 else
2164 ChannelLayout+=Layout.SpeakersInfo[i].ElevationDirection?'B':'U';
2165 ChannelLayout+='_';
2166 if (Layout.SpeakersInfo[i].AzimuthAngle!=0 && Layout.SpeakersInfo[i].AzimuthAngle!=180)
2167 ChannelLayout+=Layout.SpeakersInfo[i].AzimuthDirection?'L':'R';
2168 string AzimuthAngleString=Ztring::ToZtring(Layout.SpeakersInfo[i].AzimuthAngle).To_UTF8();
2169 AzimuthAngleString.insert(0, 3-AzimuthAngleString.size(), '0');
2170 ChannelLayout.append(AzimuthAngleString);
2171 }
2172 }
2173 if (CICPspeakerIdxs.size()==Layout.SpeakersInfo.size())
2174 {
2175 Fill(Stream_Audio, 0, (Prefix+"ChannelMode").c_str(), Aac_ChannelMode_GetString(CICPspeakerIdxs));
2176 Fill(Stream_Audio, 0, (Prefix+"ChannelLayout").c_str(), Aac_ChannelLayout_GetString(CICPspeakerIdxs));
2177 }
2178 else
2179 Fill(Stream_Audio, 0, (Prefix+"ChannelLayout").c_str(), ChannelLayout);
2180 }
2181 }
2182 else if (Layout.ChannelLayout)
2183 {
2184 Fill(Stream_Audio, 0, (Prefix+"ChannelLayout").c_str(), Layout.ChannelLayout);
2185 }
2186 }
2187
2188 //***************************************************************************
2189 // C++
2190 //***************************************************************************
2191
2192 } //NameSpace
2193
2194 #endif //MEDIAINFO_MPEGH3DA_YES
2195
2196