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