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 // https://developer.dolby.com/globalassets/professional/dolby-e/dolby-e-high-level-frame-description.pdf
9 //---------------------------------------------------------------------------
10 
11 //---------------------------------------------------------------------------
12 // Pre-compilation
13 #include "MediaInfo/PreComp.h"
14 #ifdef __BORLANDC__
15     #pragma hdrstop
16 #endif
17 //---------------------------------------------------------------------------
18 
19 //---------------------------------------------------------------------------
20 #include "MediaInfo/Setup.h"
21 //---------------------------------------------------------------------------
22 
23 //---------------------------------------------------------------------------
24 #if defined(MEDIAINFO_DOLBYE_YES)
25 //---------------------------------------------------------------------------
26 
27 //---------------------------------------------------------------------------
28 #include "MediaInfo/Audio/File_DolbyE.h"
29 #include "MediaInfo/Audio/File_Aac.h"
30 #include <cmath>
31 
32 #if !defined(INT8_MAX)
33 #define INT8_MAX (127)
34 #endif //!defined(INT8_MAX)
35 #if !defined(INT8_MIN)
36 #define INT8_MIN (-128)
37 #endif //!defined(INT8_MIN)
38 
39 using namespace std;
40 //---------------------------------------------------------------------------
41 
42 namespace MediaInfoLib
43 {
44 
45 //---------------------------------------------------------------------------
46 //CRC computing, with incomplete first and last bytes
47 //Inspired by http://zorc.breitbandkatze.de/crc.html
48 extern const int16u CRC_16_Table[256];
CRC_16_Compute(const int8u * Buffer_Begin,size_t Buffer_Size,int8u SkipBits_Begin,int8u SkipBits_End)49 int16u CRC_16_Compute(const int8u* Buffer_Begin, size_t Buffer_Size, int8u SkipBits_Begin, int8u SkipBits_End)
50 {
51     int16u CRC_16=0x0000;
52     const int8u* Buffer=Buffer_Begin;
53     const int8u* Buffer_End=Buffer+Buffer_Size;
54     if (SkipBits_End)
55         Buffer_End--; //Not handling completely the last byte
56 
57     //First partial byte
58     if (SkipBits_Begin)
59     {
60         for (int8u Mask=(1<<(7-SkipBits_Begin)); Mask; Mask>>=1)
61         {
62             bool NewBit=(CRC_16&0x8000)?true:false;
63             CRC_16<<=1;
64             if ((*Buffer)&Mask)
65                 NewBit=!NewBit;
66             if (NewBit)
67                 CRC_16^=0x8005;
68         }
69 
70         Buffer++;
71     }
72 
73     //Complete bytes
74     while (Buffer<Buffer_End)
75     {
76         CRC_16=(CRC_16<<8) ^ CRC_16_Table[(CRC_16>>8)^(*Buffer)];
77         Buffer++;
78     }
79 
80     //Last partial byte
81     if (SkipBits_End)
82     {
83         for (int8u Mask=0x80; Mask>(1<<(SkipBits_End-1)); Mask>>=1)
84         {
85             bool NewBit=(CRC_16&0x8000)?true:false;
86             CRC_16<<=1;
87             if ((*Buffer)&Mask)
88                 NewBit=!NewBit;
89             if (NewBit)
90                 CRC_16^=0x8005;
91         }
92 
93         Buffer++;
94     }
95 
96     return CRC_16;
97 }
98 
99 //***************************************************************************
100 // Infos
101 //***************************************************************************
102 
103 //---------------------------------------------------------------------------
104 static const int8u DolbyE_Programs[64]=
105 {2, 3, 2, 3, 4, 5, 4, 5, 6, 7, 8, 1, 2, 3, 3, 4, 5, 6, 1, 2, 3, 4, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
106 
107 //---------------------------------------------------------------------------
108 static const int8u DolbyE_Channels[64]=
109 {8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 6, 6, 6, 6, 6, 6, 6, 4, 4, 4, 4, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
110 
111 //---------------------------------------------------------------------------
DolbyE_Channels_PerProgram(int8u program_config,int8u program)112 const int8u DolbyE_Channels_PerProgram(int8u program_config, int8u program)
113 {
114     switch (program_config)
115     {
116         case  0 :   switch (program)
117                     {
118                         case  0 :   return 6;
119                         default :   return 2;
120                     }
121         case  1 :   switch (program)
122                     {
123                         case  0 :   return 6;
124                         default :   return 1;
125                     }
126         case  2 :
127         case 18 :   return 4;
128         case  3 :
129         case 12 :   switch (program)
130                     {
131                         case  0 :   return 4;
132                         default :   return 2;
133                     }
134         case  4 :   switch (program)
135                     {
136                         case  0 :   return 4;
137                         case  1 :   return 2;
138                         default :   return 1;
139                     }
140         case  5 :
141         case 13 :   switch (program)
142                     {
143                         case  0 :   return 4;
144                         default :   return 1;
145                     }
146         case  6 :
147         case 14 :
148         case 19 :   return 2;
149         case  7 :   switch (program)
150                     {
151                         case  0 :
152                         case  1 :
153                         case  2 :   return 2;
154                         default :   return 1;
155                     }
156         case  8 :
157         case 15 :   switch (program)
158                     {
159                         case  0 :
160                         case  1 :   return 2;
161                         default :   return 1;
162                     }
163         case  9 :
164         case 16 :
165         case 20 :   switch (program)
166                     {
167                         case  0 :   return 2;
168                         default :   return 1;
169                     }
170         case 10 :
171         case 17 :
172         case 21 :   return 1;
173         case 11 :   return 6;
174         case 22 :   return 8;
175         case 23 :   return 8;
176         default :   return 0;
177     }
178 };
179 
180 //---------------------------------------------------------------------------
181 const char*  DolbyE_ChannelPositions[64]=
182 {
183     "Front: L C R, Side: L R, LFE / Front: L R",
184     "Front: L C R, Side: L R, LFE / Front: C / Front: C",
185     "Front: L C R, LFE / Front: L C R, LFE",
186     "Front: L C R, LFE / Front: L R / Front: L R",
187     "Front: L C R, LFE / Front: L R / Front: C / Front: C",
188     "Front: L C R, LFE / Front: C / Front: C / Front: C / Front: C",
189     "Front: L R / Front: L R / Front: L R / Front: L R",
190     "Front: L R / Front: L R / Front: L R / Front: C / Front: C",
191     "Front: L R / Front: L R / Front: C / Front: C / Front: C / Front: C",
192     "Front: L R / Front: C / Front: C / Front: C / Front: C / Front: C / Front: C",
193     "Front: C / Front: C / Front: C / Front: C / Front: C / Front: C / Front: C / Front: C",
194     "Front: L C R, Side: L R, LFE",
195     "Front: L C R, LFE / Front: L R",
196     "Front: L C R, LFE / Front: C / Front: C",
197     "Front: L R / Front: L R / Front: L R",
198     "Front: L R / Front: L R / Front: C / Front: C",
199     "Front: L R / Front: C / Front: C / Front: C / Front: C",
200     "Front: C / Front: C / Front: C / Front: C / Front: C / Front: C",
201     "Front: L C R, LFE",
202     "Front: L R / Front: L R",
203     "Front: L R / Front: C / Front: C",
204     "Front: C / Front: C / Front: C / Front: C",
205     "Front: L C R, Side: L R, Rear: L R, LFE",
206     "Front: L C C C R, Side: L R, LFE",
207     "",
208     "",
209     "",
210     "",
211     "",
212     "",
213     "",
214     "",
215     "",
216     "",
217     "",
218     "",
219     "",
220     "",
221     "",
222     "",
223     "",
224     "",
225     "",
226     "",
227     "",
228     "",
229     "",
230     "",
231     "",
232     "",
233     "",
234     "",
235     "",
236     "",
237     "",
238     "",
239     "",
240     "",
241     "",
242     "",
243     "",
244     "",
245     "",
246     "",
247 };
248 
249 //---------------------------------------------------------------------------
DolbyE_ChannelPositions_PerProgram(int8u program_config,int8u program)250 const char*  DolbyE_ChannelPositions_PerProgram(int8u program_config, int8u program)
251 {
252     switch (program_config)
253     {
254         case  0 :   switch (program)
255                     {
256                         case  0 :   return "Front: L C R, Side: L R, LFE";
257                         default :   return "Front: L R";
258                     }
259         case  1 :   switch (program)
260                     {
261                         case  0 :   return "Front: L C R, Side: L R, LFE";
262                         default :   return "Front: C";
263                     }
264         case  2 :
265         case 18 :   return "Front: L C R, LFE";
266         case  3 :
267         case 12 :   switch (program)
268                     {
269                         case  0 :   return "Front: L C R, LFE";
270                         default :   return "Front: L R";
271                     }
272         case  4 :   switch (program)
273                     {
274                         case  0 :   return "Front: L C R, LFE";
275                         case  1 :   return "Front: L R";
276                         default :   return "Front: C";
277                     }
278         case  5 :
279         case 13 :   switch (program)
280                     {
281                         case  0 :   return "Front: L C R, LFE";
282                         default :   return "Front: C";
283                     }
284         case  6 :
285         case 14 :
286         case 19 :   return "Front: L R";
287         case  7 :   switch (program)
288                     {
289                         case  0 :
290                         case  1 :
291                         case  2 :   return "Front: L R";
292                         default :   return "Front: C";
293                     }
294         case  8 :
295         case 15 :   switch (program)
296                     {
297                         case  0 :
298                         case  1 :   return "Front: L R";
299                         default :   return "Front: C";
300                     }
301         case  9 :
302         case 16 :
303         case 20 :   switch (program)
304                     {
305                         case  0 :   return "Front: L R";
306                         default :   return "Front: C";
307                     }
308         case 10 :
309         case 17 :
310         case 21 :   return "Front: C";
311         case 11 :   return "Front: L C R, Side: L R, LFE";
312         case 22 :   return "Front: L C R, Side: L R, Rear: L R, LFE";
313         case 23 :   return "Front: L C C C R, Side: L R, LFE";
314         default :   return "";
315     }
316 };
317 
318 //---------------------------------------------------------------------------
319 const char*  DolbyE_ChannelPositions2[64]=
320 {
321     "3/2/0.1 / 2/0/0",
322     "3/2/0.1 / 1/0/0 / 1/0/0",
323     "3/0/0.1 / 3/0/0.1",
324     "3/0/0.1 / 2/0/0 / 2/0/0",
325     "3/0/0.1 / 2/0/0 / 1/0/0 / 1/0/0",
326     "3/0/0.1 / 1/0/0 / 1/0/0 / 1/0/0 / 1/0/0",
327     "2/0/0 / 2/0/0 / 2/0/0 / 2/0/0",
328     "2/0/0 / 2/0/0 / 2/0/0 / 1/0/0 / 1/0/0",
329     "2/0/0 / 2/0/0 / 1/0/0 / 1/0/0 / 1/0/0 / 1/0/0",
330     "2/0/0 / 1/0/0 / 1/0/0 / 1/0/0 / 1/0/0 / 1/0/0 / 1/0/0",
331     "1/0/0 / 1/0/0 / 1/0/0 / 1/0/0 / 1/0/0 / 1/0/0 / 1/0/0 / 1/0/0",
332     "3/2/0.1",
333     "3/0/0.1 / 2/0/0",
334     "3/0/0.1 / 1/0/0 / 1/0/0",
335     "2/0/0 / 2/0/0 / 2/0/0",
336     "2/0/0 / 2/0/0 / 1/0/0 / 1/0/0",
337     "2/0/0 / 1/0/0 / 1/0/0 / 1/0/0 / 1/0/0",
338     "1/0/0 / 1/0/0 / 1/0/0 / 1/0/0 / 1/0/0 / 1/0/0",
339     "3/0/0.1",
340     "2/0/0 / 2/0/0",
341     "2/0/0 / 1/0/0 / 1/0/0",
342     "1/0/0 / 1/0/0 / 1/0/0 / 1/0/0",
343     "3/2/2.1",
344     "5/2/0.1",
345     "",
346     "",
347     "",
348     "",
349     "",
350     "",
351     "",
352     "",
353     "",
354     "",
355     "",
356     "",
357     "",
358     "",
359     "",
360     "",
361     "",
362     "",
363     "",
364     "",
365     "",
366     "",
367     "",
368     "",
369     "",
370     "",
371     "",
372     "",
373     "",
374     "",
375     "",
376     "",
377     "",
378     "",
379     "",
380     "",
381     "",
382     "",
383     "",
384     "",
385 };
386 
387 //---------------------------------------------------------------------------
DolbyE_ChannelPositions2_PerProgram(int8u program_config,int8u program)388 const char*  DolbyE_ChannelPositions2_PerProgram(int8u program_config, int8u program)
389 {
390     switch (program_config)
391     {
392         case  0 :   switch (program)
393                     {
394                         case  0 :   return "3/2/0.1";
395                         default :   return "2/0/0";
396                     }
397         case  1 :   switch (program)
398                     {
399                         case  0 :   return "3/2/0.1";
400                         default :   return "1/0/0";
401                     }
402         case  2 :
403         case 18 :   return "3/0/0.1";
404         case  3 :
405         case 12 :   switch (program)
406                     {
407                         case  0 :   return "3/0/0.1";
408                         default :   return "2/0/0";
409                     }
410         case  4 :   switch (program)
411                     {
412                         case  0 :   return "3/0/0.1";
413                         case  1 :   return "2/0/0";
414                         default :   return "1/0/0";
415                     }
416         case  5 :
417         case 13 :   switch (program)
418                     {
419                         case  0 :   return "3/0/0.1";
420                         default :   return "1/0/0";
421                     }
422         case  6 :
423         case 14 :
424         case 19 :   return "Front: L R";
425         case  7 :   switch (program)
426                     {
427                         case  0 :
428                         case  1 :
429                         case  2 :   return "2/0/0";
430                         default :   return "1/0/0";
431                     }
432         case  8 :
433         case 15 :   switch (program)
434                     {
435                         case  0 :
436                         case  1 :   return "2/0/0";
437                         default :   return "1/0/0";
438                     }
439         case  9 :
440         case 16 :
441         case 20 :   switch (program)
442                     {
443                         case  0 :   return "2/0/0";
444                         default :   return "1/0/0";
445                     }
446         case 10 :
447         case 17 :
448         case 21 :   return "1/0/0";
449         case 11 :   return "3/2/0.1";
450         case 22 :   return "3/2/2.1";
451         case 23 :   return "5/2/0.1";
452         default :   return "";
453     }
454 };
455 
456 extern const char*  AC3_Surround[];
457 
458 //---------------------------------------------------------------------------
DolbyE_ChannelLayout_PerProgram(int8u program_config,int8u ProgramNumber)459 const char*  DolbyE_ChannelLayout_PerProgram(int8u program_config, int8u ProgramNumber)
460 {
461     switch (program_config)
462     {
463         case  0 :   switch (ProgramNumber)
464                     {
465                         case  0 :   return "L C Ls X R LFE Rs X";
466                         default :   return "X X X L X X X R";
467                     }
468         case  1 :   switch (ProgramNumber)
469                     {
470                         case  0 :   return "L C Ls X R LFE Rs X";
471                         case  1 :   return "X X X C X X X X";
472                         default :   return "X X X X X X X C";
473                     }
474         case  2 :   switch (ProgramNumber)
475                     {
476                         case  0 :   return "L C X X R S X X";
477                         default :   return "X X L C X X R S";
478                     }
479         case  3 :   switch (ProgramNumber)
480                     {
481                         case  0 :   return "L C X X R S X X";
482                         case  1 :   return "X X L X X X R X";
483                         default :   return "X X X L X X X R";
484                     }
485         case  4 :   switch (ProgramNumber)
486                     {
487                         case  0 :   return "L C X X R S X X";
488                         case  1 :   return "X X L X X X R X";
489                         case  2 :   return "X X X C X X X X";
490                         default :   return "X X X X X X X C";
491                     }
492         case  5 :   switch (ProgramNumber)
493                     {
494                         case  0 :   return "L C X X R S X X";
495                         case  1 :   return "X X C X X X X X";
496                         case  2 :   return "X X X X X X C X";
497                         case  3 :   return "X X X C X X X X";
498                         default :   return "X X X X X X X C";
499                     }
500         case  6 :   switch (ProgramNumber)
501                     {
502                         case  0 :   return "L X X X R X X X";
503                         case  1 :   return "X L X X X R X X";
504                         case  2 :   return "X X L X X X R X";
505                         default :   return "X X X L X X X R";
506                     }
507         case  7 :   switch (ProgramNumber)
508                     {
509                         case  0 :   return "L X X X R X X X";
510                         case  1 :   return "X L X X X R X X";
511                         case  2 :   return "X X L X X X R X";
512                         case  3 :   return "X X X C X X X X";
513                         default :   return "X X X X X X X C";
514                     }
515         case  8 :   switch (ProgramNumber)
516                     {
517                         case  0 :   return "L X X X R X X X";
518                         case  1 :   return "X L X X X R X X";
519                         case  2 :   return "X X C X X X X X";
520                         case  3 :   return "X X X X X X C X";
521                         case  4 :   return "X X X C X X X X";
522                         default :   return "X X X X X X X C";
523                     }
524         case  9 :   switch (ProgramNumber)
525                     {
526                         case  0 :   return "L X X X R X X X";
527                         case  1 :   return "X C X X X X X X";
528                         case  2 :   return "X X X X X C X X";
529                         case  3 :   return "X X C X X X X X";
530                         case  4 :   return "X X X X X X C X";
531                         case  5 :   return "X X X C X X X X";
532                         default :   return "X X X X X X X C";
533                     }
534         case 10 :   switch (ProgramNumber)
535                     {
536                         case  0 :   return "C X X X X X X X";
537                         case  1 :   return "X X X X C X X X";
538                         case  2 :   return "X C X X X X X X";
539                         case  3 :   return "X X X X X C X X";
540                         case  4 :   return "X X C X X X X X";
541                         case  5 :   return "X X X X X X C X";
542                         case  6 :   return "X X X C X X X X";
543                         default :   return "X X X X X X X C";
544                     }
545         case 11 :   return "L C Ls R LFE Rs";
546         case 12 :   switch (ProgramNumber)
547                     {
548                         case  0 :   return "L C X R S X";
549                         default :   return "X X L X X R";
550                     }
551         case 13 :   switch (ProgramNumber)
552                     {
553                         case  0 :   return "L C X R S X";
554                         case  1 :   return "X X C X X X";
555                         default :   return "X X X X X C";
556                     }
557         case 14 :   switch (ProgramNumber)
558                     {
559                         case  0 :   return "L X X R X X";
560                         case  1 :   return "X L X X R X";
561                         default :   return "X X L X X R";
562                     }
563         case 15 :   switch (ProgramNumber)
564                     {
565                         case  0 :   return "L X X R X X";
566                         case  1 :   return "X L X R X";
567                         case  2 :   return "X X C X X X";
568                         default :   return "X X X X X C";
569                     }
570         case 16 :   switch (ProgramNumber)
571                     {
572                         case  0 :   return "L X X R X X";
573                         case  1 :   return "X C X X X X";
574                         case  2 :   return "X X X X C X";
575                         case  3 :   return "X X C X X X";
576                         default :   return "X X X X X C";
577                     }
578         case 17 :   switch (ProgramNumber)
579                     {
580                         case  0 :   return "C X X X X X";
581                         case  1 :   return "X X X C X X";
582                         case  2 :   return "X C X X X X";
583                         case  3 :   return "X X X X C X";
584                         case  4 :   return "X X C X X X";
585                         default :   return "X X X X X C";
586                     }
587         case 18 :   return "L C R S";
588         case 19 :   switch (ProgramNumber)
589                     {
590                         case  0 :   return "L X R X";
591                         default :   return "X L X R";
592                     }
593         case 20 :   switch (ProgramNumber)
594                     {
595                         case  0 :   return "L X R X";
596                         case  1 :   return "X C X X";
597                         default :   return "X X X C";
598                     }
599         case 21 :   switch (ProgramNumber)
600                     {
601                         case  0 :   return "C X X X";
602                         case  1 :   return "X X C X";
603                         case  2 :   return "X C X X";
604                         default :   return "X X X C";
605                     }
606         case 22 :   return "L C Ls Lrs R LFE Rs Rrs";
607         case 23 :   return "L C Ls Lc R LFE Rs Rc";
608         default :   return "";
609     }
610 };
611 
612 extern const float64 Mpegv_frame_rate[16];
613 
614 const bool Mpegv_frame_rate_type[16]=
615 {false, false, false, false, false, false, true, true, true, false, false, false, false, false, false, false};
616 
617 
618 //---------------------------------------------------------------------------
619 static const int8u intermediate_spatial_format_object_count[8]=
620 {
621     4,
622     8,
623     10,
624     14,
625     15,
626     30,
627     0,
628     0,
629 };
630 
631 const char* sound_category_Values[4]=
632 {
633     "",
634     "Dialog",
635     "",
636     "",
637 };
638 const char* hp_render_mode_Values[4]=
639 {
640     "Bypassed",
641     "Near",
642     "Far",
643     "",
644 };
default_target_device_config_Value(int32u config)645 string default_target_device_config_Value(int32u config)
646 {
647     string Value;
648     if (config&0x1)
649         Value+="Stereo / ";
650     if (config&0x2)
651         Value+="Surround / ";
652     if (config&0x4)
653         Value+="Immersive / ";
654     if (!Value.empty())
655         Value.resize(Value.size()-3);
656     return Value;
657 }
658 struct pos3d
659 {
660     int8u x;
661     int8u y;
662     int8u z;
663     const char* Value;
664 };
665 int16u mgi_6bit_unsigned_to_oari_Q15[0x40]=
666 {
667       0,   529,  1057,  1586,  2114,  2643,  3171,  3700,
668    4228,  4757,  5285,  5814,  6342,  6871,  7399,  7928,
669    8456,  8985,  9513, 10042, 10570, 11099, 11627, 12156,
670   12684, 13213, 13741, 14270, 14798, 15327, 15855, 16384,
671   16913, 17441, 17970, 18498, 19027, 19555, 20084, 20612,
672   21141, 21669, 22198, 22726, 23255, 23783, 24312, 24840,
673   25369, 25897, 26426, 26954, 27483, 28011, 28540, 29068,
674   29597, 30125, 30654, 31182, 31711, 32239, 32767, 32767
675 };
676 
677 int16u mgi_4bit_unsigned_to_oari_Q15[0x10]=
678 {
679       0,  2185,  4369,  6554,  8738, 10923, 13107, 15292,
680   17476, 19661, 21845, 24030, 26214, 28399, 30583, 32767
681 };
682 
mgi_bitstream_val_to_Q15(int value,int8u num_bits)683 int mgi_bitstream_val_to_Q15(int value, int8u num_bits)
684 {
685     bool sign;
686     if (value<0)
687     {
688         sign=true;
689         value=-value;
690     }
691     else
692         sign=false;
693 
694     int16u* Table;
695     switch (num_bits)
696     {
697         case 4: Table=mgi_4bit_unsigned_to_oari_Q15; break;
698         case 6: Table=mgi_6bit_unsigned_to_oari_Q15; break;
699         default: return 0; //Problem
700     }
701     int decoded=Table[value];
702 
703     return sign?-decoded:decoded;
704 }
705 
mgi_bitstream_pos_z_to_Q15(bool pos_z_sign,int8u pos_z_bits)706 int mgi_bitstream_pos_z_to_Q15(bool pos_z_sign, int8u pos_z_bits)
707 {
708     if (pos_z_bits == 0xf) {
709         if (pos_z_sign == 1) /* +1 */ {
710             return(32767);
711         }
712         else /* -1 */ {
713             return(-32768);
714         }
715     }
716     else {
717         /* Negative number */
718         if (pos_z_sign == 1) {
719             return(mgi_bitstream_val_to_Q15(pos_z_bits, 4));
720         }
721         else {
722             return(mgi_bitstream_val_to_Q15(-pos_z_bits, 4));
723         }
724     }
725 }
726 
727 //---------------------------------------------------------------------------
728 struct speaker_info
729 {
730     int8u AzimuthAngle; //0 to 180 (right, if AzimuthDirection is false) or 179 (left, if AzimuthDirection is true)
731     int8s ElevationDirectionAngle; //-90 (bottom) to 90 (top)
732     enum flag
733     {
734         None                            = 0,
735         AzimuthDirection                = 1<<0, // true = right
736         isLFE                           = 1<<1,
737     };
738     int8u Flags;
739 };
operator ==(const speaker_info & L,const speaker_info & R)740 bool operator== (const speaker_info& L, const speaker_info& R)
741 {
742     return L.AzimuthAngle==R.AzimuthAngle
743         && L.ElevationDirectionAngle==R.ElevationDirectionAngle
744         && L.Flags==R.Flags;
745 }
746 extern string Aac_ChannelLayout_GetString(const Aac_OutputChannel* const OutputChannels, size_t OutputChannels_Size);
747 static const size_t SpeakerInfos_Size=43;
748 static const speaker_info SpeakerInfos[SpeakerInfos_Size] =
749 {
750     {  30,   0, speaker_info::AzimuthDirection },
751     {  30,   0, speaker_info::None },
752     {   0,   0, speaker_info::None },
753     {   0, -15,                                 speaker_info::isLFE },
754     { 110,   0, speaker_info::AzimuthDirection },
755     { 110,   0, speaker_info::None },
756     {  22,   0, speaker_info::AzimuthDirection },
757     {  22,   0, speaker_info::None },
758     { 135,   0, speaker_info::AzimuthDirection },
759     { 135,   0, speaker_info::None },
760     { 180,   0, speaker_info::None },
761     { 135,   0, speaker_info::AzimuthDirection },
762     { 135,   0, speaker_info::None },
763     {  90,   0, speaker_info::AzimuthDirection },
764     {  90,   0, speaker_info::None },
765     {  60,   0, speaker_info::AzimuthDirection },
766     {  60,   0, speaker_info::None },
767     {  30,  35, speaker_info::AzimuthDirection },
768     {  30,  35, speaker_info::None },
769     {   0,  35, speaker_info::None },
770     { 135,  35, speaker_info::AzimuthDirection },
771     { 135,  35, speaker_info::None },
772     { 180,  35, speaker_info::None },
773     {  90,  35, speaker_info::AzimuthDirection },
774     {  90,  35, speaker_info::None },
775     {   0,  90, speaker_info::None },
776     {  45, -15,                                 speaker_info::isLFE },
777     {  45, -15, speaker_info::AzimuthDirection },
778     {  45, -15, speaker_info::None },
779     {   0, -15, speaker_info::None },
780     { 110,  35, speaker_info::AzimuthDirection },
781     { 110,  35, speaker_info::None },
782     {  45,  35, speaker_info::AzimuthDirection },
783     {  45,  35, speaker_info::None },
784     {  45,   0, speaker_info::AzimuthDirection },
785     {  45,   0, speaker_info::None },
786     {  45, -15, speaker_info::None | speaker_info::isLFE },
787     {   2,   0, speaker_info::AzimuthDirection },
788     {   2,   0, speaker_info::None },
789     {   1,   0, speaker_info::AzimuthDirection },
790     {   1,   0, speaker_info::None },
791     { 150,   0, speaker_info::AzimuthDirection },
792     { 150,   0, speaker_info::None },
793 };
794 
795 struct angles
796 {
797     int Azimuth;
798     int Elevation;
799 
anglesMediaInfoLib::angles800     angles()
801     {}
802 
anglesMediaInfoLib::angles803     angles(int theta, int phi) :
804         Azimuth(theta),
805         Elevation(phi)
806     {}
807 };
AnglesToChannelName(angles Angles)808 Aac_OutputChannel AnglesToChannelName(angles Angles)
809 {
810     speaker_info SpeakerInfo;
811     if (Angles.Azimuth<0)
812     {
813         SpeakerInfo.AzimuthAngle=(int8u)-Angles.Azimuth;
814         SpeakerInfo.Flags=speaker_info::AzimuthDirection;
815     }
816     else
817     {
818         SpeakerInfo.AzimuthAngle=Angles.Azimuth;
819         SpeakerInfo.Flags=speaker_info::None;
820     }
821     SpeakerInfo.ElevationDirectionAngle=Angles.Elevation;
822 
823     for (size_t i=0; i<SpeakerInfos_Size; i++)
824         if (SpeakerInfos[i]==SpeakerInfo)
825             return (Aac_OutputChannel)i;
826     return CH_MAX;
827 }
ToAngle3Digits(int Value)828 string ToAngle3Digits(int Value)
829 {
830     string ToReturn=Ztring::ToZtring(Value).To_UTF8();
831     ToReturn.insert(0, 3-ToReturn.size(), '0');
832     return ToReturn;
833 }
mgi_bitstream_pos_ToAngles(int x_int,int y_int,int z_int)834 angles mgi_bitstream_pos_ToAngles(int x_int, int y_int, int z_int)
835 {
836     //Center becomes 0 and edges +/-1
837     float x=(((float)x_int)*2-32768)/32768;
838     float y=(((float)y_int)*2-32768)/32768;
839     float z=((float)z_int)/32768;
840 
841     if (!x && !y)
842     {
843         if (z>0)
844             return angles(0, 90);
845         else if (z<0)
846             return angles(0, -90);
847         return angles(0, 0); // Should not happen (is the center in practice)
848     }
849     else
850     {
851         angles ToReturn;
852 
853         float radius=sqrt(x*x+y*y+z*z);
854         float theta_float=round(atan2(y, x)*180/3.14159265359/5)*5;
855         ToReturn.Azimuth=float32_int32s(theta_float);
856         float phi_float=round(acos(z/radius)*180/3.14159265359);
857         ToReturn.Elevation=float32_int32s(phi_float);
858 
859         //Reference is front of viewer
860         if (ToReturn.Azimuth<90)
861             ToReturn.Azimuth+=90;
862         else
863             ToReturn.Azimuth-=270;
864         ToReturn.Elevation=90-ToReturn.Elevation;
865 
866         return ToReturn;
867     }
868 }
869 
Angles2String(angles Angles)870 string Angles2String(angles Angles)
871 {
872     string ToReturn;
873 
874     //Elevation
875     switch (Angles.Elevation)
876     {
877         case   0:   ToReturn+='M'; break;
878         case  90:   ToReturn+='T'; break;
879         case -90:   ToReturn+='X'; break; //No standard for that
880         default :   ToReturn+=(Angles.Elevation>0?'U':'B');
881                     //if (Angles.phi!=35 && Angles.phi!=-15)
882                         ToReturn+=ToAngle3Digits(Angles.Elevation);
883     }
884 
885     ToReturn+='_';
886 
887     //Azimuth
888     if (Angles.Azimuth<0)
889         ToReturn+='L';
890     else if (Angles.Azimuth>0 && Angles.Azimuth!=180)
891         ToReturn+='R';
892     ToReturn+=ToAngle3Digits(Angles.Azimuth<0?-Angles.Azimuth:Angles.Azimuth);
893 
894     return ToReturn;
895 }
896 
Angles2KnownChannelName(angles & Angles)897 string Angles2KnownChannelName(angles& Angles)
898 {
899     //Exception handling
900     int Azimuth;
901     if (Angles.Azimuth==-180)
902         Azimuth=180;
903     else
904         Azimuth=Angles.Azimuth;
905     int Elevation;
906     if (Angles.Elevation>=35 && Angles.Elevation<=45)
907         Elevation=35;
908     else
909         Elevation=Angles.Elevation;
910 
911     Aac_OutputChannel KnownChannel=AnglesToChannelName(angles(Azimuth, Elevation));
912     if (KnownChannel!=CH_MAX)
913         return Aac_ChannelLayout_GetString(&KnownChannel, 1);
914     else
915         return Angles2String(Angles);
916 }
917 
918 //---------------------------------------------------------------------------
919 extern int32u AC3_bed_channel_assignment_mask_2_nonstd(int16u bed_channel_assignment_mask);
920 extern Ztring AC3_nonstd_bed_channel_assignment_mask_ChannelLayout(int32u nonstd_bed_channel_assignment_mask);
BedChannelConfiguration_ChannelCount(int32u nonstd_bed_channel_assignment_mask)921 size_t BedChannelConfiguration_ChannelCount(int32u nonstd_bed_channel_assignment_mask)
922 {
923     Ztring BedChannelConfiguration=AC3_nonstd_bed_channel_assignment_mask_ChannelLayout(nonstd_bed_channel_assignment_mask);
924     size_t BedChannelCount=0;
925     if (!BedChannelConfiguration.empty())
926         for (size_t i=0; i<BedChannelConfiguration.size();)
927         {
928             BedChannelCount++;
929             i=BedChannelConfiguration.find(__T(' '), i+1);
930         }
931     return BedChannelCount;
932 }
933 
934 //***************************************************************************
935 // Constructor/Destructor
936 //***************************************************************************
937 
938 //---------------------------------------------------------------------------
File_DolbyE()939 File_DolbyE::File_DolbyE()
940 :File__Analyze()
941 {
942     //Configuration
943     #if MEDIAINFO_EVENTS
944         ParserIDs[0]=MediaInfo_Parser_DolbyE;
945     #endif //MEDIAINFO_EVENTS
946 
947     //Configuration
948     MustSynchronize=true;
949     Buffer_TotalBytes_FirstSynched_Max=32*1024;
950 
951     //In
952     GuardBand_Before=0;
953 
954     //Out
955     GuardBand_After=0;
956 
957     //ED2
958     Guardband_EMDF_PresentAndSize=0;
959     num_desc_packets_m1=(int32u)-1;
960 
961     //Temp
962     SMPTE_time_code_StartTimecode=(int64u)-1;
963     FrameInfo.DTS=0;
964 }
965 
966 //***************************************************************************
967 // Streams management
968 //***************************************************************************
969 
970 //---------------------------------------------------------------------------
Streams_Fill()971 void File_DolbyE::Streams_Fill()
972 {
973     Fill(Stream_General, 0, General_Format, "Dolby E");
974 
975     if (!Presets.empty())
976     {
977         Streams_Fill_ED2();
978         return;
979     }
980 
981     int8u DolbyE_Audio_Pos=0;
982     for (size_t i=0; i<8; i++)
983         if (channel_subsegment_sizes[i].size()>1)
984             DolbyE_Audio_Pos=(int8u)-1;
985     for (int8u program=0; program<DolbyE_Programs[program_config]; program++)
986     {
987         Stream_Prepare(Stream_Audio);
988         Fill(Stream_Audio, StreamPos_Last, Audio_Format, "Dolby E");
989         if (DolbyE_Programs[program_config]>1)
990             Fill(Stream_Audio, StreamPos_Last, Audio_ID, Count_Get(Stream_Audio));
991         Fill(Stream_Audio, StreamPos_Last, Audio_Channel_s_, DolbyE_Channels_PerProgram(program_config, program));
992         Fill(Stream_Audio, StreamPos_Last, Audio_ChannelPositions, DolbyE_ChannelPositions_PerProgram(program_config, program));
993         Fill(Stream_Audio, StreamPos_Last, Audio_ChannelPositions_String2, DolbyE_ChannelPositions2_PerProgram(program_config, program));
994         Fill(Stream_Audio, StreamPos_Last, Audio_ChannelLayout, DolbyE_ChannelLayout_PerProgram(program_config, program));
995         int32u Program_Size=0;
996         if (DolbyE_Audio_Pos!=(int8u)-1)
997             for (int8u Pos=0; Pos<DolbyE_Channels_PerProgram(program_config, program); Pos++)
998                 Program_Size+=channel_subsegment_size[DolbyE_Audio_Pos+Pos];
999         if (!Mpegv_frame_rate_type[frame_rate_code])
1000             Program_Size*=2; //Low bit rate, 2 channel component per block
1001         Program_Size*=bit_depth;
1002         Fill(Stream_Audio, StreamPos_Last, Audio_BitRate, Program_Size*Mpegv_frame_rate[frame_rate_code], 0);
1003         if (DolbyE_Audio_Pos!=(int8u)-1)
1004             DolbyE_Audio_Pos+=DolbyE_Channels_PerProgram(program_config, program);
1005         Streams_Fill_PerProgram();
1006 
1007         if (program<description_text_Values.size())
1008         {
1009             Fill(Stream_Audio, StreamPos_Last, Audio_Title, description_text_Values[program].Previous);
1010             Fill(Stream_Audio, StreamPos_Last, "Title_FromStream", description_text_Values[program].Previous);
1011             Fill_SetOptions(Stream_Audio, StreamPos_Last, "Title_FromStream", "N NT");
1012         }
1013     }
1014 }
1015 
1016 //---------------------------------------------------------------------------
Streams_Fill_PerProgram()1017 void File_DolbyE::Streams_Fill_PerProgram()
1018 {
1019     Fill(Stream_Audio, StreamPos_Last, Audio_SamplingRate, 48000);
1020     Fill(Stream_Audio, StreamPos_Last, Audio_BitDepth, bit_depth);
1021 
1022     if (SMPTE_time_code_StartTimecode!=(int64u)-1)
1023     {
1024         Fill(StreamKind_Last, StreamPos_Last, Audio_Delay, SMPTE_time_code_StartTimecode);
1025         Fill(StreamKind_Last, StreamPos_Last, Audio_Delay_Source, "Stream");
1026     }
1027 
1028     Fill(Stream_Audio, StreamPos_Last, Audio_FrameRate, Mpegv_frame_rate[frame_rate_code]);
1029     if (FrameInfo.PTS!=(int64u)-1 && bit_depth)
1030     {
1031         float BitRate=(float)(96000*bit_depth);
1032 
1033         if (GuardBand_Before_Initial)
1034         {
1035             float GuardBand_Before_Initial_Duration=GuardBand_Before_Initial*8/BitRate;
1036             Fill(Stream_Audio, StreamPos_Last, "GuardBand_Before", GuardBand_Before_Initial_Duration, 9);
1037             Fill(Stream_Audio, StreamPos_Last, "GuardBand_Before/String", Ztring::ToZtring(GuardBand_Before_Initial_Duration*1000000, 0)+Ztring().From_UTF8(" \xC2xB5s")); //0xC2 0xB5 = micro sign
1038             Fill_SetOptions(Stream_Audio, StreamPos_Last, "GuardBand_Before", "N NT");
1039             Fill_SetOptions(Stream_Audio, StreamPos_Last, "GuardBand_Before/String", "N NT");
1040 
1041             float GuardBand_After_Initial_Duration=GuardBand_After_Initial*8/BitRate;
1042             Fill(Stream_Audio, StreamPos_Last, "GuardBand_After", GuardBand_After_Initial_Duration, 9);
1043             Fill(Stream_Audio, StreamPos_Last, "GuardBand_After/String", Ztring::ToZtring(GuardBand_After_Initial_Duration*1000000, 0)+Ztring().From_UTF8(" \xC2xB5s")); //0xC2 0xB5 = micro sign
1044             Fill_SetOptions(Stream_Audio, StreamPos_Last, "GuardBand_After", "N NT");
1045             Fill_SetOptions(Stream_Audio, StreamPos_Last, "GuardBand_After/String", "N NT");
1046         }
1047     }
1048 
1049     if (FrameSizes.size()==1)
1050     {
1051         if (StreamPos_Last)
1052             Fill(Stream_Audio, StreamPos_Last, Audio_BitRate_Encoded, 0, 0, true);
1053         else
1054         {
1055             Fill(Stream_General, 0, General_OverallBitRate, FrameSizes.begin()->first*8*Mpegv_frame_rate[frame_rate_code], 0);
1056             Fill(Stream_Audio, 0, Audio_BitRate_Encoded, FrameSizes.begin()->first*8*Mpegv_frame_rate[frame_rate_code], 0);
1057         }
1058     }
1059 }
1060 
1061 //---------------------------------------------------------------------------
Streams_Fill_ED2()1062 void File_DolbyE::Streams_Fill_ED2()
1063 {
1064     Stream_Prepare(Stream_Audio);
1065     Fill(Stream_Audio, StreamPos_Last, Audio_Format, "Dolby ED2");
1066     if (Guardband_EMDF_PresentAndSize)
1067         Fill(Stream_Audio, StreamPos_Last, Audio_BitRate, Guardband_EMDF_PresentAndSize*8*Mpegv_frame_rate[frame_rate_code], 0);
1068     size_t ChannelCount=DynObjects.size();
1069     for (size_t p=0; p<BedInstances.size(); p++)
1070         if (p<nonstd_bed_channel_assignment_masks.size())
1071             ChannelCount+=BedChannelConfiguration_ChannelCount(nonstd_bed_channel_assignment_masks[p]);
1072     if (ChannelCount)
1073         Fill(Stream_Audio, StreamPos_Last, Audio_Channel_s_, ChannelCount);
1074     Streams_Fill_PerProgram();
1075 
1076     if (!Presets.empty())
1077     {
1078         Fill(Stream_Audio, 0, "NumberOfPresentations", Presets.size());
1079         Fill_SetOptions(Stream_Audio, 0, "NumberOfPresentations", "N NIY");
1080     }
1081     if (!BedInstances.empty())
1082     {
1083         Fill(Stream_Audio, 0, "NumberOfBeds", BedInstances.size());
1084         Fill_SetOptions(Stream_Audio, 0, "NumberOfBeds", "N NIY");
1085     }
1086     if (!DynObjects.empty())
1087     {
1088         Fill(Stream_Audio, 0, "NumberOfObjects", DynObjects.size());
1089         Fill_SetOptions(Stream_Audio, 0, "NumberOfObjects", "N NIY");
1090     }
1091 
1092     for (size_t p=0; p<Presets.size(); p++)
1093     {
1094         const preset& Presentation_Current=Presets[p];
1095 
1096         string Title;
1097         if (p<Presets_More.size() && !Presets_More[p].description.empty())
1098             Title=Presets_More[p].description;
1099 
1100         string Summary=Title;
1101         if (Summary.empty())
1102             Summary="Yes";
1103 
1104         string P="Presentation"+Ztring::ToZtring(p).To_UTF8();
1105         Fill(Stream_Audio, 0, P.c_str(), Summary);
1106         if (!Title.empty())
1107         {
1108             Fill(Stream_Audio, 0, (P+" Title").c_str(), Title);
1109             Fill_SetOptions(Stream_Audio, 0, (P+" Title").c_str(), "N NTY");
1110         }
1111         Fill(Stream_Audio, 0, (P+" DefaultTargetDeviceConfig").c_str(), default_target_device_config_Value(Presentation_Current.default_target_device_config));
1112         Fill_SetOptions(Stream_Audio, 0, (P+" DefaultTargetDeviceConfig").c_str(), "Y NTY");
1113 
1114         if (!Presentation_Current.target_device_configs.empty())
1115         {
1116             Fill(Stream_Audio, 0, (P+" NumberOfTargets").c_str(), Presentation_Current.target_device_configs.size());
1117             Fill_SetOptions(Stream_Audio, 0, (P+" NumberOfTargets").c_str(), "N NIY");
1118         }
1119         for (size_t t=0; t<Presentation_Current.target_device_configs.size(); t++)
1120         {
1121             const preset::target_device_config& Target_Current=Presentation_Current.target_device_configs[t];
1122 
1123             string Summary2=default_target_device_config_Value(Target_Current.target_devices_mask);
1124             if (Summary2.empty())
1125                 Summary2="Yes";
1126 
1127             string T=P+" Target"+Ztring::ToZtring(t).To_UTF8();
1128             Fill(Stream_Audio, 0, T.c_str(), Summary2);
1129 
1130             Fill(Stream_Audio, 0, (T+" TargetDeviceConfig").c_str(), default_target_device_config_Value(Target_Current.target_devices_mask));
1131             Fill_SetOptions(Stream_Audio, 0, (T+" TargetDeviceConfig").c_str(), "N NTY");
1132 
1133             ZtringList GroupPos[2], GroupNum[2];
1134             for (size_t i=0; i<Target_Current.md_indexes.size(); i++)
1135             {
1136                 if (Target_Current.md_indexes[i]!=(int32u)-1)
1137                 {
1138                     size_t I1, I2;
1139                     if (i<DynObjects.size())
1140                     {
1141                         I1=i;
1142                         I2=Target_Current.md_indexes[i];
1143                         if (I2 && I2>DynObjects[I1].Alts.size()) // 0 = OAMD, else Alt - 1
1144                             I2=0; // There is a problem
1145                     }
1146                     else
1147                     {
1148                         I1=i-DynObjects.size();
1149                         I2=Target_Current.md_indexes[i];
1150                         if (I2 && I2>BedInstances[I1].Alts.size()) // 0 = OAMD, else Alt - 1
1151                             I2=0; // There is a problem
1152                     }
1153 
1154                     int j=i<DynObjects.size()?1:0;
1155                     GroupPos[j].push_back(Ztring::ToZtring(I1));
1156                     GroupNum[j].push_back(Ztring::ToZtring(I1+1));
1157                     if (I2 )
1158                     {
1159                         GroupPos[j][GroupPos[j].size()-1]+=__T('-');
1160                         GroupNum[j][GroupNum[j].size()-1]+=__T('-');
1161                         GroupPos[j][GroupPos[j].size()-1]+=Ztring::ToZtring(I2-1);
1162                         GroupNum[j][GroupNum[j].size()-1]+=Ztring::ToZtring(I2);
1163                     }
1164                 }
1165             }
1166 
1167             for (size_t i=0; i<2; i++)
1168             {
1169                 GroupPos[i].Separator_Set(0, __T(" + "));
1170                 Fill(Stream_Audio, 0, (T+(!i?" LinkedTo_Bed_Pos":" LinkedTo_Object_Pos")).c_str(), GroupPos[i].Read());
1171                 Fill_SetOptions(Stream_Audio, 0, (T+(!i?" LinkedTo_Bed_Pos":" LinkedTo_Object_Pos")).c_str(), "N NIY");
1172                 GroupNum[i].Separator_Set(0, __T(" + "));
1173                 Fill(Stream_Audio, 0, (T+(!i?" LinkedTo_Bed_Pos/String":" LinkedTo_Object_Pos/String")).c_str(), GroupNum[i].Read());
1174                 Fill_SetOptions(Stream_Audio, 0, (T+(!i?" LinkedTo_Bed_Pos/String":" LinkedTo_Object_Pos/String")).c_str(), "Y NIN");
1175             }
1176         }
1177     }
1178 
1179     // Computing the count of objects in bed instances
1180     size_t Bed_Object_Count=0;
1181 
1182     // Beds
1183     for (size_t p=0; p<BedInstances.size(); p++)
1184     {
1185         const bed_instance& BedInstance=BedInstances[p];
1186 
1187         string Summary;
1188         if (Summary.empty())
1189             Summary=AC3_nonstd_bed_channel_assignment_mask_ChannelLayout(nonstd_bed_channel_assignment_masks[p]).To_UTF8();
1190         if (Summary.empty())
1191             Summary="Yes";
1192 
1193         string P=Ztring(__T("Bed")+Ztring::ToZtring(p)).To_UTF8();
1194         Fill(Stream_Audio, 0, P.c_str(), Summary);
1195 
1196         if (p<nonstd_bed_channel_assignment_masks.size())
1197         {
1198             Fill(Stream_Audio, StreamPos_Last, (P+" Channel(s)").c_str(), BedChannelConfiguration_ChannelCount(nonstd_bed_channel_assignment_masks[p]));
1199             Fill_SetOptions(Stream_Audio, 0, (P+" Channel(s)").c_str(), "Y NTY");
1200             Fill(Stream_Audio, 0, (P+" ChannelLayout").c_str(), AC3_nonstd_bed_channel_assignment_mask_ChannelLayout(nonstd_bed_channel_assignment_masks[p]));
1201             Fill_SetOptions(Stream_Audio, 0, (P+" ChannelLayout").c_str(), "Y NTY");
1202 
1203             // From OAMD
1204             if (Bed_Object_Count<ObjectElements.size() && !ObjectElements[Bed_Object_Count].Alts.empty())
1205             {
1206                 string A=P;
1207 
1208                 // Computing the count of objects in bed instances
1209                 size_t ThisBed_Object_Count=BedChannelConfiguration_ChannelCount(nonstd_bed_channel_assignment_masks[p]);
1210 
1211                 if (ThisBed_Object_Count)
1212                 {
1213                     // Check if all same
1214                     int8s obj_gain_db_Ref=ObjectElements[Bed_Object_Count].Alts[0].obj_gain_db;
1215                     for (size_t o=1; o<ThisBed_Object_Count; o++)
1216                     {
1217                         int8s obj_gain_db=ObjectElements[Bed_Object_Count+o].Alts[0].obj_gain_db;
1218                         if (obj_gain_db!=obj_gain_db_Ref)
1219                         {
1220                             obj_gain_db_Ref=INT8_MAX;
1221                             break;
1222                         }
1223                     }
1224                     if (obj_gain_db_Ref!=INT8_MAX)
1225                     {
1226                         // Same
1227                         if (obj_gain_db_Ref==INT8_MIN)
1228                             Fill_Measure(Stream_Audio, 0, (A+" Gain").c_str(), string("-infinite"), " dB");
1229                         else
1230                             Fill_Measure(Stream_Audio, 0, (A+" Gain").c_str(), obj_gain_db_Ref, " dB");
1231                     }
1232                     else
1233                     {
1234                         // Not same
1235                         for (size_t o=0; o<ThisBed_Object_Count; o++)
1236                         {
1237                             const dyn_object::dyn_object_alt& DynObject_Current=ObjectElements[Bed_Object_Count+o].Alts[0];
1238                             if (DynObject_Current.obj_gain_db!=INT8_MAX)
1239                             {
1240                                 if (DynObject_Current.obj_gain_db==INT8_MIN)
1241                                     Fill_Measure(Stream_Audio, 0, (A+" Gain").c_str(), string("-infinite"), " dB");
1242                                 else
1243                                     Fill_Measure(Stream_Audio, 0, (A+" Gain").c_str(), DynObject_Current.obj_gain_db, " dB");
1244                             }
1245                         }
1246                     }
1247 
1248                 }
1249                 Bed_Object_Count+=ThisBed_Object_Count;
1250             }
1251         }
1252 
1253         if (!BedInstance.Alts.empty())
1254         {
1255             Fill(Stream_Audio, 0, (P+" NumberOfAlts").c_str(), BedInstance.Alts.size());
1256             Fill_SetOptions(Stream_Audio, 0, (P+" NumberOfAlts").c_str(), "N NIY");
1257         }
1258         for (size_t a=0; a<BedInstance.Alts.size(); a++)
1259         {
1260             const bed_instance::bed_alt& BedInstance_Current=BedInstance.Alts[a];
1261 
1262             string Summary2;
1263             if (Summary2.empty())
1264                 Summary2="Yes";
1265 
1266             string A=P+Ztring(__T(" Alt")+Ztring::ToZtring(a)).To_UTF8();
1267             Fill(Stream_Audio, 0, A.c_str(), Summary2);
1268             if (BedInstance_Current.bed_gain_db!=INT8_MAX)
1269             {
1270                 Fill_Measure(Stream_Audio, 0, (A+" Gain").c_str(), BedInstance_Current.bed_gain_db, " dB");
1271             }
1272         }
1273 
1274         const substream_mapping& S=substream_mappings[DynObjects.size()+p];
1275         {
1276             Fill(Stream_Audio, 0, (P+" SubtstreamIdChannel").c_str(), Ztring::ToZtring(S.substream_id)+__T('-')+Ztring::ToZtring(S.channel_index));
1277             Fill_SetOptions(Stream_Audio, 0, (P+" SubtstreamIdChannel").c_str(), "Y NTY");
1278         }
1279     }
1280 
1281     // Dynamic objects
1282     for (size_t p=0; p<DynObjects.size(); p++)
1283     {
1284         const dyn_object& DynObject=DynObjects[p];
1285         string P=Ztring(__T("Object")+Ztring::ToZtring(p)).To_UTF8();
1286 
1287         // From OAMD
1288         Ztring Position_Cartesian;
1289         string Position_Polar;
1290         string ChannelLayout;
1291         if (Bed_Object_Count<ObjectElements.size() && p<ObjectElements.size()-Bed_Object_Count && !ObjectElements[Bed_Object_Count+p].Alts.empty())
1292         {
1293             string A=P;
1294             const dyn_object::dyn_object_alt& DynObject_Current=ObjectElements[Bed_Object_Count+p].Alts[0];
1295             if (DynObject_Current.pos3d_x_bits!=(int8u)-1)
1296             {
1297                 int x_32k=mgi_bitstream_val_to_Q15(DynObject_Current.pos3d_x_bits, 6);
1298                 int y_32k=mgi_bitstream_val_to_Q15(DynObject_Current.pos3d_y_bits, 6);
1299                 int z_32k=mgi_bitstream_pos_z_to_Q15(DynObject_Current.pos3d_z_sig, DynObject_Current.pos3d_z_bits);
1300                 Position_Cartesian=__T("x=")+Ztring::ToZtring((((float)x_32k)*2-32768)/32768, 1)+__T(" y=")+Ztring::ToZtring((((float)y_32k)*2-32768)/32768, 1)+__T(" z=")+Ztring::ToZtring(((float)z_32k)/32768, 1);
1301                 angles Angles=mgi_bitstream_pos_ToAngles(x_32k, y_32k, z_32k);
1302                 Position_Polar=Angles2String(Angles);
1303                 ChannelLayout=Angles2KnownChannelName(Angles);
1304                 if (ChannelLayout==Position_Polar)
1305                     ChannelLayout.clear();
1306             }
1307         }
1308 
1309         string Summary;
1310         if (Summary.empty())
1311             Summary=sound_category_Values[DynObject.sound_category];
1312         /*
1313         if (Summary.empty())
1314             Summary=ChannelLayout;
1315         if (Summary.empty())
1316             Summary=Position_Polar;
1317         */
1318         if (Summary.empty())
1319             Summary="Yes";
1320 
1321         Fill(Stream_Audio, 0, P.c_str(), Summary);
1322 
1323         if (sound_category_Values[DynObject.sound_category][0])
1324         {
1325             Fill(Stream_Audio, 0, (P+" SoundCategory").c_str(), sound_category_Values[DynObject.sound_category]);
1326             Fill_SetOptions(Stream_Audio, 0, (P+" SoundCategory").c_str(), "Y NTY");
1327         }
1328 
1329         // From OAMD
1330         if (Bed_Object_Count<ObjectElements.size() && p<ObjectElements.size()-Bed_Object_Count && !ObjectElements[Bed_Object_Count+p].Alts.empty())
1331         {
1332             string A=P;
1333             const dyn_object::dyn_object_alt& DynObject_Current=ObjectElements[Bed_Object_Count+p].Alts[0];
1334             /*
1335             if (!ChannelLayout.empty())
1336             {
1337                 Fill(Stream_Audio, 0, (A+" ChannelLayout").c_str(), ChannelLayout);
1338                 Fill_SetOptions(Stream_Audio, 0, (A+" ChannelLayout").c_str(), "Y NTY");
1339             }
1340             */
1341             if (!Position_Polar.empty())
1342             {
1343                 Fill(Stream_Audio, 0, (A+" Position_Polar").c_str(), Position_Polar);
1344                 Fill_SetOptions(Stream_Audio, 0, (A+" Position_Polar").c_str(), "Y NTY");
1345             }
1346             if (!Position_Cartesian.empty())
1347             {
1348                 Fill(Stream_Audio, 0, (A+" Position_Cartesian").c_str(), Position_Cartesian);
1349                 Fill_SetOptions(Stream_Audio, 0, (A+" Position_Cartesian").c_str(), "Y NTY");
1350             }
1351             if (DynObject_Current.obj_gain_db!=INT8_MAX)
1352             {
1353                 if (DynObject_Current.obj_gain_db==INT8_MIN)
1354                     Fill_Measure(Stream_Audio, 0, (A+" Gain").c_str(), string("-infinite"), " dB");
1355                 else
1356                     Fill_Measure(Stream_Audio, 0, (A+" Gain").c_str(), DynObject_Current.obj_gain_db, " dB");
1357             }
1358         }
1359 
1360         if (!DynObject.Alts.empty())
1361         {
1362             Fill(Stream_Audio, 0, (P+" NumberOfAlts").c_str(), DynObject.Alts.size());
1363             Fill_SetOptions(Stream_Audio, 0, (P+" NumberOfAlts").c_str(), "N NIY");
1364         }
1365         for (size_t a=0; a<DynObject.Alts.size(); a++)
1366         {
1367             const dyn_object::dyn_object_alt& DynObject_Current=DynObject.Alts[a];
1368             Ztring Position_Cartesian;
1369             string Position_Polar;
1370             string ChannelLayout;
1371             if (DynObject_Current.pos3d_x_bits!=(int8u)-1)
1372             {
1373                 int x_32k=mgi_bitstream_val_to_Q15(DynObject_Current.pos3d_x_bits, 6);
1374                 int y_32k=mgi_bitstream_val_to_Q15(DynObject_Current.pos3d_y_bits, 6);
1375                 int z_32k=mgi_bitstream_pos_z_to_Q15(DynObject_Current.pos3d_z_sig, DynObject_Current.pos3d_z_bits);
1376                 Position_Cartesian=__T("x=")+Ztring::ToZtring((((float)x_32k)*2-32768)/32768, 1)+__T(" y=")+Ztring::ToZtring((((float)y_32k)*2-32768)/32768, 1)+__T(" z=")+Ztring::ToZtring(((float)z_32k)/32768, 1);
1377                 angles Angles=mgi_bitstream_pos_ToAngles(x_32k, y_32k, z_32k);
1378                 Position_Polar=Angles2String(Angles);
1379                 ChannelLayout=Angles2KnownChannelName(Angles);
1380                 if (ChannelLayout==Position_Polar)
1381                     ChannelLayout.clear();
1382             }
1383             string Summary2;
1384             if (Summary2.empty())
1385                 Summary2=sound_category_Values[DynObject.sound_category];
1386             /*
1387             if (Summary2.empty())
1388                 Summary2=ChannelLayout;
1389             if (Summary2.empty())
1390                 Summary2=Position_Polar;
1391             */
1392             if (Summary2.empty())
1393                 Summary2="Yes";
1394 
1395             string A=P+Ztring(__T(" Alt")+Ztring::ToZtring(a)).To_UTF8();
1396             Fill(Stream_Audio, 0, A.c_str(), Summary2);
1397             /*
1398             if (!ChannelLayout.empty())
1399             {
1400                 Fill(Stream_Audio, 0, (A+" ChannelLayout").c_str(), ChannelLayout);
1401                 Fill_SetOptions(Stream_Audio, 0, (A+" ChannelLayout").c_str(), "Y NTY");
1402             }
1403             */
1404             if (!Position_Polar.empty())
1405             {
1406                 Fill(Stream_Audio, 0, (A+" Position_Polar").c_str(), Position_Polar);
1407                 Fill_SetOptions(Stream_Audio, 0, (A+" Position_Polar").c_str(), "Y NTY");
1408             }
1409             if (!Position_Cartesian.empty())
1410             {
1411                 Fill(Stream_Audio, 0, (A+" Position_Cartesian").c_str(), Position_Cartesian);
1412                 Fill_SetOptions(Stream_Audio, 0, (A+" Position_Cartesian").c_str(), "Y NTY");
1413             }
1414             if (DynObject_Current.obj_gain_db!=INT8_MAX)
1415             {
1416                 if (DynObject_Current.obj_gain_db==INT8_MIN)
1417                     Fill_Measure(Stream_Audio, 0, (A+" Gain").c_str(), string("-infinite"), " dB");
1418                 else
1419                     Fill_Measure(Stream_Audio, 0, (A+" Gain").c_str(), DynObject_Current.obj_gain_db, " dB");
1420             }
1421             if (DynObject_Current.hp_render_mode!=(int8u)-1)
1422             {
1423                 Fill(Stream_Audio, 0, (A+" RenderMode").c_str(), hp_render_mode_Values[DynObject_Current.hp_render_mode]);
1424                 Fill_SetOptions(Stream_Audio, 0, (P + " RenderMode").c_str(), "Y NTY");
1425             }
1426         }
1427 
1428         const substream_mapping& S=substream_mappings[p];
1429         {
1430             Fill(Stream_Audio, 0, (P+" SubtstreamIdChannel").c_str(), Ztring::ToZtring(S.substream_id)+__T('-')+Ztring::ToZtring(S.channel_index));
1431             Fill_SetOptions(Stream_Audio, 0, (P+" SubtstreamIdChannel").c_str(), "Y NTY");
1432         }
1433     }
1434 }
1435 
1436 //---------------------------------------------------------------------------
Streams_Finish()1437 void File_DolbyE::Streams_Finish()
1438 {
1439     if (FrameInfo.PTS!=(int64u)-1 && FrameInfo.PTS>PTS_Begin)
1440     {
1441         int64s Duration=float64_int64s(((float64)(FrameInfo.PTS-PTS_Begin))/1000000);
1442         int64s FrameCount;
1443         if (Mpegv_frame_rate[frame_rate_code])
1444             FrameCount=float64_int64s(((float64)(FrameInfo.PTS-PTS_Begin))/1000000000*Mpegv_frame_rate[frame_rate_code]);
1445         else
1446             FrameCount=0;
1447 
1448         for (size_t Pos=0; Pos<Count_Get(Stream_Audio); Pos++)
1449         {
1450             Fill(Stream_Audio, Pos, Audio_Duration, Duration);
1451             if (FrameCount)
1452                 Fill(Stream_Audio, Pos, Audio_FrameCount, FrameCount);
1453         }
1454     }
1455 }
1456 
1457 //***************************************************************************
1458 // Buffer - Synchro
1459 //***************************************************************************
1460 
1461 //---------------------------------------------------------------------------
Synchronize()1462 bool File_DolbyE::Synchronize()
1463 {
1464     //Synchronizing
1465     while (Buffer_Offset+3<=Buffer_Size)
1466     {
1467         if ((CC2(Buffer+Buffer_Offset_Temp)&0xFFFE)==0x078E) //16-bit
1468         {
1469             bit_depth=16;
1470             key_present=(CC2(Buffer+Buffer_Offset)&0x0001)?true:false;
1471             break; //while()
1472         }
1473         if ((CC3(Buffer+Buffer_Offset)&0xFFFFE0)==0x0788E0) //20-bit
1474         {
1475             bit_depth=20;
1476             key_present=(CC3(Buffer+Buffer_Offset)&0x000010)?true:false;
1477             break; //while()
1478         }
1479         if ((CC3(Buffer+Buffer_Offset)&0xFFFFFE)==0x07888E) //24-bit
1480         {
1481             bit_depth=24;
1482             key_present=(CC3(Buffer+Buffer_Offset)&0x000001)?true:false;
1483             break; //while()
1484         }
1485         Buffer_Offset++;
1486     }
1487 
1488     //Parsing last bytes if needed
1489     if (Buffer_Offset+3>Buffer_Size)
1490         return false;
1491 
1492     //Synched
1493     return true;
1494 }
1495 
1496 //---------------------------------------------------------------------------
Synched_Test()1497 bool File_DolbyE::Synched_Test()
1498 {
1499     //Must have enough buffer for having header
1500     if (Buffer_Offset+3>Buffer_Size)
1501         return false;
1502 
1503     //Quick test of synchro
1504     switch (bit_depth)
1505     {
1506         case 16 : if ((CC2(Buffer+Buffer_Offset)&0xFFFE  )!=0x078E  ) {Synched=false; return true;} break;
1507         case 20 : if ((CC3(Buffer+Buffer_Offset)&0xFFFFE0)!=0x0788E0) {Synched=false; return true;} break;
1508         case 24 : if ((CC3(Buffer+Buffer_Offset)&0xFFFFFE)!=0x07888E) {Synched=false; return true;} break;
1509         default : ;
1510     }
1511 
1512     //We continue
1513     return true;
1514 }
1515 
1516 //***************************************************************************
1517 // Buffer - Global
1518 //***************************************************************************
1519 
1520 //---------------------------------------------------------------------------
Read_Buffer_Unsynched()1521 void File_DolbyE::Read_Buffer_Unsynched()
1522 {
1523     description_text_Values.clear();
1524     num_desc_packets_m1=(int32u)-1;
1525     description_packet_data.clear();
1526 }
1527 
1528 //***************************************************************************
1529 // Buffer - Per element
1530 //***************************************************************************
1531 
1532 //---------------------------------------------------------------------------
Header_Parse()1533 void File_DolbyE::Header_Parse()
1534 {
1535     //Filling
1536     if (IsSub)
1537         Header_Fill_Size(Buffer_Size-Buffer_Offset);
1538     else
1539     {
1540         //Looking for synchro
1541         //Synchronizing
1542         Buffer_Offset_Temp=Buffer_Offset+3;
1543         if (bit_depth==16)
1544             while (Buffer_Offset_Temp+2<=Buffer_Size)
1545             {
1546                 if ((CC2(Buffer+Buffer_Offset_Temp)&0xFFFE)==0x078E) //16-bit
1547                     break; //while()
1548                 Buffer_Offset_Temp++;
1549             }
1550         if (bit_depth==20)
1551             while (Buffer_Offset_Temp+3<=Buffer_Size)
1552             {
1553                 if ((CC3(Buffer+Buffer_Offset_Temp)&0xFFFFE0)==0x0788E0) //20-bit
1554                     break; //while()
1555                 Buffer_Offset_Temp++;
1556             }
1557         if (bit_depth==24)
1558             while (Buffer_Offset_Temp+3<=Buffer_Size)
1559             {
1560                 if ((CC3(Buffer+Buffer_Offset_Temp)&0xFFFFFE)==0x07888E) //24-bit
1561                     break; //while()
1562                 Buffer_Offset_Temp++;
1563             }
1564 
1565         if (Buffer_Offset_Temp+(bit_depth>16?3:2)>Buffer_Size)
1566         {
1567             if (File_Offset+Buffer_Size==File_Size)
1568                 Buffer_Offset_Temp=Buffer_Size;
1569             else
1570             {
1571                 Element_WaitForMoreData();
1572                 return;
1573             }
1574         }
1575 
1576         Header_Fill_Size(Buffer_Offset_Temp-Buffer_Offset);
1577     }
1578     Header_Fill_Code(0, "Dolby_E_frame");
1579 }
1580 
1581 //---------------------------------------------------------------------------
Data_Parse()1582 void File_DolbyE::Data_Parse()
1583 {
1584     FrameSizes[Element_Size]++;
1585 
1586     //In case of scrambling
1587     const int8u*    Save_Buffer=NULL;
1588     size_t          Save_Buffer_Offset=0;
1589     int64u          Save_File_Offset=0;
1590     if (key_present)
1591     {
1592         //We must change the buffer,
1593         Save_Buffer=Buffer;
1594         Save_Buffer_Offset=Buffer_Offset;
1595         Save_File_Offset=File_Offset;
1596         File_Offset+=Buffer_Offset;
1597         Buffer_Offset=0;
1598         Descrambled_Buffer=new int8u[(size_t)Element_Size];
1599         std::memcpy(Descrambled_Buffer, Save_Buffer+Save_Buffer_Offset, (size_t)Element_Size);
1600         Buffer=Descrambled_Buffer;
1601     }
1602 
1603     //Parsing
1604     BS_Begin();
1605     sync_segment();
1606     metadata_segment();
1607     audio_segment();
1608     metadata_extension_segment();
1609     audio_extension_segment();
1610     meter_segment();
1611     BS_End();
1612 
1613     //Check if there is content in padding
1614     int16u Padding;
1615     if (Element_Size-Element_Offset>=2)
1616     {
1617         Peek_B2(Padding);
1618         if (Padding==0x5838)
1619             guard_band();
1620     }
1621 
1622     if (Element_Offset<Element_Size)
1623         Skip_XX(Element_Size-Element_Offset,                    "Unknown");
1624 
1625     //In case of scrambling
1626     if (key_present)
1627     {
1628         delete[] Buffer; Buffer=Save_Buffer;
1629         Buffer_Offset=Save_Buffer_Offset;
1630         File_Offset=Save_File_Offset;
1631     }
1632 
1633     FILLING_BEGIN();
1634         {
1635             //Guard band
1636             if (Mpegv_frame_rate[frame_rate_code])
1637             {
1638             int64u BytesPerSecond=96000*bit_depth/8;
1639             float64 BytesPerFrame=BytesPerSecond/Mpegv_frame_rate[frame_rate_code];
1640             int64u BytesUpToLastFrame;
1641             int64u BytesUpToNextFrame;
1642             for (;;)
1643             {
1644                 BytesUpToLastFrame=(int64u)(BytesPerFrame*Frame_Count);
1645                 BytesUpToLastFrame/=bit_depth/4;
1646                 BytesUpToLastFrame*=bit_depth/4;
1647                 BytesUpToNextFrame=(int64u)(BytesPerFrame*(Frame_Count+1));
1648                 BytesUpToNextFrame/=bit_depth/4;
1649                 BytesUpToNextFrame*=bit_depth/4;
1650 
1651                 if (BytesUpToLastFrame+GuardBand_Before<BytesUpToNextFrame)
1652                     break;
1653 
1654                 // In case previous frame was PCM
1655                 Frame_Count++;
1656                 GuardBand_Before-=BytesUpToNextFrame-BytesUpToLastFrame;
1657             }
1658             GuardBand_After=BytesUpToNextFrame-BytesUpToLastFrame;
1659             int64u ToRemove=GuardBand_Before+(bit_depth>>1)+Element_Size; // Guardband + AES3 header + Dolby E frame
1660             if (ToRemove<(int64u)GuardBand_After)
1661                 GuardBand_After-=ToRemove;
1662             else
1663                 GuardBand_After=0;
1664             GuardBand_After/=bit_depth/4;
1665             GuardBand_After*=bit_depth/4;
1666 
1667             Element_Info1(GuardBand_Before);
1668             float64 GuardBand_Before_Duration=((float64)GuardBand_Before)/BytesPerSecond;
1669             Ztring GuardBand_Before_String=__T("GuardBand_Begin ")+Ztring::ToZtring(GuardBand_Before)+__T(" (")+Ztring::ToZtring(GuardBand_Before_Duration*1000000, 0)+Ztring().From_UTF8(" \0xC20xB5s"); //0xC20xB5 = micro sign
1670             Element_Info1(GuardBand_Before_String);
1671             }
1672         }
1673 
1674         if (!Status[IsAccepted])
1675         {
1676             Accept("Dolby E");
1677             PTS_Begin=FrameInfo.PTS;
1678 
1679             //Guard band
1680             GuardBand_Before_Initial=GuardBand_Before;
1681             GuardBand_After_Initial=GuardBand_After;
1682         }
1683         Frame_Count++;
1684         if (Frame_Count_NotParsedIncluded!=(int64u)-1)
1685             Frame_Count_NotParsedIncluded++;
1686         if (Mpegv_frame_rate[frame_rate_code])
1687             FrameInfo.DUR=float64_int64s(1000000000/Mpegv_frame_rate[frame_rate_code]);
1688         else
1689             FrameInfo.DUR=(int64u)-1;
1690         if (FrameInfo.DTS!=(int64u)-1)
1691             FrameInfo.DTS+=FrameInfo.DUR;
1692         if (FrameInfo.PTS!=(int64u)-1)
1693             FrameInfo.PTS+=FrameInfo.DUR;
1694         if (!Status[IsFilled] && ((description_packet_data.empty() && description_text_Values.empty()) || Frame_Count>=32+1+1+32+1)) // max 32 chars (discarded) + ETX (discarded) + STX + max 32 chars + ETX
1695             Fill("Dolby E");
1696     FILLING_END();
1697     if (Frame_Count==0 && Buffer_TotalBytes>Buffer_TotalBytes_FirstSynched_Max)
1698         Reject("Dolby E");
1699 }
1700 
1701 //---------------------------------------------------------------------------
sync_segment()1702 void File_DolbyE::sync_segment()
1703 {
1704     //Parsing
1705     Element_Begin1("sync_segment");
1706     Skip_S3(bit_depth,                                      "sync_word");
1707     Element_End0();
1708 }
1709 
1710 //---------------------------------------------------------------------------
metadata_segment()1711 void File_DolbyE::metadata_segment()
1712 {
1713     //Parsing
1714     Element_Begin1("metadata_segment");
1715     if (key_present)
1716     {
1717         //We must change the buffer
1718         switch (bit_depth)
1719         {
1720             case 16 :
1721                         {
1722                         int16u metadata_key;
1723                         Get_S2 (16, metadata_key, "metadata_key");
1724                         int16u metadata_segment_size=((BigEndian2int16u(Buffer+Buffer_Offset+(size_t)Element_Size-Data_BS_Remain()/8)^metadata_key)>>2)&0x3FF;
1725 
1726                         if (Data_BS_Remain()<((size_t)metadata_segment_size+1)*(size_t)bit_depth) //+1 for CRC
1727                             return; //There is a problem
1728 
1729                         int8u* Temp=Descrambled_Buffer+(size_t)Element_Size-Data_BS_Remain()/8;
1730                         for (int16u Pos=0; Pos<metadata_segment_size+1; Pos++)
1731                             int16u2BigEndian(Temp+Pos*2, BigEndian2int16u(Temp+Pos*2)^metadata_key);
1732                         }
1733                         break;
1734             case 20 :
1735                         {
1736                         int32u metadata_key;
1737                         Get_S3 (20, metadata_key, "metadata_key");
1738                         int16u metadata_segment_size=((BigEndian2int16u(Buffer+Buffer_Offset+(size_t)Element_Size-Data_BS_Remain()/8)^(metadata_key>>4))>>2)&0x3FF;
1739 
1740                         if (Data_BS_Remain()<((size_t)metadata_segment_size+1)*(size_t)bit_depth) //+1 for CRC
1741                             return; //There is a problem
1742 
1743                         Descramble_20bit(metadata_key, metadata_segment_size);
1744                         }
1745                         break;
1746             case 24 :
1747                         {
1748                         int32u metadata_key;
1749                         Get_S3 (24, metadata_key, "metadata_key");
1750                         int32u metadata_segment_size=((BigEndian2int16u(Buffer+Buffer_Offset+(size_t)Element_Size-Data_BS_Remain()/8)^metadata_key)>>2)&0x3FF;
1751 
1752                         if (Data_BS_Remain()<((size_t)metadata_segment_size+1)*bit_depth) //+1 for CRC
1753                             return; //There is a problem
1754 
1755                         int8u* Temp=Descrambled_Buffer+(size_t)Element_Size-Data_BS_Remain()/8;
1756                         for (int16u Pos=0; Pos<metadata_segment_size+1; Pos++)
1757                             int24u2BigEndian(Temp+Pos*2, BigEndian2int24u(Temp+Pos*2)^metadata_key);
1758                         }
1759                         break;
1760             default :   ;
1761         }
1762     }
1763     size_t  metadata_segment_BitCountAfter=Data_BS_Remain();
1764     int16u  metadata_segment_size;
1765     Skip_S1( 4,                                                 "metadata_revision_id");
1766     Get_S2 (10, metadata_segment_size,                          "metadata_segment_size");
1767     metadata_segment_BitCountAfter-=metadata_segment_size*bit_depth;
1768     Get_S1 ( 6, program_config,                                 "program_config"); Param_Info1(DolbyE_ChannelPositions[program_config]);
1769     Get_S1 ( 4, frame_rate_code,                                "frame_rate_code"); Param_Info3(Mpegv_frame_rate[frame_rate_code], " fps", 3);
1770     Info_S1( 4, original_frame_rate_code,                       "original_frame_rate_code"); Param_Info3(Mpegv_frame_rate[original_frame_rate_code], " fps", 3);
1771     Skip_S2(16,                                                 "frame_count");
1772     Element_Begin1("SMPTE_time_code");
1773     int8u Frames_Units, Frames_Tens, Seconds_Units, Seconds_Tens, Minutes_Units, Minutes_Tens, Hours_Units, Hours_Tens;
1774     bool  DropFrame;
1775 
1776     Skip_S1(4,                                                  "BG8");
1777     Skip_S1(4,                                                  "BG7");
1778 
1779     Skip_SB(                                                    "BGF2 / Field Phase");
1780     Skip_SB(                                                    "BGF1");
1781     Get_S1 (2, Hours_Tens,                                      "Hours (Tens)");
1782     Get_S1 (4, Hours_Units,                                     "Hours (Units)");
1783 
1784     Skip_S1(4,                                                  "BG6");
1785     Skip_S1(4,                                                  "BG5");
1786 
1787     Skip_SB(                                                    "BGF0 / BGF2");
1788     Get_S1 (3, Minutes_Tens,                                    "Minutes (Tens)");
1789     Get_S1 (4, Minutes_Units,                                   "Minutes (Units)");
1790 
1791     Skip_S1(4,                                                  "BG4");
1792     Skip_S1(4,                                                  "BG3");
1793 
1794     Skip_SB(                                                    "FP - Field Phase / BGF0");
1795     Get_S1 (3, Seconds_Tens,                                    "Seconds (Tens)");
1796     Get_S1 (4, Seconds_Units,                                   "Seconds (Units)");
1797 
1798     Skip_S1(4,                                                  "BG2");
1799     Skip_S1(4,                                                  "BG1");
1800 
1801     Skip_SB(                                                    "CF - Color fame");
1802     Get_SB (   DropFrame,                                       "DP - Drop frame");
1803     Get_S1 (2, Frames_Tens,                                     "Frames (Tens)");
1804     Get_S1 (4, Frames_Units,                                    "Frames (Units)");
1805 
1806     if (Hours_Tens<3)
1807     {
1808         int64u TimeCode=(int64u)(Hours_Tens     *10*60*60*1000
1809                                + Hours_Units       *60*60*1000
1810                                + Minutes_Tens      *10*60*1000
1811                                + Minutes_Units        *60*1000
1812                                + Seconds_Tens         *10*1000
1813                                + Seconds_Units           *1000
1814                                + (Mpegv_frame_rate[frame_rate_code]?float64_int32s((Frames_Tens*10+Frames_Units)*1000/Mpegv_frame_rate[frame_rate_code]):0));
1815 
1816         Element_Info1(Ztring().Duration_From_Milliseconds(TimeCode));
1817 
1818         //TimeCode
1819         if (SMPTE_time_code_StartTimecode==(int64u)-1)
1820             SMPTE_time_code_StartTimecode=TimeCode;
1821     }
1822     Element_End0();
1823     bool evolution_data_exists;
1824     Get_SB (    evolution_data_exists,                          "evolution_data_exists");
1825     Skip_S1( 7,                                                 "metadata_reserved_bits");
1826     for (int8u Channel=0; Channel<DolbyE_Channels[program_config]; Channel++)
1827     {
1828         Get_S2 (10, channel_subsegment_size[Channel],           "channel_subsegment_size");
1829         channel_subsegment_sizes[Channel][channel_subsegment_size[Channel]]++;
1830     }
1831     if (!Mpegv_frame_rate_type[frame_rate_code])
1832         Get_S1 ( 8, metadata_extension_segment_size,            "metadata_extension_segment_size");
1833     else
1834         metadata_extension_segment_size=0;
1835     Get_S1 ( 8, meter_segment_size,                             "meter_segment_size");
1836     for (int8u Program=0; Program<DolbyE_Programs[program_config]; Program++)
1837     {
1838         Element_Begin1("per program");
1839         int8u description_text;
1840         Get_S1 ( 8, description_text,                           "description_text"); Element_Info1(description_text);
1841         Info_S1( 2, bandwidth_id,                               "bandwidth_id"); Element_Info1(bandwidth_id);
1842         if (description_text && Program>=description_text_Values.size())
1843             description_text_Values.resize(Program+1);
1844         switch (description_text)
1845         {
1846             case 0x00: // No text
1847                     if (Program<description_text_Values.size())
1848                     {
1849                         description_text_Values[Program].Previous.clear();
1850                         description_text_Values[Program].Current.clear();
1851                     }
1852                     break;
1853             case 0x02: // STX
1854                     description_text_Values[Program].Current.clear();
1855                     description_text_Values[Program].Current.push_back(description_text);
1856                     break;
1857             case 0x03: // ETX
1858                     if (!description_text_Values[Program].Current.empty() && description_text_Values[Program].Current[0]==0x02)
1859                         description_text_Values[Program].Previous= description_text_Values[Program].Current.substr(1);
1860                     else
1861                         description_text_Values[Program].Previous.clear();
1862                     description_text_Values[Program].Current.clear();
1863                     break;
1864             default: if (description_text>=0x20 && description_text<=0x7E)
1865                         description_text_Values[Program].Current.push_back(description_text);
1866         }
1867         Element_End0();
1868     }
1869     for (int8u Channel=0; Channel<DolbyE_Channels[program_config]; Channel++)
1870     {
1871         Element_Begin1("per channel");
1872         Info_S1( 4, revision_id,                                "revision_id"); Element_Info1(revision_id);
1873         Info_SB(    bitpool_type,                               "bitpool_type");
1874         Info_S2(10, begin_gain,                                 "begin_gain"); Element_Info1(begin_gain);
1875         Info_S2(10, end_gain,                                   "end_gain"); Element_Info1(end_gain);
1876         Element_End0();
1877     }
1878     for(;;)
1879     {
1880         Element_Begin1("metadata_subsegment");
1881         int16u  metadata_subsegment_length;
1882         int8u   metadata_subsegment_id;
1883         Get_S1 ( 4, metadata_subsegment_id,                     "metadata_subsegment_id");
1884         if (metadata_subsegment_id==0)
1885         {
1886             Element_End0();
1887             break;
1888         }
1889         Get_S2 (12, metadata_subsegment_length,                 "metadata_subsegment_length");
1890         size_t End=Data_BS_Remain()-metadata_subsegment_length;
1891         switch (metadata_subsegment_id)
1892         {
1893             case 1 : ac3_metadata_subsegment(true); break;
1894             case 2 : ac3_metadata_subsegment(false); break;
1895             default: Skip_BS(metadata_subsegment_length,        "metadata_subsegment (unknown)");
1896         }
1897         if (Data_BS_Remain()>End)
1898             Skip_BS(Data_BS_Remain()-End,                       "unknown");
1899         Element_End0();
1900     }
1901     if (evolution_data_exists)
1902     {
1903         for (;;)
1904         {
1905             const size_t evolution_data_segment_id_Name_Size=2;
1906             const char* const evolution_data_segment_id_Name[evolution_data_segment_id_Name_Size]=
1907             {
1908                 "End",
1909                 "intelligent_loudness_evolution_data_segment",
1910             };
1911 
1912             Element_Begin1("evolution_data_segment");
1913             int16u evolution_data_segment_length;
1914             int8u evolution_data_segment_id;
1915             Get_S1 ( 4, evolution_data_segment_id,              "evolution_data_segment_id"); Param_Info1C(evolution_data_segment_id<evolution_data_segment_id_Name_Size, evolution_data_segment_id_Name[evolution_data_segment_id]);
1916             if (!evolution_data_segment_id)
1917             {
1918                 Element_End0();
1919                 break;
1920             }
1921             Get_S2 (12, evolution_data_segment_length,          "evolution_data_segment_length");
1922             size_t End=Data_BS_Remain()-evolution_data_segment_length;
1923             switch (evolution_data_segment_id)
1924             {
1925                 case  1: intelligent_loudness_evolution_data_segment(); break;
1926                 default: Skip_BS(evolution_data_segment_length, "evolution_data_segment (unknown)");
1927             }
1928             if (Data_BS_Remain()>End)
1929                 Skip_BS(Data_BS_Remain()-End,                   "unknown");
1930             Element_End0();
1931         }
1932     }
1933     if (Data_BS_Remain()>metadata_segment_BitCountAfter)
1934         Skip_BS(Data_BS_Remain()-metadata_segment_BitCountAfter,"reserved_metadata_bits");
1935     Skip_S3(bit_depth,                                          "metadata_crc");
1936 
1937     {
1938         //CRC test
1939         size_t Pos_End=Buffer_Offset*8+(size_t)Element_Size*8-Data_BS_Remain();
1940         size_t Pos_Begin=Pos_End-(metadata_segment_size+1)*bit_depth; //+1 for CRC
1941         int8u BitSkip_Begin=Pos_Begin%8;
1942         Pos_Begin/=8;
1943         int8u BitSkip_End=0; // Pos_End%8; Looks like that the last bits must not be in the CRC computing
1944         Pos_End/=8;
1945         if (BitSkip_End)
1946             Pos_End++;
1947 
1948         int16u CRC=CRC_16_Compute(Buffer+Pos_Begin, Pos_End-Pos_Begin, BitSkip_Begin, BitSkip_End);
1949         if (CRC)
1950         {
1951             // CRC is wrong
1952             Param_Info1("metadata_crc NOK");
1953         }
1954     }
1955 
1956     Element_End0();
1957 }
1958 
1959 //---------------------------------------------------------------------------
guard_band()1960 void File_DolbyE::guard_band()
1961 {
1962     int8u* NewBuffer=NULL;
1963     size_t Buffer_Offset_Save;
1964     size_t Buffer_Size_Save;
1965     int64u Element_Offset_Save;
1966     int64u Element_Size_Save;
1967 
1968     Element_Begin1("guard_band (with data)");
1969     int16u element_length;
1970     int8u element_id;
1971     bool escape_code_valid;
1972     Skip_B2(                                                    "sync_word");
1973     BS_Begin();
1974     Skip_S1( 3,                                                 "reserved");
1975     Get_SB (    escape_code_valid,                              "escape_code_valid");
1976     if (escape_code_valid)
1977     {
1978         int16u escape_code;
1979         Get_S2 (12, escape_code,                                 "escape_code");
1980         BS_End();
1981         for (int64u i=Element_Offset; i+1<Element_Size; i++)
1982         {
1983             if ( Buffer[Buffer_Offset+i  ]     ==(escape_code>>4) && (Buffer[Buffer_Offset+i+1]>>4)==(escape_code&0x0F))
1984             {
1985                 //0xABCD --> 0x078D
1986                 if (!NewBuffer)
1987                 {
1988                     NewBuffer=new int8u[Element_Size-Element_Offset];
1989                     memcpy(NewBuffer, Buffer+Buffer_Offset+Element_Offset, Element_Size-Element_Offset);
1990                 }
1991                 NewBuffer[i  -Element_Offset]=0x07;
1992                 NewBuffer[i+1-Element_Offset]=(NewBuffer[i+1-Element_Offset]&0x0F)|0x80;
1993             }
1994             if ((Buffer[Buffer_Offset+i  ]&0xF)==(escape_code>>8) &&  Buffer[Buffer_Offset+i+1]    ==(escape_code&0xFF))
1995             {
1996                 //0xABCD --> 0xA078
1997                 if (!NewBuffer)
1998                 {
1999                     NewBuffer=new int8u[Element_Size-Element_Offset];
2000                     memcpy(NewBuffer, Buffer+Buffer_Offset+Element_Offset, Element_Size-Element_Offset);
2001                 }
2002                 NewBuffer[i  -Element_Offset]=(NewBuffer[i  -Element_Offset]&0xF0);
2003                 NewBuffer[i+1-Element_Offset]=0x78;
2004             }
2005         }
2006         if (NewBuffer)
2007         {
2008             Buffer=NewBuffer;
2009             Buffer_Offset_Save=Buffer_Offset;
2010             Buffer_Size_Save=Buffer_Offset;
2011             Element_Offset_Save=Element_Offset;
2012             Element_Size_Save=Element_Size;
2013             File_Offset+=Buffer_Offset+Element_Offset;
2014             Buffer_Offset=0;
2015             Buffer_Size=Element_Size-Element_Offset;
2016             Element_Offset=0;
2017             Element_Size=Buffer_Size;
2018         }
2019     }
2020     else
2021     {
2022         Skip_S2(12,                                             "escape_code");
2023         BS_End();
2024     }
2025     Get_B1 (    element_id,                                     "element_id");
2026     Get_B2 (    element_length,                                 "element_length");
2027     int64u After=Element_Offset+element_length;
2028     switch (element_id)
2029     {
2030         case 0xBB: evo_frame(); break;
2031         default: Skip_XX(element_length,                        "Unknown");
2032     }
2033     if (Element_Offset<After)
2034         Skip_XX(After-Element_Offset,                           "Unknown");
2035     else if (Element_Offset>After)
2036     {
2037         Param_Info1("Problem");
2038         Element_Offset=After;
2039     }
2040     Skip_B2(                                                    "crc");
2041     {
2042         //CRC test
2043         size_t Pos_End=Buffer_Offset+Element_Offset;
2044         size_t Pos_Begin=Pos_End-(element_length+2); //+2 for CRC
2045 
2046         int16u CRC=CRC_16_Compute(Buffer+Pos_Begin, Pos_End-Pos_Begin, 0, 0);
2047         if (CRC)
2048         {
2049             // CRC is wrong
2050             Param_Info1("crc NOK");
2051         }
2052         Element_End0();
2053         int64u RemainingBytes=Element_Size-Element_Offset;
2054         if (RemainingBytes && RemainingBytes<bit_depth/4)
2055         {
2056             bool HasContent=false;
2057             size_t Offset=Buffer_Offset+(size_t)Element_Offset;
2058             size_t Size=Buffer_Offset+(size_t)Element_Size;
2059             for (; Offset<Size; Offset++)
2060                 if (Buffer[Offset])
2061                     HasContent=true;
2062             if (!HasContent)
2063                 Skip_XX(Element_Size-Element_Offset,            "Padding");
2064         }
2065     }
2066 
2067     if (NewBuffer)
2068     {
2069         delete[] Buffer;
2070         Buffer_Offset=Buffer_Offset_Save;
2071         Buffer_Size=Buffer_Offset_Save;
2072         Element_Offset=Element_Offset_Save;
2073         Element_Size=Element_Size_Save;
2074         File_Offset-=Buffer_Offset+Element_Offset;
2075     }
2076 }
2077 
2078 //---------------------------------------------------------------------------
intelligent_loudness_evolution_data_segment()2079 void File_DolbyE::intelligent_loudness_evolution_data_segment()
2080 {
2081     Element_Begin1("intelligent_loudness_evolution_data_segment");
2082     for (int8u program=0; program<DolbyE_Programs[program_config]; program++)
2083     {
2084         Element_Begin1("per program");
2085         Skip_S1(4,                                          "loudness_reg_type");
2086         Skip_SB(                                            "dialogue_corrected");
2087         Skip_S1(1,                                          "loudness_corr_type");
2088         Element_End0();
2089     }
2090     Element_End0();
2091 }
2092 
2093 //---------------------------------------------------------------------------
2094 extern const char* Ac3_emdf_payload_id[16];
evo_frame()2095 void File_DolbyE::evo_frame()
2096 {
2097     if (!Guardband_EMDF_PresentAndSize)
2098         Guardband_EMDF_PresentAndSize=Element_Size;
2099 
2100     Element_Begin1("evo_frame");
2101     BS_Begin();
2102     int8u evo_version, key_id;
2103     Get_S1 (2, evo_version,                                     "evo_version");
2104     if (evo_version==3)
2105     {
2106         int32u evo_version32;
2107         Get_V4 (2, evo_version32,                               "evo_version");
2108         evo_version32+=3;
2109         evo_version=(int8u)evo_version32;
2110     }
2111     if (evo_version)
2112     {
2113         Skip_BS(Data_BS_Remain(),                               "(Unparsed evo_frame data)");
2114         Element_End0();
2115         return;
2116     }
2117     Get_S1 (3, key_id,                                          "key_id");
2118     if (key_id==7)
2119         Skip_V4(3,                                              "key_id");
2120 
2121     int32u payload_id = 0;
2122 
2123     for(;;)
2124     {
2125         Element_Begin1("evo_payload");
2126         Get_S4 (5, payload_id,                                  "payload_id");
2127         if (payload_id==0x1F)
2128         {
2129             int32u add;
2130             Get_V4 (5, add,                                     "payload_id");
2131             payload_id += add;
2132         }
2133 
2134         if (payload_id<16)
2135             Element_Info1(Ac3_emdf_payload_id[payload_id]);
2136         if (!payload_id)
2137         {
2138             Element_End0();
2139             break;
2140         }
2141 
2142         evo_payload_config();
2143 
2144         int32u payload_size = 0;
2145         Get_V4 (8, payload_size,                                "payload_size");
2146         size_t payload_End=(Data_BS_Remain()>payload_size*8)?(Data_BS_Remain()-payload_size*8):0;
2147 
2148         Element_Begin1("payload");
2149             switch (payload_id)
2150             {
2151                 case 11: object_audio_metadata_payload(); break;
2152                 case 13: mgi_payload(); break;
2153                 default: Skip_BS(payload_size*8,                "(Unknown)");
2154             }
2155             size_t Remaining=Data_BS_Remain()-payload_End;
2156             if (Remaining && Remaining<8)
2157             {
2158                 int8u padding;
2159                 Peek_S1(Remaining, padding);
2160                 if (!padding)
2161                     Skip_S1(Remaining,                          "padding");
2162             }
2163             if (Data_BS_Remain()>payload_End)
2164             {
2165                 Skip_BS(Data_BS_Remain()-payload_End,           "(Unparsed payload bytes)");
2166             }
2167             else if (Data_BS_Remain()<payload_End)
2168             {
2169                 //There is a problem, too many bits were consumed by the parser. //TODO: prevent the parser to consume more bits than count of bits in this element
2170                 if (Data_BS_Remain()>=payload_End)
2171                     Skip_BS(Data_BS_Remain()-payload_End,       "(Problem during emdf_payload parsing)");
2172                 else
2173                     Skip_BS(Data_BS_Remain(),                   "(Problem during payload parsing, going to end directly)");
2174                 Element_End0();
2175                 Element_End0();
2176                 break;
2177             }
2178         Element_End0();
2179         Element_End0();
2180     }
2181 
2182     evo_protection();
2183     BS_End();
2184     Element_End0();
2185 }
2186 
2187 //---------------------------------------------------------------------------
evo_payload_config()2188 void File_DolbyE::evo_payload_config()
2189 {
2190     Element_Begin1("payload_config");
2191     bool timestamp_present;
2192     TEST_SB_GET (timestamp_present,                             "timestamp_present");
2193         Skip_V4(11,                                             "timestamp");
2194     TEST_SB_END();
2195     TEST_SB_SKIP(                                               "duration_present");
2196         Skip_V4(11,                                             "duration");
2197     TEST_SB_END();
2198     TEST_SB_SKIP(                                               "group_id_present");
2199         Skip_V4(2,                                              "group_id");
2200     TEST_SB_END();
2201     TEST_SB_SKIP(                                               "codec_specific_id_present");
2202         Skip_S1(8,                                              "codec_specific_id");
2203     TEST_SB_END();
2204 
2205     bool dont_transcode;
2206     Get_SB(dont_transcode,                                      "dont_transcode");
2207     if (!dont_transcode)
2208     {
2209         bool now_or_never = false;
2210         if (!timestamp_present)
2211         {
2212             Get_SB (now_or_never,                               "now_or_never");
2213             if (now_or_never)
2214             {
2215                 Skip_SB(                                        "create_duplicate");
2216                 Skip_SB(                                        "remove_duplicate");
2217 
2218             }
2219         }
2220 
2221         if (timestamp_present || now_or_never)
2222         {
2223             Skip_S1(5,                                          "priority");
2224             Skip_S1(2,                                          "tight_coupling");
2225         }
2226     }
2227     Element_End0();
2228 }
2229 
2230 //---------------------------------------------------------------------------
evo_protection()2231 void File_DolbyE::evo_protection()
2232 {
2233     Element_Begin1("protection");
2234     int8u len_primary, len_second;
2235     Get_S1(2, len_primary,                                      "protection_length_primary");
2236     Get_S1(2, len_second,                                       "protection_length_secondary");
2237 
2238     switch (len_primary)
2239     {
2240         case 0: len_primary = 0; break;
2241         case 1: len_primary = 8; break;
2242         case 2: len_primary = 32; break;
2243         case 3: len_primary = 128; break;
2244         default:; //Cannot append, read only 2 bits
2245     };
2246     switch (len_second)
2247     {
2248         case 0: len_second = 0; break;
2249         case 1: len_second = 8; break;
2250         case 2: len_second = 32; break;
2251         case 3: len_second = 128; break;
2252         default:; //Cannot append, read only 2 bits
2253     };
2254     Skip_BS(len_primary,                                        "protection_bits_primary");
2255     if (len_second)
2256         Skip_BS(len_primary,                                    "protection_bits_secondary");
2257 
2258     Element_End0();
2259 }
2260 
2261 
2262 //---------------------------------------------------------------------------
object_audio_metadata_payload()2263 void File_DolbyE::object_audio_metadata_payload()
2264 {
2265     nonstd_bed_channel_assignment_masks.clear();
2266     ObjectElements.clear();
2267 
2268     Element_Begin1("object_audio_metadata_payload");
2269     int8u oa_md_version_bits;
2270     Get_S1 (2, oa_md_version_bits,                              "oa_md_version_bits");
2271     if (oa_md_version_bits == 0x3)
2272     {
2273         int8u oa_md_version_bits_ext;
2274         Get_S1 (3, oa_md_version_bits_ext,                      "oa_md_version_bits_ext");
2275         oa_md_version_bits += oa_md_version_bits_ext;
2276     }
2277 
2278     int8u object_count_bits;
2279     Get_S1 (5, object_count_bits,                               "object_count_bits");
2280     if (object_count_bits==0x1F)
2281     {
2282         int8u object_count_bits_ext;
2283         Get_S1 (7, object_count_bits_ext,                       "object_count_bits_ext");
2284         object_count_bits=0x1F+object_count_bits_ext;
2285     }
2286     object_count=object_count_bits+1;
2287     Param_Info2(object_count, " objects");
2288 
2289     program_assignment();
2290 
2291     bool b_alternate_object_data_present;
2292     Get_SB(b_alternate_object_data_present,                     "b_alternate_object_data_present");
2293     int8u oa_element_count_bits;
2294     Get_S1(4, oa_element_count_bits,                            "oa_element_count_bits");
2295     if (oa_element_count_bits==0xF)
2296     {
2297         Get_S1(5, oa_element_count_bits,                        "oa_element_count_bits_ext");
2298         oa_element_count_bits+=0xF;
2299     }
2300     for (int8u i=0; i<oa_element_count_bits; i++)
2301         oa_element_md(b_alternate_object_data_present);
2302 
2303     Element_End0();
2304 }
2305 
program_assignment()2306 void File_DolbyE::program_assignment()
2307 {
2308     Element_Begin1("program_assignment");
2309     bool b_dyn_object_only_program = false;
2310     Get_SB (b_dyn_object_only_program,                          "b_dyn_object_only_program");
2311     if (b_dyn_object_only_program)
2312     {
2313         bool b_lfe_present;
2314         Get_SB (b_lfe_present,                                  "b_lfe_present");
2315         if (b_lfe_present)
2316         {
2317             nonstd_bed_channel_assignment_masks.push_back(1<<3);
2318             b_object_in_bed_or_isf.push_back(true);
2319         }
2320     }
2321     else
2322     {
2323         int8u content_description_mask;
2324         Get_S1 (4, content_description_mask,                    "content_description_mask");
2325         if (content_description_mask & 0x1)
2326         {
2327             bool b_bed_object_chan_distribute, b_multiple_bed_instances_present;
2328 
2329             Get_SB (b_bed_object_chan_distribute,               "b_bed_object_chan_distribute");
2330             Get_SB (b_multiple_bed_instances_present,           "b_multiple_bed_instances_present");
2331             int32u num_bed_instances = 1;
2332             if (b_multiple_bed_instances_present)
2333             {
2334                 int8u num_bed_instances_bits = 0;
2335                 Get_S1 (3, num_bed_instances_bits,              "num_bed_instances_bits");
2336                 num_bed_instances = num_bed_instances_bits + 2;
2337             }
2338 
2339             for (int32u bed = 0; bed < num_bed_instances; ++bed)
2340             {
2341                 Element_Begin1("Bed");
2342                 bool b_lfe_only = true;
2343                 Get_SB (b_lfe_only,                             "b_lfe_only");
2344                 if (!b_lfe_only)
2345                 {
2346                     bool b_standard_chan_assign;
2347                     Get_SB (b_standard_chan_assign,             "b_standard_chan_assign");
2348                     int32u nonstd_bed_channel_assignment_mask;
2349                     if (b_standard_chan_assign)
2350                     {
2351                         int16u bed_channel_assignment_mask;
2352                         Get_S2 (10, bed_channel_assignment_mask, "bed_channel_assignment_mask");
2353                         nonstd_bed_channel_assignment_mask=AC3_bed_channel_assignment_mask_2_nonstd(bed_channel_assignment_mask);
2354                     }
2355                     else
2356                     {
2357                         int32u nonstd_bed_channel_assignment_mask;
2358                         Get_S3 (17, nonstd_bed_channel_assignment_mask, "nonstd_bed_channel_assignment_mask");
2359                     }
2360                     Param_Info1(AC3_nonstd_bed_channel_assignment_mask_ChannelLayout(nonstd_bed_channel_assignment_mask));
2361                     nonstd_bed_channel_assignment_masks.push_back(nonstd_bed_channel_assignment_mask);
2362                     size_t BedChannelCount=BedChannelConfiguration_ChannelCount(nonstd_bed_channel_assignment_mask);
2363                     b_object_in_bed_or_isf.resize(b_object_in_bed_or_isf.size()+BedChannelCount, true);
2364                 }
2365                 else
2366                     b_object_in_bed_or_isf.push_back(true);
2367                 Element_End0();
2368             }
2369         }
2370 
2371         if (content_description_mask & 0x2)
2372         {
2373             int8u intermediate_spatial_format_idx;
2374             Get_S1 (3, intermediate_spatial_format_idx,        "intermediate_spatial_format_idx");
2375             b_object_in_bed_or_isf.resize(b_object_in_bed_or_isf.size()+intermediate_spatial_format_object_count[intermediate_spatial_format_idx], true);
2376         }
2377 
2378         if (content_description_mask & 0x4)
2379         {
2380             int8u num_dynamic_objects_bits;
2381             Get_S1(5, num_dynamic_objects_bits,                 "num_dynamic_objects_bits");
2382             if (num_dynamic_objects_bits==0x1F)
2383             {
2384                 int8u num_dynamic_objects_bits_ext = 0;
2385                 Get_S1 (7, num_dynamic_objects_bits_ext,        "num_dynamic_objects_bits_ext");
2386                 num_dynamic_objects_bits=0x1F+num_dynamic_objects_bits_ext;
2387             }
2388             num_dynamic_objects_bits++;
2389             Param_Info2(object_count-num_dynamic_objects_bits, " static objects");
2390             Param_Info2(num_dynamic_objects_bits, " dynamic objects");
2391             b_object_in_bed_or_isf.resize(b_object_in_bed_or_isf.size()+num_dynamic_objects_bits, false);
2392         }
2393 
2394         if (content_description_mask & 0x8)
2395         {
2396             int8u reserved_data_size_bits;
2397             Get_S1 (4, reserved_data_size_bits,                 "reserved_data_size_bits");
2398             int8u padding = 8 - (reserved_data_size_bits % 8);
2399             Skip_S1(reserved_data_size_bits,                    "reserved_data()");
2400             Skip_S1(padding,                                    "padding");
2401         }
2402     }
2403 
2404     Element_End0();
2405 }
2406 
oa_element_md(bool b_alternate_object_data_present)2407 void File_DolbyE::oa_element_md(bool b_alternate_object_data_present)
2408 {
2409     Element_Begin1("oa_element_md");
2410     int8u oa_element_id_idx;
2411     int32u oa_element_size_bits;
2412     Get_S1 (4, oa_element_id_idx,                               "oa_element_id_idx");
2413     Get_V4 (4, 4, oa_element_size_bits,                         "oa_element_size_bits");
2414     oa_element_size_bits++;
2415     oa_element_size_bits*=8;
2416     int32u b_alternate_object_data_present_Reduced=b_alternate_object_data_present*4+1;
2417     if (oa_element_size_bits<b_alternate_object_data_present_Reduced || oa_element_size_bits>Data_BS_Remain())
2418     {
2419         Skip_BS(oa_element_size_bits,                           "?");
2420         Element_End0();
2421         return;
2422     }
2423     oa_element_size_bits-=b_alternate_object_data_present_Reduced;
2424     if (b_alternate_object_data_present)
2425         Skip_S1(4,                                              "alternate_object_data_id_idx");
2426     Skip_SB(                                                    "b_discard_unknown_element");
2427     size_t End=Data_BS_Remain()-oa_element_size_bits;
2428     switch (oa_element_id_idx)
2429     {
2430         case  1: object_element(); break;
2431         default: Skip_BS(oa_element_size_bits,                  "oa_element");
2432     }
2433     if (Data_BS_Remain()>End)
2434         Skip_BS(Data_BS_Remain()-End,                           "padding");
2435     Element_End0();
2436 }
2437 
object_element()2438 void File_DolbyE::object_element()
2439 {
2440     Element_Begin1("object_element");
2441     int8u num_obj_info_blocks_bits;
2442     md_update_info(num_obj_info_blocks_bits);
2443     bool b_reserved_data_not_present;
2444     Get_SB (b_reserved_data_not_present,                        "b_reserved_data_not_present");
2445     if (!b_reserved_data_not_present)
2446         Skip_S1(5,                                              "reserved");
2447     for (int8u i=0; i<object_count; i++)
2448         object_data(i, num_obj_info_blocks_bits);
2449     Element_End0();
2450 }
2451 
md_update_info(int8u & num_obj_info_blocks_bits)2452 void File_DolbyE::md_update_info(int8u& num_obj_info_blocks_bits)
2453 {
2454     Element_Begin1("md_update_info");
2455     int8u sample_offset_code;
2456     Get_S1 (2, sample_offset_code,                              "sample_offset_code");
2457     switch (sample_offset_code)
2458     {
2459         case 1 : Skip_S1(2,                                     "sample_offset_idx"); break;
2460         case 2 : Skip_S1(5,                                     "sample_offset_bits"); break;
2461         default:;
2462     }
2463     Get_S1 (3, num_obj_info_blocks_bits,                        "num_obj_info_blocks_bits");
2464     for (int8u blk=0; blk<=num_obj_info_blocks_bits; blk++)
2465         block_update_info();
2466     Element_End0();
2467 }
2468 
block_update_info()2469 void File_DolbyE::block_update_info()
2470 {
2471     Element_Begin1("block_update_info");
2472     int8u block_offset_factor_bits, ramp_duration_code;
2473     Get_S1 (6, block_offset_factor_bits,                        "block_offset_factor_bits");
2474     Get_S1 (2, ramp_duration_code,                              "ramp_duration_code");
2475     switch (ramp_duration_code)
2476     {
2477         case 3 :
2478                 {
2479                     bool b_use_ramp_duration_idx;
2480                     Get_SB (b_use_ramp_duration_idx,            "b_use_ramp_duration_idx");
2481                     if (b_use_ramp_duration_idx)
2482                         Skip_S1( 4,                             "ramp_duration_idx");
2483                     else
2484                         Skip_S1(11,                             "ramp_duration_bits");
2485                 }
2486                 break;
2487         default:;
2488     }
2489     Element_End0();
2490 }
2491 
object_data(int8u obj_idx,int8u num_obj_info_blocks_bits)2492 void File_DolbyE::object_data(int8u obj_idx, int8u num_obj_info_blocks_bits)
2493 {
2494     ObjectElements.resize(ObjectElements.size()+1);
2495     ObjectElements[ObjectElements.size()-1].Alts.resize(num_obj_info_blocks_bits+1);
2496 
2497     Element_Begin1("object_data");
2498     for (int8u blk=0; blk<=num_obj_info_blocks_bits; blk++)
2499         object_info_block(obj_idx, blk);
2500     Element_End0();
2501 }
2502 
object_info_block(int8u obj_idx,int8u blk)2503 void File_DolbyE::object_info_block(int8u obj_idx, int8u blk)
2504 {
2505     Element_Begin1("object_info_block");
2506     int8u object_basic_info_status_idx, object_render_info_status_idx;
2507     bool b_object_not_active;
2508     Get_SB (b_object_not_active,                                "b_object_not_active");
2509     if (b_object_not_active)
2510         object_basic_info_status_idx=0;
2511     else if (!blk)
2512         object_basic_info_status_idx=1;
2513     else
2514         Get_S1 (2, object_basic_info_status_idx,                "object_basic_info_status_idx");
2515     if (object_basic_info_status_idx&1) // 1 or 3
2516         object_basic_info(object_basic_info_status_idx>>1, blk); // Use bit 1
2517     else
2518     {
2519         dyn_object& D=ObjectElements[ObjectElements.size()-1];
2520         dyn_object::dyn_object_alt& A=D.Alts[blk];
2521         A.obj_gain_db=INT8_MAX;
2522     }
2523     if (b_object_not_active || (obj_idx<b_object_in_bed_or_isf.size() && b_object_in_bed_or_isf[obj_idx]))
2524         object_render_info_status_idx=0;
2525     else if (!blk)
2526         object_render_info_status_idx=1;
2527     else
2528         Get_S1 (2, object_render_info_status_idx,               "object_render_info_status_idx");
2529     if (object_render_info_status_idx&1) // 1 or 3
2530         object_render_info(object_render_info_status_idx>>1, blk); // Use bit 1
2531     else
2532     {
2533         dyn_object& D=ObjectElements[ObjectElements.size()-1];
2534         dyn_object::dyn_object_alt& A=D.Alts[blk];
2535         A.pos3d_x_bits=(int8u)-1;
2536     }
2537     bool b_additional_table_data_exists;
2538     Get_SB (b_additional_table_data_exists,                     "b_additional_table_data_exists");
2539     if (b_additional_table_data_exists)
2540     {
2541         int8u additional_table_data_size_bits;
2542         Get_S1(4, additional_table_data_size_bits,              "additional_table_data_size_bits");
2543         additional_table_data_size_bits++;
2544         additional_table_data_size_bits*=8;
2545         Skip_BS(additional_table_data_size_bits,                "additional_table_data");
2546     }
2547     Element_End0();
2548 }
2549 
object_basic_info(int8u object_basic_info_array,int8u blk)2550 void File_DolbyE::object_basic_info(int8u object_basic_info_array, int8u blk)
2551 {
2552     Element_Begin1("object_basic_info");
2553     if (!object_basic_info_array) // object_basic_info_array is "reuse" info at this point
2554         object_basic_info_array=3; // 2x 1
2555     else
2556         Get_S1 (2, object_basic_info_array,                     "object_basic_info[]");
2557     dyn_object& D=ObjectElements[ObjectElements.size()-1];
2558     dyn_object::dyn_object_alt& A=D.Alts[blk];
2559     if (object_basic_info_array>>1) // bit 1
2560     {
2561         int8u object_gain_idx;
2562         Get_S1 (2, object_gain_idx,                             "object_gain_idx");
2563         switch (object_gain_idx)
2564         {
2565             case 0 :
2566                     A.obj_gain_db=0;
2567                     break;
2568             case 1 :
2569                     A.obj_gain_db=INT8_MIN;
2570                     break;
2571             case 2 :
2572                     {
2573                     int8u object_gain_bits;
2574                     Get_S1 (6, object_gain_bits,                "object_gain_bits");
2575                     A.obj_gain_db=(object_gain_bits<15?15:14)-object_gain_bits;
2576                     }
2577                     break;
2578             default:
2579                     if (ObjectElements.size()>=2)
2580                         A.obj_gain_db=ObjectElements[ObjectElements.size()-2].Alts[blk].obj_gain_db;
2581                     else
2582                         A.obj_gain_db=0;
2583         }
2584     }
2585     else
2586         A.obj_gain_db=INT8_MAX;
2587     if (object_basic_info_array&1) // bit 0
2588     {
2589         bool b_default_object_priority;
2590         Get_SB (   b_default_object_priority,                   "b_default_object_priority");
2591         if (!b_default_object_priority)
2592             Skip_S1(5,                                          "b_default_object_priority");
2593     }
2594     Element_End0();
2595 }
2596 
object_render_info(int8u object_render_info_array,int8u blk)2597 void File_DolbyE::object_render_info(int8u object_render_info_array, int8u blk)
2598 {
2599     Element_Begin1("object_render_info");
2600     if (!object_render_info_array) // object_render_info_array is "reuse" info at this point
2601         object_render_info_array=0xF; // 4x 1
2602     else
2603         Get_S1 (4, object_render_info_array,                    "object_render_info[]");
2604     dyn_object& D=ObjectElements[ObjectElements.size()-1];
2605     dyn_object::dyn_object_alt& A=D.Alts[blk];
2606     if (object_render_info_array&1) // bit 0
2607     {
2608         bool b_differential_position_specified;
2609         if (!blk)
2610             b_differential_position_specified=0;
2611         else
2612             Get_SB(b_differential_position_specified,           "b_differential_position_specified");
2613         if (b_differential_position_specified)
2614         {
2615             Skip_S1(3,                                          "diff_pos3D_X_bits");
2616             Skip_S1(3,                                          "diff_pos3D_Y_bits");
2617             Skip_S1(3,                                          "diff_pos3D_Z_bits");
2618             A.pos3d_x_bits=(int8u)-1; // Not supported
2619         }
2620         else
2621         {
2622             bool b_object_distance_specified;
2623             Get_S1 (6, A.pos3d_x_bits,                          "pos3d_x_bits"); Param_Info3(mgi_bitstream_val_to_Q15(A.pos3d_x_bits, 6)/32768.0*100, "%", 0);
2624             Get_S1 (6, A.pos3d_y_bits,                          "pos3d_y_bits"); Param_Info3(mgi_bitstream_val_to_Q15(A.pos3d_y_bits, 6)/32768.0*100, "%", 0);
2625             Get_SB (   A.pos3d_z_sig,                           "pos3d_z_sig");
2626             Get_S1 (4, A.pos3d_z_bits,                          "pos3d_z_bits"); Param_Info3(mgi_bitstream_pos_z_to_Q15(A.pos3d_z_sig, A.pos3d_z_bits)/32768.0*100, "%", 0);
2627             Get_SB (   b_object_distance_specified,             "b_object_distance_specified");
2628             if (b_object_distance_specified)
2629             {
2630                 bool b_object_at_infinity;
2631                 Get_SB (   b_object_at_infinity,                "b_object_at_infinity");
2632                 if (!b_object_at_infinity)
2633                     Skip_S1(4,                                  "distance_factor_idx");
2634             }
2635         }
2636     }
2637     else
2638         A.pos3d_x_bits=(int8u)-1;
2639     A.hp_render_mode=(int8u)-1;
2640     if ((object_render_info_array>>1)&1) // bit 1
2641     {
2642         Skip_S1(3,                                              "zone_constraints_idx");
2643         Skip_SB(                                                "b_enable_elevation");
2644     }
2645     if ((object_render_info_array>>2)&1) // bit 2
2646     {
2647         int8u object_size_idx;
2648         Get_S1 (2, object_size_idx,                             "object_size_idx");
2649         switch (object_size_idx)
2650         {
2651             case  1:
2652                     {
2653                     Skip_S1(5,                                  "object_size_bits");
2654                     }
2655                     break;
2656             case  2:
2657                     {
2658                     Skip_S1(5,                                  "object_width_bits");
2659                     Skip_S1(5,                                  "object_depth_bits");
2660                     Skip_S1(5,                                  "object_height_bits");
2661                     }
2662                     break;
2663             default:;
2664         }
2665     }
2666     if (object_render_info_array>>3) // bit 3
2667     {
2668         bool b_object_use_screen_ref;
2669         Get_SB (   b_object_use_screen_ref,                     "b_object_use_screen_ref");
2670         if (b_object_use_screen_ref)
2671         {
2672             Skip_S1(3,                                          "screen_factor_bits");
2673             Skip_S1(2,                                          "depth_factor_idx");
2674         }
2675         Skip_SB(                                                "b_object_snap");
2676     }
2677     Element_End0();
2678 }
2679 
bits_needed(size_t value)2680 int8u bits_needed(size_t value)
2681 {
2682     if (!value)
2683         return 0;
2684 
2685     int8u res = 0;
2686     while (value) {
2687         res += 1;
2688         value >>= 1;
2689     }
2690     return res;
2691 }
2692 
mgi_payload()2693 void File_DolbyE::mgi_payload()
2694 {
2695     DynObjects.clear();
2696     BedInstances.clear();
2697     Presets.clear();
2698     substream_mappings.clear();
2699 
2700     Element_Begin1("mgi_payload");
2701     size_t BS_Start=Data_BS_Remain();
2702     int8u mgi_version, num_presets_m1, num_dyn_objects, num_bed_instances;
2703     bool program_id_available, is_substream_mapping_present, mini_mixgraph_extension_present, mini_mixgraph_description_present;
2704     Get_S1 (2, mgi_version,                                     "mgi_version");
2705     if (mgi_version ==3)
2706     {
2707         int32u mgi_version32;
2708         Get_V4 (2, mgi_version32,                               "mgi_version");
2709         mgi_version32+=3;
2710         mgi_version=(int8u)mgi_version32;
2711     }
2712     if (mgi_version!=5)
2713     {
2714         Skip_BS(1,                                              "(Unparsed mgi_payload data)"); //TODO: exact count of bits
2715         Element_End0();
2716         return;
2717     }
2718     Get_SB (program_id_available,                               "program_id_available");
2719     Get_SB (is_substream_mapping_present,                       "is_substream_mapping_present");
2720     Get_SB (mini_mixgraph_extension_present,                    "mini_mixgraph_extension_present");
2721     Get_SB (mini_mixgraph_description_present,                  "mini_mixgraph_description_present");
2722     if (program_id_available)
2723     {
2724         Skip_S1( 3,                                             "program_uuid_segment_number");
2725         Skip_S2(16,                                             "program_uuid_segment");
2726     }
2727     {
2728         size_t ToPadd=(BS_Start-Data_BS_Remain())%8;
2729         if (ToPadd<8)
2730             Skip_BS(8-ToPadd,                                   "byte_align");
2731     }
2732     Skip_S2(16,                                                 "short_program_id");
2733     Get_S1 (4, num_presets_m1,                                  "num_presets_m1");
2734     Get_S1 (7, num_dyn_objects,                                 "num_dyn_objects");
2735     Get_S1 (4, num_bed_instances,                               "num_bed_instances");
2736 
2737     DynObjects.resize(num_dyn_objects);
2738     for (int8u i=0; i<num_dyn_objects; i++)
2739     {
2740         dyn_object& D=DynObjects[i];
2741         Element_Begin1("dyn_object");
2742         int32u num_dyn_obj_alt_md;
2743         Get_V4 (2, num_dyn_obj_alt_md,                          "num_dyn_obj_alt_md");
2744         Get_S1 (2, D.sound_category,                            "sound_category"); Param_Info1(sound_category_Values[D.sound_category]);
2745         D.Alts.resize(num_dyn_obj_alt_md);
2746         for (int32u j=0; j<num_dyn_obj_alt_md; j++)
2747         {
2748             dyn_object::dyn_object_alt& A=D.Alts[j];
2749             Element_Begin1("dyn_obj_alt_md");
2750             int32u object_info_mask, object_info_size_bytes;
2751             Get_V4 (3, object_info_mask,                        "object_info_mask");
2752             //Get_V4 (3, object_info_size_bytes,                  "object_info_size_bytes"); //TODO
2753             Get_S4 (4, object_info_size_bytes,                  "object_info_size_bytes, variable_bits ignored");
2754             object_info_size_bytes=4;
2755             size_t Begin=Data_BS_Remain();
2756             if (object_info_size_bytes)
2757             {
2758                 if (object_info_mask & 0x1)
2759                 {
2760                     int8u dyn_obj_gain_db_bits;
2761                     Get_S1(6, dyn_obj_gain_db_bits,             "dyn_obj_gain_db_bits");
2762                     if (dyn_obj_gain_db_bits==63)
2763                         A.obj_gain_db=INT8_MIN;
2764                     else
2765                         A.obj_gain_db=15-dyn_obj_gain_db_bits;
2766                 }
2767                 else
2768                     A.obj_gain_db=INT8_MAX;
2769                 if (object_info_mask & 0x2)
2770                 {
2771                     Get_S1 (6, A.pos3d_x_bits,                  "pos3d_x_bits"); Param_Info3(mgi_bitstream_val_to_Q15(A.pos3d_x_bits, 6)/32768.0*100, "%", 0);
2772                     Get_S1 (6, A.pos3d_y_bits,                  "pos3d_y_bits"); Param_Info3(mgi_bitstream_val_to_Q15(A.pos3d_y_bits, 6)/32768.0*100, "%", 0);
2773                     Get_SB (   A.pos3d_z_sig,                   "pos3d_z_sig");
2774                     Get_S1 (4, A.pos3d_z_bits,                  "pos3d_z_bits"); Param_Info3(mgi_bitstream_pos_z_to_Q15(A.pos3d_z_sig, A.pos3d_z_bits)/32768.0*100, "%", 0);
2775                     Element_Level--;
2776                     Element_Info1(Angles2String(mgi_bitstream_pos_ToAngles(mgi_bitstream_val_to_Q15(A.pos3d_x_bits, 6), mgi_bitstream_val_to_Q15(A.pos3d_y_bits, 6), mgi_bitstream_pos_z_to_Q15(A.pos3d_z_sig, A.pos3d_z_bits))));
2777                     Element_Level++;
2778                 }
2779                 else
2780                     A.pos3d_x_bits=(int8u)-1;
2781                 if (object_info_mask & 0x4)
2782                 {
2783                     Skip_SB(                                    "hp_md_state");
2784                     Get_S1 (2, A.hp_render_mode,                "hp_render_mode"); Param_Info1(hp_render_mode_Values[A.hp_render_mode]);
2785                     Skip_SB(                                    "hp_headtrack_state");
2786                 }
2787                 else
2788                     A.hp_render_mode=(int8u)-1;
2789                 size_t Parsed=Begin-Data_BS_Remain();
2790                 int8u Padding=8-(Parsed%8);
2791                 Skip_BS(Padding,                                "padding");
2792             }
2793             Element_End0();
2794         }
2795         Element_End0();
2796     }
2797 
2798     BedInstances.resize(num_bed_instances);
2799     for (int8u i=0; i<num_bed_instances; i++)
2800     {
2801         bed_instance& B=BedInstances[i];
2802         Element_Begin1("bed_instance");
2803         int32u num_bed_alt_md;
2804         Get_V4 (2, num_bed_alt_md,                              "num_bed_alt_md");
2805         B.Alts.resize(num_bed_alt_md);
2806         for (int8u j=0; j<num_bed_alt_md; j++)
2807         {
2808             bed_instance::bed_alt& A=B.Alts[j];
2809             Element_Begin1("bed_alt_md");
2810             int32u bed_info_mask, bed_info_size_bytes;
2811             Get_V4 (2, bed_info_mask,                           "bed_info_mask");
2812             Get_V4 (2, bed_info_size_bytes,                     "bed_info_size_bytes");
2813             size_t End=Data_BS_Remain()-bed_info_size_bytes*8;
2814             if (bed_info_mask&1)
2815             {
2816                 int8u bed_gain_db_bits;
2817                 Get_S1(6, bed_gain_db_bits,                     "bed_gain_db_bits");
2818                 A.bed_gain_db=15-bed_gain_db_bits;
2819             }
2820             else
2821                 A.bed_gain_db=INT8_MAX;
2822             if (Data_BS_Remain()>End)
2823                 Skip_BS(Data_BS_Remain()-End,                   "padding");
2824             Element_End0();
2825         }
2826         Element_End0();
2827     }
2828 
2829     Presets.resize(num_presets_m1 + 1);
2830     for (int8u i=0; i<=num_presets_m1; i++)
2831     {
2832         preset& P=Presets[i];
2833         Element_Begin1("preset");
2834         int32u num_target_device_configs_m1;
2835         Get_V4 (2, num_target_device_configs_m1,                "num_target_device_configs_m1");
2836         Get_V4 (2, P.default_target_device_config,              "default_target_device_config"); Param_Info1(default_target_device_config_Value(P.default_target_device_config));
2837         P.target_device_configs.resize(num_target_device_configs_m1+1);
2838         for (int32u j=0; j<=num_target_device_configs_m1; j++)
2839         {
2840             preset::target_device_config& T=P.target_device_configs[j];
2841             Element_Begin1("target_device_config");
2842             Get_V4 (3, T.target_devices_mask,                   "target_devices_mask"); Param_Info1(default_target_device_config_Value(T.target_devices_mask));
2843             for (int32u k=0; k<num_dyn_objects+num_bed_instances; k++)
2844             {
2845                 Element_Begin1(k<num_dyn_objects?"object":"bed");
2846                 bool active;
2847                 Get_SB (active,                                 k<num_dyn_objects?"object_active":"bed_active");
2848                 if (active)
2849                 {
2850                     int32u md_index;
2851                     size_t Size=k<num_dyn_objects?DynObjects[k].Alts.size():BedInstances[k-num_dyn_objects].Alts.size();
2852                     Get_S4 (bits_needed(Size+1), md_index, k<num_dyn_objects?"obj_md_index":"bed_md_index");
2853                     T.md_indexes.push_back(md_index);
2854                 }
2855                 else
2856                     T.md_indexes.push_back((int32u)-1);
2857                 Element_End0();
2858             }
2859             Element_End0();
2860         }
2861         TEST_SB_SKIP(                                           "preset_extension");
2862             int32u extension_size;
2863             Get_V4 (4, extension_size,                          "extension_size");
2864             Skip_BS(extension_size,                             "extension");
2865         TEST_SB_END();
2866         Element_End0();
2867     }
2868 
2869     substream_mappings.resize(num_dyn_objects+num_bed_instances);
2870     if (is_substream_mapping_present)
2871     {
2872         Element_Begin1("substream_mapping");
2873         for (int8u i=0; i<substream_mappings.size(); i++)
2874         {
2875             substream_mapping& S=substream_mappings[i];
2876             Element_Begin1(i<num_dyn_objects?"dyn_object":"bed_instance");
2877             bool standard_index;
2878             Get_S1(4, S.substream_id,                           "substream_id");
2879             Get_SB(   standard_index,                           "standard_index");
2880             if (standard_index)
2881                 Get_S4 (3, S.channel_index,                     "channel_index");
2882             else
2883             {
2884                 Get_S4(5, S.channel_index,                      "channel_index");
2885                 if (S.channel_index==0x1F)
2886                 {
2887                     Get_V4(3, S.channel_index,                  "channel_index");
2888                     S.channel_index+=0x1F;
2889                 }
2890             }
2891 
2892             Element_End0();
2893         }
2894         Element_End0();
2895     }
2896     int8u byte_align_Content=0;
2897     {
2898         size_t ToPadd=(BS_Start-Data_BS_Remain())%8;
2899         if (ToPadd)
2900             Get_S1(8-ToPadd, byte_align_Content,                "byte_align");
2901     }
2902     if (mini_mixgraph_extension_present)
2903     {
2904         Element_Begin1("mini_mixgraph_extension");
2905         TEST_SB_SKIP(                                           "mgi_extension");
2906             int32u extension_size;
2907             Get_V4 (4, extension_size,                          "extension_size");
2908             Skip_BS(extension_size,                             "extension");
2909         TEST_SB_END();
2910         Element_End0();
2911     }
2912     if (mini_mixgraph_description_present)
2913     {
2914         Element_Begin1("mini_mixgraph_description");
2915         int32u desc_packet_idx, desc_pkt_size_bits;
2916         if (!byte_align_Content)
2917         {
2918             Get_V4 (5, desc_packet_idx,                         "desc_packet_idx");
2919         }
2920         else
2921         {
2922             Skip_S1(6,                                          "0x3F?");
2923             desc_packet_idx = 30; //Not in spec. Bug in the stream here?
2924         }
2925         if (!desc_packet_idx)
2926         {
2927             Get_V4 (5, num_desc_packets_m1,                     "num_desc_packets_m1");
2928         }
2929         if (desc_packet_idx==num_desc_packets_m1)
2930         {
2931             Get_V4 (7, desc_pkt_size_bits,                      "desc_pkt_size_bits");
2932         }
2933         else
2934         {
2935             Get_V4 (4, desc_pkt_size_bits,                      "desc_pkt_size_bytes");
2936             desc_pkt_size_bits<<=3; //bits to bytes
2937         }
2938         while (desc_pkt_size_bits)
2939         {
2940             int8u bits8=desc_pkt_size_bits>8?8:desc_pkt_size_bits;
2941             int8u data;
2942             Get_S1(bits8, data,                                 "description_packet_data");
2943             if (num_desc_packets_m1!=(int32u)-1)
2944                 description_packet_data.push_back(data<<(8-bits8));
2945             desc_pkt_size_bits-=bits8;
2946         }
2947         if (desc_packet_idx==num_desc_packets_m1 && !description_packet_data.empty())
2948         {
2949             Presets_More.clear();
2950             BitStream_Fast* BS_Save=BS;
2951             BS=new BitStream_Fast(&*description_packet_data.begin(), description_packet_data.size()); //In bytes, we can not provide a precise count of bits
2952             Element_Begin1("packet_description");
2953             int8u preset_description_id_bits;
2954             Get_S1(3, preset_description_id_bits,           "preset_description_id_bits");
2955             for (int8u i=0; i <=num_presets_m1; i++)
2956             {
2957                 Skip_BS(preset_description_id_bits,         "preset_description_id[i]");
2958             }
2959             TEST_SB_SKIP("preset_description_text_present");
2960                 Presets_More.resize(num_presets_m1+1);
2961                 for (int8u i=0; i<=num_presets_m1; i++)
2962                 {
2963                     preset_more& P=Presets_More[i];
2964                     int8u desc_text_len;
2965                     Get_S1(5, desc_text_len,                "desc_text_len");
2966                     Element_Begin1("preset_description");
2967                     for (int8u j=0; j<desc_text_len; j++)
2968                     {
2969                         int8u preset_description_char;
2970                         Get_S1(8, preset_description_char,  "preset_description_char");
2971                         P.description+=(char)preset_description_char;
2972                     }
2973                     if (Ztring().From_UTF8(P.description).empty())
2974                         P.description.clear(); // Problem while parsing
2975                     Element_Info1(P.description);
2976                     Element_End0();
2977                 }
2978             TEST_SB_END();
2979             Element_End0();
2980             delete BS; BS=BS_Save;
2981             description_packet_data.clear();
2982             mini_mixgraph_description_present=false; //Indicates that the stream is ready for data filling
2983         }
2984         Element_End0();
2985         {
2986             size_t ToPadd=(BS_Start-Data_BS_Remain())%8;
2987             if (ToPadd<8)
2988                 Skip_BS(8-ToPadd,                               "byte_align");
2989         }
2990     }
2991     Element_End0();
2992 }
2993 
2994 //---------------------------------------------------------------------------
Get_V4(int8u Bits,int8u MaxLoops,int32u & Info,const char * Name)2995 void File_DolbyE::Get_V4(int8u Bits, int8u MaxLoops, int32u& Info, const char* Name)
2996 {
2997     Info=0;
2998     #if MEDIAINFO_TRACE
2999         if (Trace_Activated)
3000         {
3001             int8u Count=0;
3002             for (;;)
3003             {
3004                 Info+=BS->Get4(Bits);
3005                 Count+=1+Bits;
3006                 if (!BS->GetB() || !(--MaxLoops))
3007                     break;
3008                 Info<<=Bits;
3009                 Info+=(1<<Bits);
3010             }
3011 
3012             Param(Name, Info, Count);
3013             Param_Info(__T("(")+Ztring::ToZtring(Count)+__T(" bits)"));
3014         }
3015         else
3016     #endif //MEDIAINFO_TRACE
3017         {
3018             for (;;)
3019             {
3020                 Info+=BS->Get4(Bits);
3021                 if (!BS->GetB() || !(--MaxLoops))
3022                     break;
3023                 Info<<=Bits;
3024                 Info+=(1<<Bits);
3025             }
3026         }
3027 }
3028 
3029 //---------------------------------------------------------------------------
Get_V4(int8u Bits,int32u & Info,const char * Name)3030 void File_DolbyE::Get_V4(int8u Bits, int32u& Info, const char* Name)
3031 {
3032     Info=0;
3033     #if MEDIAINFO_TRACE
3034         if (Trace_Activated)
3035         {
3036             int8u Count=0;
3037             for (;;)
3038             {
3039                 Info+=BS->Get4(Bits);
3040                 Count+=1+Bits;
3041                 if (!BS->GetB())
3042                     break;
3043                 Info<<=Bits;
3044                 Info+=(1<<Bits);
3045             }
3046 
3047             Param(Name, Info, Count);
3048             Param_Info(__T("(")+Ztring::ToZtring(Count)+__T(" bits)"));
3049         }
3050         else
3051     #endif //MEDIAINFO_TRACE
3052         {
3053             for (;;)
3054             {
3055                 Info+=BS->Get4(Bits);
3056                 if (!BS->GetB())
3057                     break;
3058                 Info<<=Bits;
3059                 Info+=(1<<Bits);
3060             }
3061         }
3062 }
3063 
3064 //---------------------------------------------------------------------------
Skip_V4(int8u Bits,const char * Name)3065 void File_DolbyE::Skip_V4(int8u  Bits, const char* Name)
3066 {
3067     #if MEDIAINFO_TRACE
3068         if (Trace_Activated)
3069         {
3070             int32u Info=0;
3071             int8u Count=0;
3072             for (;;)
3073             {
3074                 Info+=BS->Get4(Bits);
3075                 Count+=1+Bits;
3076                 if (!BS->GetB())
3077                     break;
3078                 Info<<=Bits;
3079                 Info+=(1<<Bits);
3080             }
3081 
3082             Param(Name, Info, Count);
3083             Param_Info(__T("(")+Ztring::ToZtring(Count)+__T(" bits)"));
3084         }
3085         else
3086     #endif //MEDIAINFO_TRACE
3087         {
3088             for (;;)
3089             {
3090                 BS->Skip(Bits);
3091                 if (!BS->GetB())
3092                     break;
3093             }
3094         }
3095 }
3096 
3097 //---------------------------------------------------------------------------
audio_segment()3098 void File_DolbyE::audio_segment()
3099 {
3100     //Parsing
3101     Element_Begin1("audio_segment");
3102     #if MEDIAINFO_TRACE
3103         //CRC test
3104         size_t Pos_Begin=0;
3105     #endif //MEDIAINFO_TRACE
3106     for (int8u Channel=0; Channel<DolbyE_Channels[program_config]; Channel++)
3107     {
3108         if ((Channel%(DolbyE_Channels[program_config]/2))==0 && key_present)
3109         {
3110             int16u audio_subsegment_size=0;
3111             for (int8u ChannelForSize=0; ChannelForSize<DolbyE_Channels[program_config]/2; ChannelForSize++)
3112                 audio_subsegment_size+=channel_subsegment_size[((Channel<DolbyE_Channels[program_config]/2)?0:(DolbyE_Channels[program_config]/2))+ChannelForSize];
3113 
3114             if (Data_BS_Remain()<(audio_subsegment_size+1)*(size_t)bit_depth)
3115                 return; //There is a problem
3116 
3117             //We must change the buffer
3118             switch (bit_depth)
3119             {
3120                 case 16 :
3121                             {
3122                             int16u audio_subsegment_key;
3123                             Get_S2 (16, audio_subsegment_key, (Channel+1==DolbyE_Channels[program_config])?"audio_subsegment1_key":"audio_subsegment0_key");
3124 
3125                             int8u* Temp=Descrambled_Buffer+(size_t)Element_Size-Data_BS_Remain()/8;
3126                             for (int16u Pos=0; Pos<audio_subsegment_size+1; Pos++)
3127                                 int16u2BigEndian(Temp+Pos*2, BigEndian2int16u(Temp+Pos*2)^audio_subsegment_key);
3128                             }
3129                             break;
3130                 case 20 :
3131                             {
3132                             int32u audio_subsegment_key;
3133                             Get_S3 (20, audio_subsegment_key, (Channel+1==DolbyE_Channels[program_config])?"audio_subsegment1_key":"audio_subsegment0_key");
3134 
3135                             Descramble_20bit(audio_subsegment_key, audio_subsegment_size);
3136                             }
3137                             break;
3138                 default :   ;
3139             }
3140         }
3141 
3142         #if MEDIAINFO_TRACE
3143             //CRC test
3144             if ((Channel%(DolbyE_Channels[program_config]/2))==0)
3145                 Pos_Begin=Buffer_Offset*8+(size_t)Element_Size*8-Data_BS_Remain();
3146         #endif //MEDIAINFO_TRACE
3147 
3148         Element_Begin1(__T("Channel ")+Ztring::ToZtring(Channel));
3149         Element_Info1(Ztring::ToZtring(channel_subsegment_size[Channel])+__T(" words"));
3150         Skip_BS(channel_subsegment_size[Channel]*bit_depth,     "channel_subsegment");
3151         Element_End0();
3152         if ((Channel%(DolbyE_Channels[program_config]/2))==DolbyE_Channels[program_config]/2-1)
3153         {
3154             Skip_S3(bit_depth,                                  (Channel+1==DolbyE_Channels[program_config])?"audio_subsegment1_crc":"audio_subsegment0_crc");
3155 
3156             #if MEDIAINFO_TRACE
3157                 //CRC test
3158                 size_t Pos_End=Buffer_Offset*8+(size_t)Element_Size*8-Data_BS_Remain();
3159                 int8u BitSkip_Begin=Pos_Begin%8;
3160                 Pos_Begin/=8;
3161                 int8u BitSkip_End=0; // Pos_End%8; Looks like that the last bits must not be in the CRC computing
3162                 Pos_End/=8;
3163                 if (BitSkip_End)
3164                     Pos_End++;
3165 
3166                 int16u CRC=CRC_16_Compute(Buffer+Pos_Begin, Pos_End-Pos_Begin, BitSkip_Begin, BitSkip_End);
3167                 if (CRC)
3168                 {
3169                     //CRC is wrong
3170                     Param_Info1("NOK");
3171                 }
3172             #endif //MEDIAINFO_TRACE
3173         }
3174     }
3175     Element_End0();
3176 }
3177 
3178 //---------------------------------------------------------------------------
metadata_extension_segment()3179 void File_DolbyE::metadata_extension_segment()
3180 {
3181     //Parsing
3182     Element_Begin1("metadata_extension_segment");
3183     if (key_present)
3184     {
3185         if (Data_BS_Remain()<((size_t)metadata_extension_segment_size+1)*(size_t)bit_depth) //+1 for CRC
3186             return; //There is a problem
3187 
3188         //We must change the buffer
3189         switch (bit_depth)
3190         {
3191             case 16 :
3192                         {
3193                         int16u metadata_extension_segment_key;
3194                         Get_S2 (16, metadata_extension_segment_key, "metadata_extension_segment_key");
3195 
3196                         int8u* Temp=Descrambled_Buffer+(size_t)Element_Size-Data_BS_Remain()/8;
3197                         for (int16u Pos=0; Pos<metadata_extension_segment_size+1; Pos++)
3198                             int16u2BigEndian(Temp+Pos*2, BigEndian2int16u(Temp+Pos*2)^metadata_extension_segment_key);
3199                         }
3200                         break;
3201             case 20 :
3202                         {
3203                         int32u metadata_extension_segment_key;
3204                         Get_S3 (20, metadata_extension_segment_key, "metadata_extension_segment_key");
3205 
3206                         Descramble_20bit(metadata_extension_segment_key, metadata_extension_segment_size);
3207                         }
3208                         break;
3209             default :   ;
3210         }
3211     }
3212 
3213     #if MEDIAINFO_TRACE
3214         //CRC test
3215         size_t Pos_Begin=Buffer_Offset*8+(size_t)Element_Size*8-Data_BS_Remain();
3216     #endif //MEDIAINFO_TRACE
3217 
3218     size_t  metadata_extension_segment_BitCountAfter=Data_BS_Remain();
3219     metadata_extension_segment_BitCountAfter-=metadata_extension_segment_size*bit_depth;
3220     if (metadata_extension_segment_size)
3221     {
3222         for(;;)
3223         {
3224             Element_Begin1("metadata_extension_subsegment");
3225             int16u  metadata_extension_subsegment_length;
3226             int8u   metadata_extension_subsegment_id;
3227             Get_S1 ( 4, metadata_extension_subsegment_id,       "metadata_extension_subsegment_id");
3228             if (metadata_extension_subsegment_id==0)
3229             {
3230                 Element_End0();
3231                 break;
3232             }
3233             Get_S2 (12, metadata_extension_subsegment_length,   "metadata_extension_subsegment_length");
3234             switch (metadata_extension_subsegment_id)
3235             {
3236                 default: Skip_BS(metadata_extension_subsegment_length,"metadata_extension_subsegment (unknown)");
3237             }
3238             Element_End0();
3239         }
3240         Param_Info1(metadata_extension_segment_BitCountAfter);
3241         Param_Info1(Data_BS_Remain());
3242         Param_Info1(Data_BS_Remain()-metadata_extension_segment_BitCountAfter);
3243         if (Data_BS_Remain()>metadata_extension_segment_BitCountAfter)
3244             Skip_BS(Data_BS_Remain()-metadata_extension_segment_BitCountAfter,"reserved_metadata_extension_bits");
3245     }
3246     Skip_S3(bit_depth,                                          "metadata_extension_crc");
3247 
3248     #if MEDIAINFO_TRACE
3249         //CRC test
3250         size_t Pos_End=Buffer_Offset*8+(size_t)Element_Size*8-Data_BS_Remain();
3251         int8u BitSkip_Begin=Pos_Begin%8;
3252         Pos_Begin/=8;
3253         int8u BitSkip_End=0; // Pos_End%8; Looks like that the last bits must not be in the CRC computing
3254         Pos_End/=8;
3255         if (BitSkip_End)
3256             Pos_End++;
3257 
3258         int16u CRC=CRC_16_Compute(Buffer+Pos_Begin, Pos_End-Pos_Begin, BitSkip_Begin, BitSkip_End);
3259         if (CRC)
3260         {
3261             //CRC is wrong
3262             Param_Info1("NOK");
3263         }
3264     #endif //MEDIAINFO_TRACE
3265 
3266     Element_End0();
3267 }
3268 
3269 //---------------------------------------------------------------------------
audio_extension_segment()3270 void File_DolbyE::audio_extension_segment()
3271 {
3272     //Parsing
3273     Element_Begin1("audio_extension_segment");
3274     #if MEDIAINFO_TRACE
3275         //CRC test
3276         size_t Pos_Begin=0;
3277     #endif //MEDIAINFO_TRACE
3278     for (int8u Channel=0; Channel<DolbyE_Channels[program_config]; Channel++)
3279     {
3280         if ((Channel%(DolbyE_Channels[program_config]/2))==0 && key_present)
3281         {
3282             int16u audio_extension_subsegment_size=0;
3283             for (int8u ChannelForSize=0; ChannelForSize<DolbyE_Channels[program_config]/2; ChannelForSize++)
3284                 audio_extension_subsegment_size+=channel_subsegment_size[((Channel<DolbyE_Channels[program_config]/2)?0:(DolbyE_Channels[program_config]/2))+ChannelForSize];
3285 
3286             if (Data_BS_Remain()<((size_t)audio_extension_subsegment_size+1)*(size_t)bit_depth)
3287                 return; //There is a problem
3288 
3289             //We must change the buffer
3290             switch (bit_depth)
3291             {
3292                 case 16 :
3293                             {
3294                             int16u audio_extension_subsegment_key;
3295                             Get_S2 (16, audio_extension_subsegment_key, (Channel+1==DolbyE_Channels[program_config])?"audio_extension_subsegment1_key":"audio_extension_subsegment0_key");
3296 
3297                             int8u* Temp=Descrambled_Buffer+(size_t)Element_Size-Data_BS_Remain()/8;
3298                             for (int16u Pos=0; Pos<audio_extension_subsegment_size+1; Pos++)
3299                                 int16u2BigEndian(Temp+Pos*2, BigEndian2int16u(Temp+Pos*2)^audio_extension_subsegment_key);
3300                             }
3301                             break;
3302                 case 20 :
3303                             {
3304                             int32u audio_extension_subsegment_key;
3305                             Get_S3 (20, audio_extension_subsegment_key, (Channel+1==DolbyE_Channels[program_config])?"audio_extension_subsegment1_key":"audio_extension_subsegment0_key");
3306 
3307                             Descramble_20bit(audio_extension_subsegment_key, audio_extension_subsegment_size);
3308                             }
3309                             break;
3310                 default :   ;
3311             }
3312         }
3313 
3314         #if MEDIAINFO_TRACE
3315             //CRC test
3316             if ((Channel%(DolbyE_Channels[program_config]/2))==0)
3317                 Pos_Begin=Buffer_Offset*8+(size_t)Element_Size*8-Data_BS_Remain();
3318         #endif //MEDIAINFO_TRACE
3319 
3320         Element_Begin1(__T("Channel ")+Ztring::ToZtring(Channel));
3321         Element_Info1(Ztring::ToZtring(channel_subsegment_size[Channel])+__T(" words"));
3322         Skip_BS(channel_subsegment_size[Channel]*bit_depth,     "channel_subsegment");
3323         Element_End0();
3324         if ((Channel%(DolbyE_Channels[program_config]/2))==DolbyE_Channels[program_config]/2-1)
3325         {
3326             Skip_S3(bit_depth,                                  (Channel+1==DolbyE_Channels[program_config])?"audio_extension_subsegment1_crc":"audio_extension_subsegment0_crc");
3327 
3328             #if MEDIAINFO_TRACE
3329                 //CRC test
3330                 size_t Pos_End=Buffer_Offset*8+(size_t)Element_Size*8-Data_BS_Remain();
3331                 int8u BitSkip_Begin=Pos_Begin%8;
3332                 Pos_Begin/=8;
3333                 int8u BitSkip_End=0; // Pos_End%8; Looks like that the last bits must not be in the CRC computing
3334                 Pos_End/=8;
3335                 if (BitSkip_End)
3336                     Pos_End++;
3337 
3338                 int16u CRC=CRC_16_Compute(Buffer+Pos_Begin, Pos_End-Pos_Begin, BitSkip_Begin, BitSkip_End);
3339                 if (CRC)
3340                 {
3341                     //CRC is wrong
3342                     Param_Info1("NOK");
3343                 }
3344             #endif //MEDIAINFO_TRACE
3345         }
3346     }
3347     Element_End0();
3348 }
3349 
3350 //---------------------------------------------------------------------------
meter_segment()3351 void File_DolbyE::meter_segment()
3352 {
3353     //Parsing
3354     Element_Begin1("meter_segment");
3355     if (key_present)
3356     {
3357         if (Data_BS_Remain()<((size_t)meter_segment_size+1)*(size_t)bit_depth) //+1 for CRC
3358             return; //There is a problem
3359 
3360         //We must change the buffer
3361         switch (bit_depth)
3362         {
3363             case 16 :
3364                         {
3365                         int16u meter_segment_key;
3366                         Get_S2 (16, meter_segment_key, "meter_segment_key");
3367 
3368                         int8u* Temp=Descrambled_Buffer+(size_t)Element_Size-Data_BS_Remain()/8;
3369                         for (int16u Pos=0; Pos<meter_segment_size+1; Pos++)
3370                             int16u2BigEndian(Temp+Pos*2, BigEndian2int16u(Temp+Pos*2)^meter_segment_key);
3371                         }
3372                         break;
3373             case 20 :
3374                         {
3375                         int32u meter_segment_key;
3376                         Get_S3 (20, meter_segment_key, "meter_segment_key");
3377 
3378                         Descramble_20bit(meter_segment_key, meter_segment_size);
3379                         }
3380                         break;
3381             default :   ;
3382         }
3383     }
3384     size_t  meter_segment_BitCountAfter=Data_BS_Remain();
3385     meter_segment_BitCountAfter-=meter_segment_size*bit_depth;
3386     for (int8u Channel=0; Channel<DolbyE_Channels[program_config]; Channel++)
3387         Skip_S2(10,                                             "peak_meter");
3388     for (int8u Channel=0; Channel<DolbyE_Channels[program_config]; Channel++)
3389         Skip_S2(10,                                             "rms_meter");
3390     if (Data_BS_Remain()>meter_segment_BitCountAfter)
3391         Skip_BS(Data_BS_Remain()>meter_segment_BitCountAfter,   "reserved_meter_bits");
3392     Skip_S3(bit_depth,                                          "meter_crc");
3393 
3394     #if MEDIAINFO_TRACE
3395         //CRC test
3396         size_t Pos_End=Buffer_Offset*8+(size_t)Element_Size*8-Data_BS_Remain();
3397         size_t Pos_Begin=Pos_End-(meter_segment_size+1)*bit_depth; //+1 for CRC
3398         int8u BitSkip_Begin=Pos_Begin%8;
3399         Pos_Begin/=8;
3400         int8u BitSkip_End=0; // Pos_End%8; Looks like that the last bits must not be in the CRC computing
3401         Pos_End/=8;
3402         if (BitSkip_End)
3403             Pos_End++;
3404 
3405         int16u CRC=CRC_16_Compute(Buffer+Pos_Begin, Pos_End-Pos_Begin, BitSkip_Begin, BitSkip_End);
3406         if (CRC)
3407         {
3408             //CRC is wrong
3409             Param_Info1("NOK");
3410         }
3411     #endif //MEDIAINFO_TRACE
3412 
3413     Element_End0();
3414 }
3415 
3416 //---------------------------------------------------------------------------
ac3_metadata_subsegment(bool xbsi)3417 void File_DolbyE::ac3_metadata_subsegment(bool xbsi)
3418 {
3419     for (int8u program=0; program<DolbyE_Programs[program_config]; program++)
3420     {
3421         Element_Begin1("per program");
3422         Skip_S1(5,                                          "ac3_datarate");
3423         Skip_S1(3,                                          "ac3_bsmod");
3424         Skip_S1(3,                                          "ac3_acmod");
3425         Skip_S1(2,                                          "ac3_cmixlev");
3426         Skip_S1(2,                                          "ac3_surmixlev");
3427         Skip_S1(2,                                          "ac3_dsurmod");
3428         Skip_S1(1,                                          "ac3_lfeon");
3429         Skip_S1(5,                                          "ac3_dialnorm");
3430         Skip_S1(1,                                          "ac3_langcode");
3431         Skip_S1(8,                                          "ac3_langcod");
3432         Skip_S1(1,                                          "ac3_audprodie");
3433         Skip_S1(5,                                          "ac3_mixlevel");
3434         Skip_S1(2,                                          "ac3_roomtyp");
3435         Skip_S1(1,                                          "ac3_copyrightb");
3436         Skip_S1(1,                                          "ac3_origbs");
3437         if (xbsi)
3438         {
3439             Skip_S1(1,                                      "ac3_xbsi1e");
3440             Skip_S1(2,                                      "ac3_dmixmod");
3441             Skip_S1(3,                                      "ac3_ltrtcmixlev");
3442             Skip_S1(3,                                      "ac3_ltrtsurmixlev");
3443             Skip_S1(3,                                      "ac3_lorocmixlev");
3444             Skip_S1(3,                                      "ac3_lorosurmixlev");
3445             Skip_S1(1,                                      "ac3_xbsi2e");
3446             Skip_S1(2,                                      "ac3_dsurexmod");
3447             Skip_S1(2,                                      "ac3_dheadphonmod");
3448             Skip_S1(1,                                      "ac3_adconvtyp");
3449             Skip_S1(8,                                      "ac3_xbsi2");
3450             Skip_S1(1,                                      "ac3_encinfo");
3451         }
3452         else
3453         {
3454             Skip_S1(1,                                      "ac3_timecode1e");
3455             Skip_S2(14,                                     "ac3_timecode1");
3456             Skip_S1(1,                                      "ac3_timecode2e");
3457             Skip_S2(14,                                     "ac3_timecode2");
3458         }
3459         Skip_S1(1,                                          "ac3_hpfon");
3460         Skip_S1(1,                                          "ac3_bwlpfon");
3461         Skip_S1(1,                                          "ac3_lfelpfon");
3462         Skip_S1(1,                                          "ac3_sur90on");
3463         Skip_S1(1,                                          "ac3_suratton");
3464         Skip_S1(1,                                          "ac3_rfpremphon");
3465         Skip_S1(1,                                          "ac3_compre");
3466         Skip_S1(8,                                          "ac3_compr1");
3467         Skip_S1(1,                                          "ac3_dynrnge");
3468         Skip_S1(8,                                          "ac3_dynrng1");
3469         Skip_S1(8,                                          "ac3_dynrng2");
3470         Skip_S1(8,                                          "ac3_dynrng3");
3471         Skip_S1(8,                                          "ac3_dynrng4");
3472         Element_End0();
3473     }
3474     for (int8u program=0; program<DolbyE_Programs[program_config]; program++)
3475     {
3476         Element_Begin1("per program");
3477         bool ac3_addbsie;
3478         Get_SB (   ac3_addbsie,                             "ac3_addbsie");
3479         if (ac3_addbsie)
3480         {
3481             int8u ac3_addbsil;
3482             Get_S1 (6, ac3_addbsil,                         "ac3_addbsil");
3483             for (int8u Pos=0; Pos<ac3_addbsil+1; Pos++)
3484                 Skip_S1(8,                                  "ac3_addbsi[x]");
3485         }
3486         Element_End0();
3487     }
3488 }
3489 
3490 //***************************************************************************
3491 // Helpers
3492 //***************************************************************************
3493 
3494 //---------------------------------------------------------------------------
Descramble_20bit(int32u key,int16u size)3495 void File_DolbyE::Descramble_20bit (int32u key, int16u size)
3496 {
3497     int8u* Temp=Descrambled_Buffer+(size_t)Element_Size-Data_BS_Remain()/8;
3498     int64u keys=(((int64u)key)<<20)|key;
3499     bool Half;
3500     if (Data_BS_Remain()%8)
3501     {
3502         Temp--;
3503         int24u2BigEndian(Temp, BigEndian2int24u(Temp)^(key));
3504         Half=true;
3505     }
3506     else
3507         Half=false;
3508     for (int16u Pos=0; Pos<size-(Half?1:0); Pos+=2)
3509         int40u2BigEndian(Temp+(Half?3:0)+Pos*5/2, BigEndian2int40u(Temp+(Half?3:0)+Pos*5/2)^keys);
3510     if ((size-((size && Half)?1:0))%2==0)
3511         int24u2BigEndian(Temp+(Half?3:0)+(size-((size && Half)?1:0))*5/2, BigEndian2int24u(Temp+(Half?3:0)+(size-((size && Half)?1:0))*5/2)^(key<<4));
3512 }
3513 
3514 //***************************************************************************
3515 // C++
3516 //***************************************************************************
3517 
3518 } //NameSpace
3519 
3520 #endif //MEDIAINFO_DOLBYE_YES
3521