1 /* Copyright (c) MediaArea.net SARL. All Rights Reserved.
2 *
3 * Use of this source code is governed by a BSD-style license that can
4 * be found in the License.html file in the root of the source tree.
5 */
6
7 //---------------------------------------------------------------------------
8 // Pre-compilation
9 #include "MediaInfo/PreComp.h"
10 #ifdef __BORLANDC__
11 #pragma hdrstop
12 #endif
13 //---------------------------------------------------------------------------
14
15 //---------------------------------------------------------------------------
16 #include "MediaInfo/Setup.h"
17 //---------------------------------------------------------------------------
18
19 //---------------------------------------------------------------------------
20 #if defined(MEDIAINFO_BDMV_YES)
21 //---------------------------------------------------------------------------
22
23 //---------------------------------------------------------------------------
24 #include "MediaInfo/Multiple/File_Bdmv.h"
25 #include "MediaInfo/MediaInfo.h"
26 #include "MediaInfo/MediaInfo_Internal.h"
27 #if defined(MEDIAINFO_DIRECTORY_YES)
28 #include "ZenLib/Dir.h"
29 #endif //defined(MEDIAINFO_DIRECTORY_YES)
30 #include "ZenLib/FileName.h"
31 using namespace ZenLib;
32 //---------------------------------------------------------------------------
33
34 namespace MediaInfoLib
35 {
36
37 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
38 // index (INDX) with title
39 // --> MovieObject (MOBJ) with mobj
40 // --> PlayList (MPLS)
41 // --> PlayItem (MPLS) with Mark
42 // --> ClipInfo (CLPI)
43 // --> Clip (?) (CLPI)
44 // --> Stream (M2TS)
45 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
46
47 //***************************************************************************
48 // Constants
49 //***************************************************************************
50
51 //---------------------------------------------------------------------------
52 namespace Elements
53 {
54 const int32u CLPI=0x48444D56; //HDMV
55 const int32u INDX=0x494E4458;
56 const int32u MOBJ=0x4D4F424A;
57 const int32u MPLS=0x4D504C53;
58 }
59
60 //***************************************************************************
61 // Infos
62 //***************************************************************************
63
64 //---------------------------------------------------------------------------
65 static const char* Clpi_Offsets[]=
66 {
67 "ClipInfo",
68 "SequenceInfo",
69 "ProgramInfo",
70 "CPI",
71 "ClipMark",
72 "ExtensionData",
73 "Reserved",
74 "Reserved",
75 "Reserved",
76 };
77
78 //---------------------------------------------------------------------------
79 static const char* Indx_Offsets[]=
80 {
81 "AppInfoBDMV",
82 "Indexes",
83 "ExtensionData",
84 "Reserved",
85 "Reserved",
86 "Reserved",
87 "Reserved",
88 "Reserved",
89 "Reserved",
90 };
91
92 //---------------------------------------------------------------------------
93 static const char* Mobj_Offsets[]=
94 {
95 "MovieObjects",
96 "Reserved",
97 "Reserved",
98 "Reserved",
99 "Reserved",
100 "Reserved",
101 "Reserved",
102 "Reserved",
103 "Reserved",
104 };
105
106 //---------------------------------------------------------------------------
107 static const char* Mpls_Offsets[]=
108 {
109 "AppInfoPlayList",
110 "PlayList",
111 "PlayListMarks",
112 "ExtensionData",
113 "Reserved",
114 "Reserved",
115 "Reserved",
116 "Reserved",
117 "Reserved",
118 };
119
120 //---------------------------------------------------------------------------
Bdmv_Type(int32u Type_Indicator,size_t Start_Adress_Pos)121 static const char* Bdmv_Type(int32u Type_Indicator, size_t Start_Adress_Pos)
122 {
123 switch (Type_Indicator)
124 {
125 case Elements::CLPI : return Clpi_Offsets[Start_Adress_Pos];
126 case Elements::INDX : return Indx_Offsets[Start_Adress_Pos];
127 case Elements::MOBJ : return Mobj_Offsets[Start_Adress_Pos];
128 case Elements::MPLS : return Mpls_Offsets[Start_Adress_Pos];
129 default : return "";
130 }
131 }
132
133 //---------------------------------------------------------------------------
Clpi_Format(int8u StreamType)134 static const char* Clpi_Format(int8u StreamType)
135 {
136 switch (StreamType)
137 {
138 case 0x01 : return "MPEG-1 Video";
139 case 0x02 : return "MPEG-2 Video";
140 case 0x03 : return "MPEG-1 Audio";
141 case 0x04 : return "MPEG-2 Audio";
142 case 0x1B : return "AVC";
143 case 0x20 : return "AVC";
144 case 0x80 : return "PCM";
145 case 0x81 : return "AC-3";
146 case 0x82 : return "DTS";
147 case 0x83 : return "TrueHD";
148 case 0x84 : return "E-AC-3";
149 case 0x85 : return "DTS";
150 case 0x86 : return "DTS";
151 case 0x90 : return "PGS";
152 case 0x91 : return "Interactive";
153 case 0x92 : return "Subtitle";
154 case 0xA1 : return "E-AC-3"; //Secondary
155 case 0xA2 : return "DTS"; //Secondary
156 case 0xEA : return "VC-1";
157 default : return "";
158 }
159 }
160
161 //---------------------------------------------------------------------------
Clpi_Format_Profile(int8u StreamType)162 static const char* Clpi_Format_Profile(int8u StreamType)
163 {
164 switch (StreamType)
165 {
166 case 0x85 : return "HD";
167 case 0x86 : return "MA";
168 case 0xA2 : return "HD"; //Secondary
169 default : return "";
170 }
171 }
172
173 //---------------------------------------------------------------------------
Clpi_Type(int8u StreamType)174 static stream_t Clpi_Type(int8u StreamType)
175 {
176 switch (StreamType)
177 {
178 case 0x01 : return Stream_Video;
179 case 0x02 : return Stream_Video;
180 case 0x03 : return Stream_Audio;
181 case 0x04 : return Stream_Audio;
182 case 0x1B : return Stream_Video;
183 case 0x20 : return Stream_Video;
184 case 0x80 : return Stream_Audio;
185 case 0x81 : return Stream_Audio;
186 case 0x82 : return Stream_Audio;
187 case 0x83 : return Stream_Audio;
188 case 0x84 : return Stream_Audio;
189 case 0x85 : return Stream_Audio;
190 case 0x86 : return Stream_Audio;
191 case 0x90 : return Stream_Text;
192 case 0x91 : return Stream_Max;
193 case 0x92 : return Stream_Text;
194 case 0xA1 : return Stream_Audio;
195 case 0xA2 : return Stream_Audio;
196 case 0xEA : return Stream_Video;
197 default : return Stream_Max;
198 }
199 }
200
201 //---------------------------------------------------------------------------
202 static const char* Clpi_Video_Format[]=
203 {
204 "",
205 "480i",
206 "576i",
207 "480p",
208 "1080i",
209 "720p",
210 "1080p",
211 "576p",
212 "",
213 "",
214 "",
215 "",
216 "",
217 "",
218 "",
219 "",
220 };
221
222 //---------------------------------------------------------------------------
223 static const char* Clpi_Video_Interlacement[]=
224 {
225 "",
226 "Interlaced",
227 "Interlaced",
228 "PPF",
229 "Interlaced",
230 "PPF",
231 "PPF",
232 "PPF",
233 "",
234 "",
235 "",
236 "",
237 "",
238 "",
239 "",
240 "",
241 };
242
243 //---------------------------------------------------------------------------
244 static const char* Clpi_Video_Standard[]=
245 {
246 "",
247 "NTSC",
248 "PAL",
249 "NTSC",
250 "",
251 "",
252 "",
253 "PAL",
254 "",
255 "",
256 "",
257 "",
258 "",
259 "",
260 "",
261 "",
262 };
263
264 //---------------------------------------------------------------------------
265 static const int16u Clpi_Video_Width[]=
266 {
267 0,
268 720,
269 720,
270 720,
271 1920,
272 1280,
273 1920,
274 720,
275 0,
276 0,
277 0,
278 0,
279 0,
280 0,
281 0,
282 0,
283 };
284
285 //---------------------------------------------------------------------------
286 static const int16u Clpi_Video_Height[]=
287 {
288 0,
289 480,
290 576,
291 480,
292 1080,
293 720,
294 1080,
295 576,
296 0,
297 0,
298 0,
299 0,
300 0,
301 0,
302 0,
303 0,
304 };
305
306 //---------------------------------------------------------------------------
307 static const float32 Clpi_Video_FrameRate[]=
308 {
309 (float32) 0.000,
310 (float32)23.976,
311 (float32)24.000,
312 (float32)25.000,
313 (float32)29.970,
314 (float32) 0.000,
315 (float32)50.000,
316 (float32)59.940,
317 (float32) 0.000,
318 (float32) 0.000,
319 (float32) 0.000,
320 (float32) 0.000,
321 (float32) 0.000,
322 (float32) 0.000,
323 (float32) 0.000,
324 (float32) 0.000,
325 };
326
327 //---------------------------------------------------------------------------
328 static const float32 Clpi_Video_AspectRatio[]=
329 {
330 (float32)0.000,
331 (float32)0.000,
332 (float32)1.333,
333 (float32)1.778,
334 (float32)2.210,
335 (float32)0.000,
336 (float32)0.000,
337 (float32)0.000,
338 (float32)0.000,
339 (float32)0.000,
340 (float32)0.000,
341 (float32)0.000,
342 (float32)0.000,
343 (float32)0.000,
344 (float32)0.000,
345 (float32)0.000,
346 };
347
348 //---------------------------------------------------------------------------
349 static const int8u Clpi_Audio_Channels[]=
350 {
351 0,
352 1,
353 0,
354 2,
355 0,
356 0,
357 0, //Multi 6-8
358 0,
359 0,
360 0,
361 0,
362 0,
363 0, //Combo
364 0,
365 0,
366 0,
367 };
368
369 //---------------------------------------------------------------------------
370 static const int32u Clpi_Audio_SamplingRate[]=
371 {
372 0,
373 48000,
374 0,
375 0,
376 96000,
377 192000,
378 0,
379 0,
380 0,
381 0,
382 0,
383 0,
384 48000, //192000?
385 48000, // 96000?
386 0,
387 0,
388 };
389
390 //---------------------------------------------------------------------------
391 static const char* Indx_object_type[]=
392 {
393 "",
394 "HDMV",
395 "BD-J",
396 "",
397 };
398
399 //---------------------------------------------------------------------------
400 static const char* Indx_playback_type[4][4]=
401 {
402 {"", "", "", "", },
403 {"Movie", "Interactive", "", "", },
404 {"", "", "Movie", "Interactive", },
405 {"", "", "", "", },
406 };
407
408 //---------------------------------------------------------------------------
409 static const char* Indx_title_search[]=
410 {
411 "Permitted",
412 "Prohibited1",
413 "Prohibited2",
414 "",
415 };
416
417 //---------------------------------------------------------------------------
418 static const char* Mpls_playback_type[]=
419 {
420 "Sequential",
421 "Random",
422 "Shuffle",
423 "",
424 };
425
426 //---------------------------------------------------------------------------
Mpls_PlayListMarks_Mark_type(int8u type)427 static const char* Mpls_PlayListMarks_Mark_type(int8u type)
428 {
429 switch (type)
430 {
431 case 1 : return "entry-mark";
432 case 2 : return "link point";
433 default: return "";
434 }
435 }
436
437 //***************************************************************************
438 // Helpers
439 //***************************************************************************
440
441 //---------------------------------------------------------------------------
Bdmv_Decimal_Hexa(int64u Number)442 static Ztring Bdmv_Decimal_Hexa(int64u Number)
443 {
444 return Get_Hex_ID(Number);
445 }
446
447 //***************************************************************************
448 // Buffer - File header
449 //***************************************************************************
450
451 //---------------------------------------------------------------------------
FileHeader_Begin()452 bool File_Bdmv::FileHeader_Begin()
453 {
454 size_t BDMV_Pos=File_Name.find(Ztring(1, PathSeparator)+__T("BDMV"));
455 if (BDMV_Pos!=string::npos && BDMV_Pos+5==File_Name.size()) //Blu-ray directory
456 return true;
457
458 //Element_Size
459 if (Buffer_Size<4)
460 return false; //Must wait for more data
461
462 switch (CC4(Buffer))
463 {
464 case Elements::CLPI :
465 case Elements::INDX :
466 case Elements::MOBJ :
467 case Elements::MPLS :
468 break;
469 default : Reject("Blu-ray");
470 return false;
471 }
472
473 //Init
474 Mpls_PlayList_IsParsed=false;
475
476 //All should be OK...
477 return true;
478 }
479
480 //***************************************************************************
481 // Buffer - Global
482 //***************************************************************************
483
484 //---------------------------------------------------------------------------
Read_Buffer_Continue()485 void File_Bdmv::Read_Buffer_Continue()
486 {
487 size_t BDMV_Pos=File_Name.find(Ztring(1, PathSeparator)+__T("BDMV"));
488 if (BDMV_Pos!=string::npos && BDMV_Pos+5==File_Name.size()) //Blu-ray directory
489 {
490 BDMV();
491 return;
492 }
493
494 if (Buffer_Size<File_Size)
495 {
496 Element_WaitForMoreData();
497 return; //Wait for more data
498 }
499
500 //Parsing
501 int32u type_indicator;
502 int16u version_numberH;
503 Element_Begin1("Header");
504 Get_C4 (type_indicator, "type_indicator");
505 Data_Accept("Blu-ray");
506 Get_C2 (version_numberH, "version_number (High)");
507 Skip_C2( "version_number (Low)");
508 Element_End0();
509
510 FILLING_BEGIN();
511 Accept("BDMV");
512 switch (type_indicator)
513 {
514 case Elements::CLPI : Fill(Stream_General, 0, General_Format, "Blu-ray Clip info"); break;
515 case Elements::INDX : Fill(Stream_General, 0, General_Format, "Blu-ray Index"); break;
516 case Elements::MOBJ : Fill(Stream_General, 0, General_Format, "Blu-ray Movie object"); break;
517 case Elements::MPLS : Fill(Stream_General, 0, General_Format, "Blu-ray Playlist"); break;
518 default : ;
519 }
520 FILLING_END();
521
522 if (version_numberH==0x3031 || version_numberH==0x3032 || version_numberH==0x3033) //Version 1, 2 or 3 (3 = UHD Blu-ray)
523 {
524 Element_Begin1("Offsets");
525 Types[0x28]=0; //First object
526 for (size_t Start_Adress_Pos=1; Start_Adress_Pos<9; Start_Adress_Pos++)
527 {
528 int32u Start_Adress;
529 Get_B4 (Start_Adress, Bdmv_Type(type_indicator, Start_Adress_Pos));
530 Types[Start_Adress]=Start_Adress_Pos;
531 }
532 Element_End0();
533
534 for (std::map<int32u, size_t>::iterator Type=Types.begin(); Type!=Types.end(); ++Type)
535 {
536 if (Type->first>=Element_Offset) //If valid
537 {
538 if (Type->first>Element_Offset)
539 Skip_XX(Type->first-Element_Offset, "unknown");
540
541 Element_Begin1(Bdmv_Type(type_indicator, Type->second));
542 int32u length;
543 Get_B4 (length, "length");
544 int64u End=Element_Offset+length;
545 switch (type_indicator)
546 {
547 case Elements::CLPI :
548 switch(Type->second)
549 {
550 case 2 : Clpi_ProgramInfo(); break;
551 case 5 : Clpi_ExtensionData(); break;
552 default: ;
553 }
554 break;
555 case Elements::INDX :
556 switch(Type->second)
557 {
558 case 0 : Indx_AppInfoBDMV(); break;
559 case 1 : Indx_Indexes(); break;
560 case 2 : Indx_ExtensionData(); break;
561 default: ;
562 }
563 break;
564 case Elements::MOBJ :
565 switch(Type->second)
566 {
567 case 0 : Mobj_MovieObjects(); break;
568 case 1 : Mobj_ExtensionData(); break;
569 default: ;
570 }
571 break;
572 case Elements::MPLS :
573 switch(Type->second)
574 {
575 case 0 : Mpls_AppInfoPlayList(); break;
576 case 1 : Mpls_PlayList(); break;
577 case 2 : Mpls_PlayListMarks (); break;
578 case 3 : Mpls_ExtensionData (); break;
579 default: ;
580 }
581 break;
582 default : ;
583 }
584 if (End>Element_Offset)
585 Skip_XX(End-Element_Offset, "Unknown");
586 Element_End0();
587 }
588 }
589
590 if (Element_Size>Element_Offset)
591 Skip_XX(Element_Size-Element_Offset, "Unknown");
592 }
593 else
594 Skip_XX(Element_Size-Element_Offset, "Unknown");
595 }
596
597 //***************************************************************************
598 // Elements
599 //***************************************************************************
600
601 //---------------------------------------------------------------------------
BDMV()602 void File_Bdmv::BDMV()
603 {
604 Accept("BDMV");
605
606 //Searching the longest playlist
607 #if defined(MEDIAINFO_DIRECTORY_YES)
608 ZtringList List=Dir::GetAllFileNames(File_Name+PathSeparator+__T("PLAYLIST")+PathSeparator+__T("*.mpls"), Dir::Include_Files);
609 std::vector<MediaInfo_Internal*> MIs;
610 MIs.resize(List.size());
611 size_t MaxDuration_Pos=(size_t)-1;
612 int64u MaxDuration=0;
613 if (Config->File_Bdmv_ParseTargetedFile_Get())
614 {
615 for (size_t Pos=0; Pos<MIs.size(); Pos++)
616 {
617 MIs[Pos]=new MediaInfo_Internal();
618 MIs[Pos]->Option(__T("File_Bdmv_ParseTargetedFile"), __T("0"));
619 MIs[Pos]->Option(__T("File_IsReferenced"), __T("1"));
620 MIs[Pos]->Open(List[Pos]);
621 int64u Duration=Ztring(MIs[Pos]->Get(Stream_General, 0, General_Duration)).To_int64u();
622 if (Duration>MaxDuration)
623 {
624 MaxDuration=Duration;
625 MaxDuration_Pos=Pos;
626 }
627 }
628 }
629
630 if (MaxDuration_Pos!=(size_t)-1)
631 {
632 //Merging
633 MediaInfo_Internal MI;
634 MI.Option(__T("File_IsReferenced"), __T("1"));
635 MI.Open(List[MaxDuration_Pos]); //Open it again for having the M2TS part
636 Merge(MI);
637
638 Clear(Stream_General, 0, General_Format);
639 Clear(Stream_General, 0, General_Format_String);
640 Clear(Stream_General, 0, General_Format_Extensions);
641 Clear(Stream_General, 0, General_Format_Info);
642 Clear(Stream_General, 0, General_Codec);
643 Clear(Stream_General, 0, General_Codec_String);
644 Clear(Stream_General, 0, General_Codec_Extensions);
645 Clear(Stream_General, 0, General_FileSize);
646 Clear(Stream_Video, 0, Video_ScanType_String);
647 Clear(Stream_Video, 0, Video_Bits__Pixel_Frame_);
648 }
649
650 for (size_t Pos=0; Pos<MIs.size(); Pos++)
651 delete MIs[Pos]; //MIs[Pos]=NULL;
652 MIs.clear();
653
654 //Detecting some directories
655 if (Dir::Exists(File_Name+PathSeparator+__T("BDSVM"))
656 || Dir::Exists(File_Name+PathSeparator+__T("SLYVM"))
657 || Dir::Exists(File_Name+PathSeparator+__T("ANYVM")))
658 Fill(Stream_General, 0, General_Format_Profile, "BD+");
659 if (Dir::Exists(File_Name+PathSeparator+__T("BDJO")) && !Dir::GetAllFileNames(File_Name+PathSeparator+__T("BDJO")).empty())
660 Fill(Stream_General, 0, General_Format_Profile, "BD-Java");
661 #endif //defined(MEDIAINFO_DIRECTORY_YES)
662
663 //Filling
664 File_Name.resize(File_Name.size()-5); //Removing "/BDMV"
665 Fill(Stream_General, 0, General_Format, "Blu-ray movie", Unlimited, true, true);
666 Fill(Stream_General, 0, General_CompleteName, File_Name, true);
667 Fill(Stream_General, 0, General_FolderName, FileName::Path_Get(File_Name), true);
668 if (FileName::Extension_Get(File_Name).empty())
669 Fill(Stream_General, 0, General_FileName, FileName::Name_Get(File_Name), true);
670 else
671 Fill(Stream_General, 0, General_FileName, FileName::Name_Get(File_Name)+__T('.')+FileName::Extension_Get(File_Name), true);
672 File_Name.clear();
673
674 Finish("BDMV");
675 }
676
677 //---------------------------------------------------------------------------
Clpi_ProgramInfo()678 void File_Bdmv::Clpi_ProgramInfo()
679 {
680 //Retrieving data from the M2TS file
681 std::map<int16u, stream_t> PIDs_StreamKind;
682 std::map<int16u, size_t> PIDs_StreamPos;
683 if (Config->File_Bdmv_ParseTargetedFile_Get() && File_Name.size()>10+1+7)
684 {
685 Ztring file=File_Name.substr(File_Name.size()-10, 5);
686 Ztring M2TS_File=File_Name;
687 M2TS_File.resize(M2TS_File.size()-(10+1+7));
688 M2TS_File+=__T("STREAM");
689 M2TS_File+=PathSeparator;
690 M2TS_File+=file;
691 M2TS_File+=__T(".m2ts");
692
693 MediaInfo_Internal MI;
694 MI.Option(__T("File_Bdmv_ParseTargetedFile"), __T("0"));
695 MI.Option(__T("File_IsReferenced"), __T("1"));
696 if (MI.Open(M2TS_File))
697 {
698 Merge(MI);
699 for (size_t StreamKind=Stream_General+1; StreamKind<Stream_Max; StreamKind++)
700 for (size_t StreamPos=0; StreamPos<Count_Get((stream_t)StreamKind); StreamPos++)
701 Fill((stream_t)StreamKind, StreamPos, "Source", file+__T(".m2ts"));
702 }
703
704 //Retrieving PID mapping
705 for (size_t StreamKind=(size_t)Stream_General+1; StreamKind<(size_t)Stream_Max; StreamKind++)
706 for (size_t StreamPos=0; StreamPos<Count_Get((stream_t)StreamKind); StreamPos++)
707 {
708 int16u PID=Retrieve((stream_t)StreamKind, StreamPos, General_ID).To_int16u();
709 PIDs_StreamKind[PID]=(stream_t)StreamKind;
710 PIDs_StreamPos[PID]=StreamPos;
711 }
712 }
713
714 //Parsing
715 int8u number_of_program_sequences;
716 Skip_B1( "Unknown");
717 Get_B1 (number_of_program_sequences, "number_of_program_sequences");
718 for (int8u program_sequence=0; program_sequence<number_of_program_sequences; program_sequence++)
719 {
720 int8u number_of_streams_in_ps;
721 Skip_B4( "Unknown");
722 Skip_B2( "program_map_PID");
723 Get_B1 (number_of_streams_in_ps, "number_of_streams_in_ps");
724 Skip_B1( "Unknown");
725 for (int16u Pos=0; Pos<number_of_streams_in_ps; Pos++)
726 {
727 Element_Begin1("Stream");
728 int16u stream_PID;
729 int8u Stream_Length;
730 Get_B2 (stream_PID, "stream_PID");
731 Get_B1 (Stream_Length, "Length");
732 int64u Stream_End=Element_Offset+Stream_Length;
733 StreamKind_Last=Stream_Max;
734 std::map<int16u, stream_t>::iterator PID_StreamKind=PIDs_StreamKind.find(stream_PID);
735 if (PID_StreamKind!=PIDs_StreamKind.end())
736 {
737 StreamKind_Last=PID_StreamKind->second;
738 StreamPos_Last=PIDs_StreamPos.find(stream_PID)->second;
739 }
740 Get_B1 (stream_type, "Stream type"); Param_Info1(Clpi_Format(stream_type)); Element_Info1(Clpi_Format(stream_type));
741 switch (Clpi_Type(stream_type))
742 {
743 case Stream_Video : StreamCodingInfo_Video(); break;
744 case Stream_Audio : StreamCodingInfo_Audio(); break;
745 case Stream_Text : StreamCodingInfo_Text() ; break;
746 default : ;
747 }
748
749 if (Stream_End-Element_Offset)
750 Skip_XX(Stream_End-Element_Offset, "Unknown");
751 Element_End0();
752
753 FILLING_BEGIN();
754 if (StreamKind_Last!=Stream_Max)
755 {
756 Fill(StreamKind_Last, StreamPos_Last, General_ID, stream_PID, 10, true);
757 Fill(StreamKind_Last, StreamPos_Last, General_ID_String, Bdmv_Decimal_Hexa(stream_PID), true);
758 }
759 FILLING_END();
760 }
761 }
762 }
763
764 struct entry
765 {
766 int16u ID1;
767 int16u ID2;
768 int32u Length;
769 };
770 typedef std::map<int32u, entry> entries; //Key is the start address
771
772 //---------------------------------------------------------------------------
Clpi_ExtensionData()773 void File_Bdmv::Clpi_ExtensionData()
774 {
775 entries Entries; //Key is the start address
776
777 int32u Base_Pos=(int32u)Element_Offset-4;
778
779 int8u number_of_ext_data_entries;
780 Skip_B4( "Unknown");
781 Skip_B3( "Unknown");
782 Element_Begin1("Offsets");
783 Get_B1 (number_of_ext_data_entries, "number_of_ext_data_entries");
784 for (size_t Start_Adress_Pos=0; Start_Adress_Pos<number_of_ext_data_entries; Start_Adress_Pos++)
785 {
786 int32u Start_Adress, Length;
787 int16u ID1, ID2;
788 Get_B2 (ID1, "ID1");
789 Get_B2 (ID2, "ID2");
790 Get_B4 (Start_Adress, "Start_Adress");
791 Get_B4 (Length, "Length");
792 Entries[Base_Pos+Start_Adress].ID1=ID1;
793 Entries[Base_Pos+Start_Adress].ID2=ID2;
794 Entries[Base_Pos+Start_Adress].Length=Length;
795 }
796 Element_End0();
797
798 for (entries::iterator Entry=Entries.begin(); Entry!=Entries.end(); ++Entry)
799 {
800 if (Entry->first>=Element_Offset) //If valid
801 {
802 if (Entry->first>Element_Offset)
803 Skip_XX(Entry->first-Element_Offset, "unknown");
804
805 Element_Begin1("Entry");
806 int32u length;
807 Get_B4 (length, "length");
808 int64u End=Element_Offset+length;
809 switch (Entry->second.ID1)
810 {
811 case 0x0002 :
812 switch(Entry->second.ID2)
813 {
814 case 0x0005 : Clpi_ProgramInfo(); break;
815 default: ;
816 }
817 break;
818 default : ;
819 }
820 if (End>Element_Offset)
821 Skip_XX(End-Element_Offset, "Unknown");
822 Element_End0();
823 }
824 }
825
826 if (Element_Size>Element_Offset)
827 Skip_XX(Element_Size-Element_Offset, "Unknown");
828 }
829
830 //---------------------------------------------------------------------------
Indx_AppInfoBDMV()831 void File_Bdmv::Indx_AppInfoBDMV()
832 {
833 //Parsing
834 Skip_B2( "reserved");
835 Skip_Local(32, "user_data");
836 }
837
838 //---------------------------------------------------------------------------
Indx_Indexes()839 void File_Bdmv::Indx_Indexes()
840 {
841 //Parsing
842 int16u number_of_Titles;
843 Element_Begin1("FirstPlayback");
844 BS_Begin();
845 int8u FirstPlayback_object_type;
846 Get_S1 ( 2, FirstPlayback_object_type, "object_type"); Param_Info1(Indx_object_type[FirstPlayback_object_type]);
847 Skip_S4(30, "reserved");
848 BS_End();
849 Indx_Indexes_Index(FirstPlayback_object_type);
850 Element_End0();
851 Element_Begin1("TopMenu");
852 BS_Begin();
853 int8u TopMenu_object_type;
854 Get_S1 ( 2, TopMenu_object_type, "object_type"); Param_Info1(Indx_object_type[TopMenu_object_type]);
855 Skip_S4(30, "reserved");
856 BS_End();
857 Indx_Indexes_Index(TopMenu_object_type);
858 Element_End0();
859 Get_B2 (number_of_Titles, "number_of_Titles");
860 for (int16u Pos=0; Pos<number_of_Titles; Pos++)
861 {
862 Element_Begin1("Title");
863 BS_Begin();
864 int8u Title_object_type;
865 Get_S1 ( 2, Title_object_type, "object_type"); Param_Info1(Indx_object_type[Title_object_type]);
866 Info_S1( 2, Title_title_search, "title_search"); Param_Info1(Indx_title_search[Title_title_search]);
867 Skip_S4(28, "reserved");
868 BS_End();
869 Indx_Indexes_Index(Title_object_type);
870 Element_End0();
871 }
872 }
873
874 //---------------------------------------------------------------------------
Indx_Indexes_Index(int8u object_type)875 void File_Bdmv::Indx_Indexes_Index(int8u object_type)
876 {
877 BS_Begin();
878 Info_S1( 2, playback_type, "playback_type"); Param_Info1(Indx_playback_type[object_type][playback_type]);
879 Skip_S2(14, "reserved");
880 BS_End();
881 switch (object_type)
882 {
883 case 1 : //HDMV
884 {
885 Info_B2(id_ref, "id_ref"); Element_Info1(id_ref);
886 Skip_B4( "reserved");
887 }
888 break;
889 case 2 : //BD-J
890 {
891 Info_Local(5, id_ref, "id_ref"); Element_Info1(id_ref);
892 Skip_B1( "reserved");
893 }
894 break;
895 default:
896 Skip_XX(6, "unknown");
897 }
898 }
899
900 //---------------------------------------------------------------------------
Indx_ExtensionData()901 void File_Bdmv::Indx_ExtensionData()
902 {
903 //Parsing
904 std::map<int32u, int32u> exts; //Key is the start address, value is length
905 int64u Base_Offset=Element_Offset-4; //Size is included
906 int8u number_of_ext_data_entries;
907 Skip_B4( "data_block_start_adress");
908 Skip_B3( "reserved");
909 Get_B1 (number_of_ext_data_entries, "number_of_ext_data_entries");
910 for (int16u Pos=0; Pos<number_of_ext_data_entries; Pos++)
911 {
912 Element_Begin1("ext_data_entry");
913 int32u ext_data_start_adress, ext_data_length;
914 Skip_B2( "ID1 (AVCHD)");
915 Skip_B2( "ID2 (Version)");
916 Get_B4 (ext_data_start_adress, "ext_data_start_adress");
917 Get_B4 (ext_data_length, "ext_data_length");
918 Element_End0();
919 exts[ext_data_start_adress]=ext_data_length;
920 }
921
922 for (std::map<int32u, int32u>::iterator ext=exts.begin(); ext!=exts.end(); ++ext)
923 {
924 if (Base_Offset+ext->first>=Element_Offset)
925 {
926 if (Base_Offset+ext->first>Element_Offset)
927 Skip_XX(ext->first-Element_Offset, "Unknown");
928
929 Element_Begin0();
930 int64u End=Element_Offset+ext->second;
931
932 int32u type_indicator;
933 Get_C4(type_indicator, "type_indicator"); Element_Info1(Ztring().From_CC4(type_indicator));
934 switch (type_indicator)
935 {
936 case 0x49444558 : Indx_ExtensionData_IDEX(); break;
937 default : Element_Name("Unknown");
938 Skip_XX(ext->second-4, "Unknown");
939 }
940 if (End>Element_Offset)
941 Skip_XX(End-Element_Offset, "Unknown");
942 Element_End0();
943 }
944 }
945 }
946
947 //---------------------------------------------------------------------------
Indx_ExtensionData_IDEX()948 void File_Bdmv::Indx_ExtensionData_IDEX()
949 {
950 Element_Name("IndexExtension");
951
952 //Parsing
953 int64u Base_Offset=Element_Offset-4; //Size is included
954 int32u TableOfPlayLists_start_adress, MakersPrivateData_start_adress;
955 Skip_B4( "reserved");
956 Get_B4 (TableOfPlayLists_start_adress, "TableOfPlayLists_start_adress");
957 Get_B4 (MakersPrivateData_start_adress, "MakersPrivateData_start_adress");
958 Skip_XX(24, "reserved");
959
960 Indx_ExtensionData_IDEX_UIAppInfoAVCHD();
961 if (TableOfPlayLists_start_adress)
962 {
963 if (Base_Offset+TableOfPlayLists_start_adress>Element_Offset)
964 Skip_XX(Base_Offset+TableOfPlayLists_start_adress-Element_Offset, "Unknown");
965 Indx_ExtensionData_IDEX_TableOfPlayLists();
966 }
967 if (MakersPrivateData_start_adress)
968 {
969 if (Base_Offset+MakersPrivateData_start_adress>Element_Offset)
970 Skip_XX(Base_Offset+MakersPrivateData_start_adress-Element_Offset, "Unknown");
971 Indx_ExtensionData_IDEX_MakersPrivateData();
972 }
973 }
974
975 //---------------------------------------------------------------------------
Indx_ExtensionData_IDEX_UIAppInfoAVCHD()976 void File_Bdmv::Indx_ExtensionData_IDEX_UIAppInfoAVCHD()
977 {
978 Element_Begin1("UIAppInfoAVCHD");
979
980 //Parsing
981 int32u length, length2;
982 int8u AVCHD_name_length;
983 Get_B4 (length, "length");
984 Skip_B2( "maker_ID");
985 Skip_B2( "maker_model_code");
986 Skip_XX(32, "maker_private_area");
987 BS_Begin();
988 Skip_BS(15, "reserved");
989 Skip_SB( "AVCHD_write_protect_flag");
990 BS_End();
991 Skip_B2( "ref_to_menu_thumbail_index");
992 Skip_B1( "time_zone");
993 Skip_XX(7, "record_time_and_date");
994 Skip_B1( "reserved");
995 Skip_B1( "AVCHD_character_set");
996 Get_B1 (AVCHD_name_length, "AVCHD_name_length");
997 Skip_Local(AVCHD_name_length, "AVCHD_name");
998 Skip_XX(255-AVCHD_name_length, "AVCHD_name (junk)");
999 Element_Begin1("additional data");
1000 Get_B4 (length2, "length2");
1001 Skip_XX(length2, "reserved");
1002 Element_End0();
1003
1004 Element_End0();
1005 }
1006
1007 //---------------------------------------------------------------------------
Indx_ExtensionData_IDEX_TableOfPlayLists()1008 void File_Bdmv::Indx_ExtensionData_IDEX_TableOfPlayLists()
1009 {
1010 Element_Begin1("TableOfPlayLists");
1011
1012 //Parsing
1013 int32u length;
1014 Get_B4 (length, "length");
1015 Skip_XX(length, "unknown");
1016
1017 Element_End0();
1018 }
1019
1020 //---------------------------------------------------------------------------
Indx_ExtensionData_IDEX_MakersPrivateData()1021 void File_Bdmv::Indx_ExtensionData_IDEX_MakersPrivateData()
1022 {
1023 Element_Begin1("MakersPrivateData");
1024
1025 //Parsing
1026 int64u Base_Offset=Element_Offset-4; //Size is included
1027 int32u length, datablock_start_adress;
1028 int8u number_of_maker_entries;
1029 Get_B4 (length, "length");
1030 Get_B4 (datablock_start_adress, "datablock_start_adress");
1031 Skip_XX(24, "reserved");
1032 Get_B1 (number_of_maker_entries, "number_of_maker_entries");
1033 for (int8u Pos=0; Pos<number_of_maker_entries; Pos++)
1034 {
1035 Element_Begin1("maker_entry");
1036 Skip_B2( "maker_ID");
1037 Skip_B2( "maker_model_code");
1038 Skip_B4( "mpd_start_adress");
1039 Skip_B4( "mpd_length");
1040 Element_End0();
1041 }
1042
1043 if (datablock_start_adress)
1044 {
1045 if (Base_Offset+datablock_start_adress>Element_Offset)
1046 Skip_XX(Base_Offset+datablock_start_adress-Element_Offset, "Unknown");
1047 Skip_XX(length-datablock_start_adress, "Unknown");
1048 }
1049
1050 Element_End0();
1051 }
1052
1053 //---------------------------------------------------------------------------
Mobj_MovieObjects()1054 void File_Bdmv::Mobj_MovieObjects()
1055 {
1056 //Parsing
1057 int16u number_of_mobjs;
1058 Skip_B4( "reserved");
1059 Get_B2 (number_of_mobjs, "number_of_mobj");
1060 for (int16u mobjs_Pos=0; mobjs_Pos<number_of_mobjs; mobjs_Pos++)
1061 {
1062 Element_Begin1("mobj");
1063 int16u number_of_navigation_commands;
1064 BS_Begin();
1065 Info_SB(resume, "resume"); Param_Info1(resume?"suspend":"discard");
1066 Info_SB(menu_call, "menu_call"); Param_Info1(menu_call?"enable":"disable");
1067 Info_SB(title_search, "title_search"); Param_Info1(title_search?"enable":"disable");
1068 Skip_BS(13, "reserved");
1069 BS_End();
1070 Get_B2 (number_of_navigation_commands, "number_of_navigation_commands");
1071 for (int16u navigation_command_Pos=0; navigation_command_Pos<number_of_navigation_commands; navigation_command_Pos++)
1072 {
1073 Element_Begin1("navigation_command");
1074 Skip_B4( "opcode");
1075 Skip_B4( "destination");
1076 Skip_B4( "source");
1077 Element_End0();
1078 }
1079 Element_End0();
1080 }
1081 }
1082
1083 //---------------------------------------------------------------------------
Mobj_ExtensionData()1084 void File_Bdmv::Mobj_ExtensionData()
1085 {
1086 }
1087
1088 //---------------------------------------------------------------------------
Mpls_AppInfoPlayList()1089 void File_Bdmv::Mpls_AppInfoPlayList()
1090 {
1091 //Parsing
1092 Skip_B1( "unknown");
1093 BS_Begin();
1094 Skip_S1(6, "unknown");
1095 Info_S2(2, playback_type, "playback_type"); Param_Info1(Mpls_playback_type[playback_type]);
1096 BS_End();
1097 Skip_B2( "playback_count");
1098 Skip_B4( "user_operation_mask_code 1");
1099 Skip_B4( "user_operation_mask_code 2");
1100 BS_Begin();
1101 Skip_SB( "random access");
1102 Skip_SB( "audio mix");
1103 Skip_SB( "bypass mixer");
1104 Skip_S2(13, "reserved");
1105 BS_End();
1106 }
1107
1108 //---------------------------------------------------------------------------
Mpls_PlayList()1109 void File_Bdmv::Mpls_PlayList()
1110 {
1111 //Parsing
1112 Mpls_PlayList_Duration=0;
1113 int16u number_of_PlayItems, number_of_SubPaths;
1114 Skip_B2( "reserved");
1115 Get_B2 (number_of_PlayItems, "number_of_PlayItems");
1116 Get_B2 (number_of_SubPaths, "number_of_SubPaths");
1117 for (int16u Pos=0; Pos<number_of_PlayItems; Pos++)
1118 Mpls_PlayList_PlayItem();
1119
1120 if (Mpls_PlayList_Duration)
1121 Fill(Stream_General, 0, General_Duration, Mpls_PlayList_Duration/45);
1122
1123 for (int16u SubPath_Pos=0; SubPath_Pos<number_of_SubPaths; SubPath_Pos++)
1124 {
1125 Element_Begin1("SubPath");
1126 int32u SubPath_length;
1127 int16u number_of_SubPlayItems;
1128 int8u SubPath_type;
1129 Get_B4 (SubPath_length, "length");
1130 int64u SubPath_End=Element_Offset+SubPath_length;
1131 Skip_B1( "Unknown");
1132 Get_B1 (SubPath_type, "SubPath_type");
1133 Skip_B2( "repeat");
1134 Get_B2 (number_of_SubPlayItems, "number_of_SubPlayItems");
1135 for (int16u Pos=0; Pos<number_of_SubPlayItems; Pos++)
1136 Mpls_PlayList_SubPlayItem(SubPath_type, Pos);
1137
1138 if (SubPath_End>Element_Offset)
1139 Skip_XX(SubPath_End-Element_Offset, "unknown");
1140 Element_End0();
1141 }
1142
1143 FILLING_BEGIN();
1144 if (!Mpls_PlayList_IsParsed)
1145 {
1146 Mpls_PlayList_number_of_SubPaths=number_of_SubPaths;
1147 Mpls_PlayList_IsParsed=true;
1148 }
1149 FILLING_END();
1150 }
1151
1152 //---------------------------------------------------------------------------
Mpls_PlayList_PlayItem()1153 void File_Bdmv::Mpls_PlayList_PlayItem()
1154 {
1155 Element_Begin1("PlayItem");
1156 Ztring Clip_Information_file_name;
1157 int32u Time_In, Time_Out;
1158 int16u length;
1159 Get_B2 (length, "length");
1160 int64u End=Element_Offset+length;
1161 Get_UTF8 (5, Clip_Information_file_name, "Clip_Information_file_name"); Element_Info1(Clip_Information_file_name);
1162 Skip_Local(4, "Clip_codec_identifier");
1163 Skip_B2( "unknown");
1164 Skip_B1( "Unknown");
1165 Get_B4 (Time_In, "Time (In)"); Param_Info1((float32)Time_In/45000);
1166 Get_B4 (Time_Out, "Time (Out)"); Param_Info1((float32)Time_Out/45000);
1167 Skip_B4( "UO1");
1168 Skip_B4( "UO2");
1169 Skip_B4( "An?");
1170
1171 Mpls_PlayList_PlayItem_Duration=Time_Out-Time_In;
1172 if (Time_Out>Time_In)
1173 Mpls_PlayList_Duration+=Mpls_PlayList_PlayItem_Duration;
1174
1175 std::vector<size_t> StreamCount_Before;
1176 for (size_t StreamKind=Stream_General; StreamKind<Stream_Max; StreamKind++)
1177 StreamCount_Before.push_back(Count_Get((stream_t)StreamKind));
1178
1179 Mpls_PlayList_PlayItem_STN_table();
1180
1181 if (Clip_Information_file_names.find(Clip_Information_file_name)==Clip_Information_file_names.end() && File_Name.size()>10+1+8)
1182 {
1183 Ztring CLPI_File=File_Name;
1184 CLPI_File.resize(CLPI_File.size()-(10+1+8));
1185 CLPI_File+=__T("CLIPINF");
1186 CLPI_File+=PathSeparator;
1187 CLPI_File+=Clip_Information_file_name;
1188 CLPI_File+=__T(".clpi");
1189
1190 MediaInfo_Internal MI;
1191 MI.Option(__T("File_Bdmv_ParseTargetedFile"), Config->File_Bdmv_ParseTargetedFile_Get()?__T("1"):__T("0"));
1192 MI.Option(__T("File_IsReferenced"), __T("1"));
1193 if (MI.Open(CLPI_File))
1194 {
1195 for (size_t StreamKind=Stream_General+1; StreamKind<Stream_Max; StreamKind++)
1196 for (size_t StreamPos=0; StreamPos<MI.Count_Get((stream_t)StreamKind); StreamPos++)
1197 {
1198 while (StreamCount_Before[StreamKind]+StreamPos>=Count_Get((stream_t)StreamKind))
1199 Stream_Prepare((stream_t)StreamKind);
1200 Merge(MI, (stream_t)StreamKind, StreamPos, StreamCount_Before[StreamKind]+StreamPos);
1201 }
1202 }
1203
1204 Clip_Information_file_names.insert(Clip_Information_file_name);
1205 }
1206
1207 if (End>Element_Offset)
1208 Skip_XX(End-Element_Offset, "unknown");
1209 Element_End0();
1210 }
1211
1212 //---------------------------------------------------------------------------
Mpls_PlayList_PlayItem_STN_table()1213 void File_Bdmv::Mpls_PlayList_PlayItem_STN_table()
1214 {
1215 Element_Begin1("STN");
1216
1217 int16u length;
1218 Get_B2 (length, "length");
1219 int64u End=Element_Offset+length;
1220 if (End>Element_Size)
1221 {
1222 Skip_XX(Element_Size-Element_Offset, "Problem");
1223 return;
1224 }
1225 Skip_B2( "unknown");
1226 Skip_B1( "Vi");
1227 Skip_B1( "Au");
1228 Skip_B1( "PG");
1229 Skip_B1( "IG");
1230 Skip_B1( "sV");
1231 Skip_B1( "sA");
1232 Skip_B1( "PIP");
1233 Skip_B1( "unknown");
1234 Skip_B1( "unknown");
1235 Skip_B1( "unknown");
1236 Skip_B1( "unknown");
1237 Skip_B1( "unknown");
1238
1239 while (Element_Offset+16<=End)
1240 {
1241 Element_Begin0();
1242 Ztring language;
1243 int16u mPID;
1244 int8u IDs_length;
1245 Skip_B1( "type");
1246 Skip_B1( "unknown");
1247 Get_B2 (mPID, "mPID"); Element_Name(Ztring::ToZtring(mPID, 16));
1248 Skip_B2( "SPid");
1249 Skip_B2( "sCid");
1250 Skip_B2( "sPID");
1251 Get_B1 (IDs_length, "length");
1252 int64u IDs_End=Element_Offset+IDs_length;
1253 Get_B1 (stream_type, "stream_type"); Param_Info1(Clpi_Format(stream_type)); Element_Info1(Clpi_Format(stream_type));
1254 switch (Clpi_Type(stream_type))
1255 {
1256 case Stream_Video : Mpls_PlayList_PlayItem_STN_table_Video(); break;
1257 case Stream_Audio : Mpls_PlayList_PlayItem_STN_table_Audio(); break;
1258 case Stream_Text : Mpls_PlayList_PlayItem_STN_table_Text() ; break;
1259 default : StreamKind_Last=Stream_Max;
1260 }
1261 Get_UTF8(3, language, "language"); Element_Info1(language);
1262
1263 if (IDs_End-Element_Offset)
1264 Skip_XX(IDs_End-Element_Offset, "unknown");
1265 Element_End0();
1266
1267 FILLING_BEGIN();
1268 if (StreamKind_Last!=Stream_Max)
1269 {
1270 if (mPID)
1271 {
1272 Fill(StreamKind_Last, StreamPos_Last, General_ID, mPID, 10, true);
1273 Fill(StreamKind_Last, StreamPos_Last, General_ID_String, Bdmv_Decimal_Hexa(mPID), true);
1274 }
1275 Fill(StreamKind_Last, StreamPos_Last, "Language", language);
1276 Fill(StreamKind_Last, StreamPos_Last, Fill_Parameter(StreamKind_Last, Generic_Duration), Mpls_PlayList_PlayItem_Duration/45);
1277 }
1278 FILLING_END();
1279 }
1280
1281 if (End>Element_Offset)
1282 Skip_XX(End-Element_Offset, "unknown");
1283 Element_End0();
1284 }
1285
1286 //---------------------------------------------------------------------------
Mpls_PlayList_PlayItem_STN_table_Video()1287 void File_Bdmv::Mpls_PlayList_PlayItem_STN_table_Video()
1288 {
1289 //Parsing
1290 int8u Format, FrameRate;
1291 BS_Begin();
1292 Get_S1 (4, Format, "format"); Param_Info1(Clpi_Video_Format[Format]);
1293 Get_S1 (4, FrameRate, "frame_rate"); Param_Info1(Clpi_Video_FrameRate[FrameRate]);
1294 BS_End();
1295
1296 FILLING_BEGIN();
1297 Stream_Prepare(Stream_Video);
1298 Fill(Stream_Video, StreamPos_Last, Video_Format, Clpi_Format(stream_type));
1299 if (Clpi_Video_Width[Format])
1300 Fill(Stream_Video, StreamPos_Last, Video_Width, Clpi_Video_Width[Format]);
1301 if (Clpi_Video_Height[Format])
1302 Fill(Stream_Video, StreamPos_Last, Video_Height, Clpi_Video_Height[Format]);
1303 Fill(Stream_Video, StreamPos_Last, Video_Interlacement, Clpi_Video_Interlacement[Format]);
1304 Fill(Stream_Video, StreamPos_Last, Video_Standard, Clpi_Video_Standard[Format]);
1305 if (Clpi_Video_FrameRate[FrameRate])
1306 Fill(Stream_Video, StreamPos_Last, Video_FrameRate, Clpi_Video_FrameRate[FrameRate]);
1307 FILLING_END();
1308 }
1309
1310 //---------------------------------------------------------------------------
Mpls_PlayList_PlayItem_STN_table_Audio()1311 void File_Bdmv::Mpls_PlayList_PlayItem_STN_table_Audio()
1312 {
1313 //Parsing
1314 int8u Channels, SamplingRate;
1315 BS_Begin();
1316 Get_S1 (4, Channels, "channel_layout"); Param_Info1(Clpi_Audio_Channels[Channels]);
1317 Get_S1 (4, SamplingRate, "sampling_rate"); Param_Info1(Clpi_Audio_SamplingRate[SamplingRate]);
1318 BS_End();
1319
1320 FILLING_BEGIN();
1321 Stream_Prepare(Stream_Audio);
1322 Fill(Stream_Audio, StreamPos_Last, Audio_Format, Clpi_Format(stream_type));
1323 Fill(Stream_Audio, StreamPos_Last, Audio_Format_Profile, Clpi_Format_Profile(stream_type));
1324 if (Clpi_Audio_Channels[Channels])
1325 Fill(Stream_Audio, StreamPos_Last, Audio_Channel_s_, Clpi_Audio_Channels[Channels]);
1326 if (Clpi_Audio_SamplingRate[SamplingRate])
1327 Fill(Stream_Audio, StreamPos_Last, Audio_SamplingRate, Clpi_Audio_SamplingRate[SamplingRate]);
1328 FILLING_END();
1329 }
1330
1331 //---------------------------------------------------------------------------
Mpls_PlayList_PlayItem_STN_table_Text()1332 void File_Bdmv::Mpls_PlayList_PlayItem_STN_table_Text()
1333 {
1334 //Parsing
1335 if (stream_type==0x92) //Subtitle
1336 Skip_B1( "Unknown");
1337
1338 FILLING_BEGIN();
1339 Stream_Prepare(Stream_Text);
1340 Fill(Stream_Text, StreamPos_Last, Text_Format, Clpi_Format(stream_type));
1341 FILLING_END();
1342 }
1343
1344 //---------------------------------------------------------------------------
Mpls_PlayList_SubPlayItem(int8u SubPath_type,int16u Pos)1345 void File_Bdmv::Mpls_PlayList_SubPlayItem(int8u SubPath_type, int16u Pos)
1346 {
1347 Element_Begin1("SubPlayItem");
1348 Ztring Clip_Information_file_name;
1349 int16u length;
1350 Get_B2 (length, "length");
1351 int64u End=Element_Offset+length;
1352 Get_UTF8 (5, Clip_Information_file_name, "Clip_Information_file_name"); Element_Info1(Clip_Information_file_name);
1353 Skip_Local(4, "Clip_codec_identifier");
1354 Skip_B4( "unknown");
1355 Skip_B1( "unknown");
1356 Info_B4(Time_In, "time (in)"); Param_Info1((float32)Time_In/45000);
1357 Info_B4(Time_Out, "time (out)"); Param_Info1((float32)Time_Out/45000);
1358 Skip_B2( "sync PI");
1359 Skip_B4( "sync PTS");
1360
1361 if (End>Element_Offset)
1362 Skip_XX(End-Element_Offset, "unknown");
1363 Element_End0();
1364
1365 FILLING_BEGIN();
1366 if (SubPath_type==8 && Pos!=(int16u)-1) //MVC
1367 {
1368 if (File_Name.size()>=10+1+8)
1369 {
1370 Ztring CLPI_File=File_Name;
1371 CLPI_File.resize(CLPI_File.size()-(10+1+8));
1372 CLPI_File+=__T("CLIPINF");
1373 CLPI_File+=PathSeparator;
1374 CLPI_File+=Clip_Information_file_name;
1375 CLPI_File+=__T(".clpi");
1376
1377 MediaInfo_Internal MI;
1378 MI.Option(__T("File_Bdmv_ParseTargetedFile"), Config->File_Bdmv_ParseTargetedFile_Get()?__T("1"):__T("0"));
1379 MI.Option(__T("File_IsReferenced"), __T("1"));
1380 if (MI.Open(CLPI_File))
1381 {
1382 if (MI.Count_Get(Stream_Video))
1383 {
1384 Ztring ID=Retrieve(Stream_Video, Pos, Video_ID);
1385 Ztring ID_String=Retrieve(Stream_Video, Pos, Video_ID_String);
1386 Ztring Format_Profile=Retrieve(Stream_Video, Pos, Video_Format_Profile);
1387 Ztring BitRate=Retrieve(Stream_Video, Pos, Video_BitRate);
1388 Ztring Source=Retrieve(Stream_Video, Pos, "Source");
1389 Fill(Stream_Video, Pos, Video_ID, MI.Get(Stream_Video, 0, Video_ID)+__T(" / ")+ID, true);
1390 Fill(Stream_Video, Pos, Video_ID_String, MI.Get(Stream_Video, 0, Video_ID_String)+__T(" / ")+ID_String, true);
1391 if (!Format_Profile.empty())
1392 Fill(Stream_Video, Pos, Video_Format_Profile, MI.Get(Stream_Video, 0, Video_Format_Profile)+__T(" / ")+Format_Profile, true);
1393 if (!BitRate.empty())
1394 Fill(Stream_Video, Pos, Video_BitRate, Ztring::ToZtring(BitRate.To_int32u()+MI.Get(Stream_Video, 0, Video_BitRate).To_int32u())+__T(" / ")+BitRate, true);
1395 if (!Source.empty())
1396 Fill(Stream_Video, Pos, "Source", Clip_Information_file_name +__T(".m2ts / ")+Source, true);
1397 }
1398 }
1399 }
1400 }
1401 FILLING_END();
1402 }
1403
1404 //---------------------------------------------------------------------------
Mpls_PlayListMarks()1405 void File_Bdmv::Mpls_PlayListMarks()
1406 {
1407 Stream_Prepare(Stream_Menu);
1408 Fill(Stream_Menu, StreamPos_Last, Menu_Chapters_Pos_Begin, Count_Get(Stream_Menu, StreamPos_Last), 10, true);
1409
1410 //Parsing
1411 int32u time_Pos0=0, time_Pos=1;
1412 int16u count;
1413 Get_B2 (count, "count");
1414 for (int16u Pos=0; Pos<count; Pos++)
1415 {
1416 Element_Begin1("Mark");
1417 int8u type;
1418 Skip_B1( "unknown");
1419 Get_B1 (type, "type"); Param_Info1(Mpls_PlayListMarks_Mark_type(type));
1420 switch (type)
1421 {
1422 case 1 : //entry-mark
1423 case 2 : //link point
1424 {
1425 int32u time;
1426 int16u stream_file_index;
1427 Get_B2 (stream_file_index, "stream_file_index");
1428 Get_B4 (time, "time"); Param_Info2(time/45, " milliseconds");
1429 Skip_B2( "unknown");
1430 Skip_B4( "unknown");
1431
1432 FILLING_BEGIN();
1433 if (Pos==0)
1434 time_Pos0=time;
1435 if (stream_file_index==0 && type==1) //We currently handle only the first file
1436 {
1437 Fill(Stream_Menu, 0, Ztring().Duration_From_Milliseconds((int64u)((time-time_Pos0)/45)).To_UTF8().c_str(), __T("Chapter ")+Ztring::ToZtring(time_Pos));
1438 time_Pos++;
1439 }
1440 FILLING_END();
1441 }
1442 break;
1443 default:
1444 Skip_XX(12, "unknwon");
1445 }
1446 Element_End0();
1447 }
1448
1449 Fill(Stream_Menu, StreamPos_Last, Menu_Chapters_Pos_End, Count_Get(Stream_Menu, StreamPos_Last), 10, true);
1450 }
1451
1452 //---------------------------------------------------------------------------
Mpls_ExtensionData()1453 void File_Bdmv::Mpls_ExtensionData()
1454 {
1455 entries Entries; //Key is the start address
1456
1457 int32u Base_Pos=(int32u)Element_Offset-4;
1458
1459 int8u number_of_ext_data_entries;
1460 Skip_B4( "Unknown");
1461 Skip_B3( "Unknown");
1462 Element_Begin1("Offsets");
1463 Get_B1 (number_of_ext_data_entries, "number_of_ext_data_entries");
1464 for (size_t Start_Adress_Pos=0; Start_Adress_Pos<number_of_ext_data_entries; Start_Adress_Pos++)
1465 {
1466 int32u Start_Adress, Length;
1467 int16u ID1, ID2;
1468 Get_B2 (ID1, "ID1");
1469 Get_B2 (ID2, "ID2");
1470 Get_B4 (Start_Adress, "Start_Adress");
1471 Get_B4 (Length, "Length");
1472 Entries[Base_Pos+Start_Adress].ID1=ID1;
1473 Entries[Base_Pos+Start_Adress].ID2=ID2;
1474 Entries[Base_Pos+Start_Adress].Length=Length;
1475 }
1476 Element_End0();
1477
1478 for (entries::iterator Entry=Entries.begin(); Entry!=Entries.end(); ++Entry)
1479 {
1480 if (Entry->first>=Element_Offset) //If valid
1481 {
1482 if (Entry->first>Element_Offset)
1483 Skip_XX(Entry->first-Element_Offset, "unknown");
1484
1485 Element_Begin1("Entry");
1486 int64u End=Element_Offset+Entry->second.Length;
1487 switch (Entry->second.ID1)
1488 {
1489 case 0x0001 :
1490 switch(Entry->second.ID2)
1491 {
1492 case 0x0001 : break; //Mpls_ExtensionData_pip_metadata(); break;
1493 default: ;
1494 }
1495 break;
1496 case 0x0002 :
1497 switch(Entry->second.ID2)
1498 {
1499 case 0x0001 : break; //Mpls_ExtensionData_STN_table(); break;
1500 case 0x0002 : Mpls_ExtensionData_SubPath_entries(); break;
1501 case 0x0003 : break; //Mpls_ExtensionData_active_video_window(); break;
1502 default: ;
1503 }
1504 break;
1505 default : ;
1506 }
1507 if (End>Element_Offset)
1508 Skip_XX(End-Element_Offset, "Unknown");
1509 Element_End0();
1510 }
1511 }
1512
1513 if (Element_Size>Element_Offset)
1514 Skip_XX(Element_Size-Element_Offset, "Unknown");
1515 }
1516
1517 //---------------------------------------------------------------------------
Mpls_ExtensionData_SubPath_entries()1518 void File_Bdmv::Mpls_ExtensionData_SubPath_entries()
1519 {
1520 Element_Begin1("SubPath_entries");
1521 int32u length;
1522 int16u number_of_SubPath_extensions;
1523 int8u SubPath_type;
1524 Get_B4 (length, "length");
1525 int64u End=Element_Offset+length;
1526 Get_B2 (number_of_SubPath_extensions, "number_of_SubPath_extensions");
1527 for (int8u SubPath_extension=0; SubPath_extension<number_of_SubPath_extensions; SubPath_extension++)
1528 {
1529 Element_Begin1("SubPath_extension");
1530 int32u SubPath_extension_length;
1531 Get_B4 (SubPath_extension_length, "length");
1532 int64u SubPath_extension_End=Element_Offset+SubPath_extension_length;
1533 Skip_B1( "Unknown");
1534 Get_B1 (SubPath_type, "SubPath_type");
1535 switch(SubPath_type)
1536 {
1537 case 0x08 :
1538 {
1539 int8u number_of_SubPlayItems;
1540 Skip_B3( "Unknown");
1541 Get_B1 (number_of_SubPlayItems, "number_of_SubPlayItems");
1542 for (int8u Pos=0; Pos<number_of_SubPlayItems; Pos++)
1543 Mpls_PlayList_SubPlayItem(SubPath_type, Pos);
1544 }
1545 default : ;
1546 }
1547 if (SubPath_extension_End-Element_Offset)
1548 Skip_XX(SubPath_extension_End-Element_Offset, "Padding");
1549 Element_End0();
1550 }
1551 if (End-Element_Offset)
1552 Skip_XX(End-Element_Offset, "Padding");
1553 Element_End0();
1554 }
1555
1556 //---------------------------------------------------------------------------
StreamCodingInfo_Video()1557 void File_Bdmv::StreamCodingInfo_Video()
1558 {
1559 //Parsing
1560 int8u Format, FrameRate, AspectRatio;
1561 BS_Begin();
1562 Get_S1 (4, Format, "Format"); Param_Info1(Clpi_Video_Format[Format]);
1563 Get_S1 (4, FrameRate, "Frame rate"); Param_Info1(Clpi_Video_FrameRate[FrameRate]);
1564 Get_S1 (4, AspectRatio, "Aspect ratio"); Param_Info1(Clpi_Video_AspectRatio[AspectRatio]);
1565 Skip_BS(4, "Reserved");
1566 BS_End();
1567
1568 FILLING_BEGIN();
1569 if (StreamKind_Last==Stream_Max)
1570 {
1571 Stream_Prepare(Stream_Video);
1572 Fill(Stream_Video, StreamPos_Last, Video_Format, Clpi_Format(stream_type));
1573 if (Clpi_Video_Width[Format])
1574 Fill(Stream_Video, StreamPos_Last, Video_Width, Clpi_Video_Width[Format]);
1575 if (Clpi_Video_Height[Format])
1576 Fill(Stream_Video, StreamPos_Last, Video_Height, Clpi_Video_Height[Format]);
1577 Fill(Stream_Video, StreamPos_Last, Video_Interlacement, Clpi_Video_Interlacement[Format]);
1578 Fill(Stream_Video, StreamPos_Last, Video_Standard, Clpi_Video_Standard[Format]);
1579 if (Clpi_Video_FrameRate[FrameRate])
1580 Fill(Stream_Video, StreamPos_Last, Video_FrameRate, Clpi_Video_FrameRate[FrameRate]);
1581 if (Clpi_Video_Height[AspectRatio])
1582 Fill(Stream_Video, StreamPos_Last, Video_DisplayAspectRatio, Clpi_Video_AspectRatio[AspectRatio], 3, true);
1583 }
1584 FILLING_END();
1585 }
1586
1587 //---------------------------------------------------------------------------
StreamCodingInfo_Audio()1588 void File_Bdmv::StreamCodingInfo_Audio()
1589 {
1590 //Parsing
1591 Ztring Language;
1592 int8u Channels, SamplingRate;
1593 BS_Begin();
1594 Get_S1 (4, Channels, "Channel layout"); Param_Info1(Clpi_Audio_Channels[Channels]);
1595 Get_S1 (4, SamplingRate, "Sampling Rate"); Param_Info1(Clpi_Audio_SamplingRate[SamplingRate]);
1596 BS_End();
1597 Get_UTF8(3, Language, "Language"); Element_Info1(Language);
1598
1599 FILLING_BEGIN();
1600 if (StreamKind_Last==Stream_Max)
1601 {
1602 Stream_Prepare(Stream_Audio);
1603 Fill(Stream_Audio, StreamPos_Last, Audio_Format, Clpi_Format(stream_type));
1604 Fill(Stream_Audio, StreamPos_Last, Audio_Format_Profile, Clpi_Format_Profile(stream_type));
1605 if (Clpi_Audio_Channels[Channels])
1606 Fill(Stream_Audio, StreamPos_Last, Audio_Channel_s_, Clpi_Audio_Channels[Channels]);
1607 if (Clpi_Audio_SamplingRate[SamplingRate])
1608 Fill(Stream_Audio, StreamPos_Last, Audio_SamplingRate, Clpi_Audio_SamplingRate[SamplingRate]);
1609 }
1610 Fill(Stream_Audio, StreamPos_Last, Audio_Language, Language);
1611 FILLING_END();
1612 }
1613
1614 //---------------------------------------------------------------------------
StreamCodingInfo_Text()1615 void File_Bdmv::StreamCodingInfo_Text()
1616 {
1617 //Parsing
1618 Ztring Language;
1619 if (stream_type==0x92) //Subtitle
1620 Skip_B1( "Unknown");
1621 Get_UTF8(3, Language, "Language"); Element_Info1(Language);
1622
1623 FILLING_BEGIN();
1624 if (StreamKind_Last==Stream_Max)
1625 {
1626 Stream_Prepare(Stream_Text);
1627 Fill(Stream_Text, StreamPos_Last, Text_Format, Clpi_Format(stream_type));
1628 }
1629 Fill(Stream_Text, StreamPos_Last, Text_Language, Language);
1630 FILLING_END();
1631 }
1632
1633 } //NameSpace
1634
1635 #endif //MEDIAINFO_BDMV_YES
1636