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