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_MPEGTS_YES)
21 //---------------------------------------------------------------------------
22 
23 //---------------------------------------------------------------------------
24 #include "MediaInfo/Multiple/File_MpegTs.h"
25 #include "MediaInfo/Multiple/File_MpegPs.h"
26 #include "MediaInfo/Multiple/File_Mpeg_Descriptors.h"
27 #include "MediaInfo/MediaInfo_Config_MediaInfo.h"
28 #include "MediaInfo/MediaInfo.h"
29 #include "MediaInfo/MediaInfo_Internal.h"
30 #if defined(MEDIAINFO_REFERENCES_YES)
31 #include "ZenLib/File.h"
32 #endif //defined(MEDIAINFO_REFERENCES_YES)
33 #include <memory>
34 #include <algorithm>
35 #if MEDIAINFO_EVENTS
36     #include "MediaInfo/MediaInfo_Config_MediaInfo.h"
37     #include "MediaInfo/MediaInfo_Events_Internal.h"
38     #include "MediaInfo/MediaInfo_Config_PerPackage.h"
39 #endif //MEDIAINFO_EVENTS
40 #if MEDIAINFO_IBIUSAGE && MEDIAINFO_SEEK
41     #include "MediaInfo/Multiple/File_Ibi.h"
42 #endif //MEDIAINFO_IBIUSAGE && MEDIAINFO_SEEK
43 using namespace std;
44 //---------------------------------------------------------------------------
45 
46 namespace MediaInfoLib
47 {
48 
49 //***************************************************************************
50 // Constants
51 //***************************************************************************
52 
53 namespace Elements
54 {
55     const int32u HDMV=0x48444D56; //BluRay
56 }
57 
58 
59 #if !MEDIAINFO_ADVANCED
60     const float64   Config_VbrDetection_Delta=0;
61     const int64u    Config_VbrDetection_Occurences=4;
62 #endif // MEDIAINFO_ADVANCED
63 
Scte128_tag(int8u tag)64 static const char* Scte128_tag (int8u tag)
65 {
66     switch (tag)
67     {
68         case 0x00: return "Forbidden";
69         case 0x01: return "Used by DVB";
70         case 0x02: return "AU_Information";
71         case 0xDF: return "Registered";
72         case 0xFF: return "Reserved";
73         default  : return tag<0xE0?"Reserved":"User private";
74     }
75 }
76 //***************************************************************************
77 // Depends of configuration
78 //***************************************************************************
79 
80 #if !defined(MEDIAINFO_BDAV_YES)
81     const size_t BDAV_Size=0;
82 #endif
83 #if !defined(MEDIAINFO_TSP_YES)
84     const size_t TSP_Size=0;
85 #endif
86 #if !defined(MEDIAINFO_BDAV_YES) && !defined(MEDIAINFO_TSP_YES)
87     const size_t TS_Size=188;
88 #endif
89 
90 //***************************************************************************
91 // Info
92 //***************************************************************************
93 
94 //---------------------------------------------------------------------------
95 //From Mpeg_Psi
96 extern const char* Mpeg_Descriptors_registration_format_identifier_Format(int32u format_identifier);
97 extern stream_t    Mpeg_Descriptors_registration_format_identifier_StreamKind(int32u format_identifier);
98 
99 extern const char* Mpeg_Psi_stream_type_Format(int8u stream_type, int32u format_identifier);
100 extern const char* Mpeg_Psi_stream_type_Codec(int8u stream_type, int32u format_identifier);
101 extern stream_t    Mpeg_Psi_stream_type_StreamKind(int32u stream_type, int32u format_identifier);
102 extern const char* Mpeg_Psi_stream_type_Info(int8u stream_type, int32u format_identifier);
103 
104 extern const char* Mpeg_Psi_table_id(int8u table_id);
105 extern const char* Mpeg_Descriptors_stream_Format(int8u descriptor_tag, int32u format_identifier);
106 extern const char* Mpeg_Descriptors_stream_Codec(int8u descriptor_tag, int32u format_identifier);
107 extern stream_t    Mpeg_Descriptors_stream_Kind(int8u descriptor_tag, int32u format_identifier);
108 
109 extern const char* Mpeg_Descriptors_CA_system_ID(int16u CA_system_ID);
110 
111 //---------------------------------------------------------------------------
112 //DTS Neural (ETSI EN 300 468 v1.14+)
113 const size_t MpegTs_DtsNeural_2_Count=9;
114 const size_t MpegTs_DtsNeural_6_Count=4;
115 
116 static const int8u MpegTs_DtsNeural_Channels_2[MpegTs_DtsNeural_2_Count]=
117 {
118     0,
119     3,
120     4,
121     5,
122     6,
123     7,
124     8,
125     6,
126     7,
127 };
128 
129 static const int8u MpegTs_DtsNeural_Channels_6[MpegTs_DtsNeural_6_Count]=
130 {
131     0,
132     6,
133     7,
134     8,
135 };
136 
MpegTs_DtsNeural_Channels(int8u Channels,int8u config_id)137 static const int8u MpegTs_DtsNeural_Channels(int8u Channels, int8u config_id)
138 {
139     if (config_id==0)
140         return 0;
141 
142     switch (Channels)
143     {
144         case 2 :
145                 if (config_id>=MpegTs_DtsNeural_2_Count)
146                     return 0;
147                 return MpegTs_DtsNeural_Channels_2[config_id];
148         case 6 :
149                 if (config_id>=MpegTs_DtsNeural_6_Count)
150                     return 0;
151                 return MpegTs_DtsNeural_Channels_6[config_id];
152         default: return 0;
153     }
154 }
155 
156 static const char* MpegTs_DtsNeural_ChannelPositions_2[MpegTs_DtsNeural_2_Count]=
157 {
158     "",
159     "Front: L R, LFE",
160     "Front: L C R, LFE",
161     "Front: L R, Side: L R, LFE",
162     "Front: L C R, Side: L R, LFE",
163     "Front: L C R, Side: L R, Back: C, LFE",
164     "Front: L C R, Side: L R, Back: L R, LFE",
165     "Front: L R, Side: L R, Back: C, LFE",
166     "Front: L R, Side: L R, Back: L R, LFE",
167 };
168 
169 static const char* MpegTs_DtsNeural_ChannelPositions_6[MpegTs_DtsNeural_6_Count]=
170 {
171     "",
172     "Front: L C R, Side: L R",
173     "Front: L C R, Side: L R, Back: C",
174     "Front: L C R, Side: L R, Back: L R",
175 };
176 
MpegTs_DtsNeural_ChannelPositions(int8u Channels,int8u config_id)177 static const char* MpegTs_DtsNeural_ChannelPositions(int8u Channels, int8u config_id)
178 {
179     if (config_id==0)
180         return "";
181 
182     switch (Channels)
183     {
184         case 2 :
185                 if (config_id>=MpegTs_DtsNeural_2_Count)
186                     return "";
187                 return MpegTs_DtsNeural_ChannelPositions_2[config_id];
188         case 6 :
189                 if (config_id>=MpegTs_DtsNeural_6_Count)
190                     return "";
191                 return MpegTs_DtsNeural_ChannelPositions_6[config_id];
192         default: return "";
193     }
194 }
195 
196 static const char* MpegTs_DtsNeural_ChannelPositions2_2[MpegTs_DtsNeural_2_Count]=
197 {
198     "",
199     "2/0/0.1",
200     "3/0/0.1",
201     "2/2/0.1",
202     "3/2/0.1",
203     "3/2/1.1",
204     "3/2/2.1",
205     "2/2/1.1",
206     "2/2/2.1",
207 };
208 
209 static const char* MpegTs_DtsNeural_ChannelPositions2_6[MpegTs_DtsNeural_6_Count]=
210 {
211     "",
212     "3/2/0.1",
213     "3/2/1.1",
214     "3/2/2.1",
215 };
216 
MpegTs_DtsNeural_ChannelPositions2(int8u Channels,int8u config_id)217 static const char* MpegTs_DtsNeural_ChannelPositions2(int8u Channels, int8u config_id)
218 {
219     if (config_id==0)
220         return "";
221 
222     switch (Channels)
223     {
224         case 2 :
225                 if (config_id>=MpegTs_DtsNeural_2_Count)
226                     return "";
227                 return MpegTs_DtsNeural_ChannelPositions2_2[config_id];
228         case 6 :
229                 if (config_id>=MpegTs_DtsNeural_6_Count)
230                     return "";
231                 return MpegTs_DtsNeural_ChannelPositions2_6[config_id];
232         default: return "";
233     }
234 }
235 
236 //---------------------------------------------------------------------------
Decimal_Hexa(int64u Number)237 static Ztring Decimal_Hexa(int64u Number)
238 {
239     return Get_Hex_ID(Number);
240 }
241 
242 //***************************************************************************
243 // Constructor/Destructor
244 //***************************************************************************
245 
246 //---------------------------------------------------------------------------
File_MpegTs()247 File_MpegTs::File_MpegTs()
248 #if MEDIAINFO_DUPLICATE
249 :File__Duplicate()
250 #endif //MEDIAINFO_DUPLICATE
251 {
252     //Configuration
253     ParserName="MpegTs";
254     #if MEDIAINFO_EVENTS
255         ParserIDs[0]=MediaInfo_Parser_MpegTs;
256         StreamIDs_Width[0]=4;
257     #endif //MEDIAINFO_EVENTS
258     #if MEDIAINFO_DEMUX
259         Demux_Level=4; //Intermediate
260     #endif //MEDIAINFO_DEMUX
261     MustSynchronize=true;
262     Buffer_TotalBytes_FirstSynched_Max=64*1024;
263     Buffer_TotalBytes_Fill_Max=(int64u)-1; //Disabling this feature for this format, this is done in the parser
264     Trusted_Multiplier=2;
265     #if MEDIAINFO_DEMUX
266         Demux_EventWasSent_Accept_Specific=true;
267     #endif //MEDIAINFO_DEMUX
268 
269     //Internal config
270     #if defined(MEDIAINFO_BDAV_YES)
271         BDAV_Size=0; //No BDAV header
272     #endif
273     #if defined(MEDIAINFO_TSP_YES)
274         TSP_Size=0; //No TSP footer
275     #endif
276     #ifdef MEDIAINFO_ARIBSTDB24B37_YES
277         FromAribStdB24B37=false;
278     #endif
279     NoPatPmt=false;
280 
281     //Data
282     MpegTs_JumpTo_Begin=MediaInfoLib::Config.MpegTs_MaximumOffset_Get();
283     MpegTs_JumpTo_End=MediaInfoLib::Config.MpegTs_MaximumOffset_Get()/4;
284     MpegTs_ScanUpTo=(int64u)-1;
285     Searching_TimeStamp_Start=true;
286     Complete_Stream=NULL;
287     ForceStreamDisplay=MediaInfoLib::Config.MpegTs_ForceStreamDisplay_Get();
288     ForceTextStreamDisplay=MediaInfoLib::Config.MpegTs_ForceTextStreamDisplay_Get();
289 
290     #if MEDIAINFO_SEEK
291         Seek_Value=(int64u)-1;
292         Seek_ID=(int64u)-1;
293         InfiniteLoop_Detect=0;
294         Duration_Detected=false;
295     #endif //MEDIAINFO_SEEK
296 }
297 
~File_MpegTs()298 File_MpegTs::~File_MpegTs ()
299 {
300     delete Complete_Stream; Complete_Stream=NULL;
301 }
302 
303 //***************************************************************************
304 // Streams management
305 //***************************************************************************
306 
307 //---------------------------------------------------------------------------
Streams_Accept()308 void File_MpegTs::Streams_Accept()
309 {
310     Fill(Stream_General, 0, General_Format, BDAV_Size?"BDAV":(TSP_Size?"MPEG-TS 188+16":"MPEG-TS"), Unlimited, true, true);
311     if (NoPatPmt)
312         Fill(Stream_General, 0, General_Format_Profile, "No PAT/PMT");
313 
314     #if MEDIAINFO_DEMUX && MEDIAINFO_NEXTPACKET
315         if (Config->NextPacket_Get() && Config->Event_CallBackFunction_IsSet())
316             Config->Demux_EventWasSent=true;
317     #endif //MEDIAINFO_DEMUX && MEDIAINFO_NEXTPACKET
318 
319     if (!IsSub && !Config->File_IsReferenced_Get())
320     {
321         #if MEDIAINFO_ADVANCED
322             // TODO: temporary disabling theses options for MPEG-TS, because it does not work as expected
323             if (Config->File_IgnoreSequenceFileSize_Get())
324                 Config->File_IgnoreSequenceFileSize_Set(false);
325             if (Config->File_IgnoreSequenceFilesCount_Get())
326                 Config->File_IgnoreSequenceFilesCount_Set(false);
327         #endif //MEDIAINFO_ADVANCED
328 
329         TestContinuousFileNames(24, Ztring(), true);
330     }
331 
332     //Temp
333     MpegTs_JumpTo_Begin=(File_Offset_FirstSynched==(int64u)-1?0:Buffer_TotalBytes_LastSynched)+MediaInfoLib::Config.MpegTs_MaximumOffset_Get();
334     MpegTs_JumpTo_End=MediaInfoLib::Config.MpegTs_MaximumOffset_Get()/4;
335     if (MpegTs_JumpTo_Begin==(int64u)-1 || MpegTs_JumpTo_Begin+MpegTs_JumpTo_End>=File_Size)
336     {
337         if (MpegTs_JumpTo_Begin+MpegTs_JumpTo_End>File_Size)
338         {
339             MpegTs_JumpTo_Begin=File_Size;
340             MpegTs_JumpTo_End=0;
341         }
342         else
343             MpegTs_JumpTo_Begin=File_Size-MpegTs_JumpTo_End;
344     }
345 }
346 
347 //---------------------------------------------------------------------------
Streams_Fill()348 void File_MpegTs::Streams_Fill ()
349 {
350     Status[User_20]=true;
351 }
352 
353 //---------------------------------------------------------------------------
Streams_Update()354 void File_MpegTs::Streams_Update()
355 {
356     if (Status[User_19])
357         Streams_Update_Programs();
358 
359     if (Status[User_18])
360         Streams_Update_EPG();
361 
362     #ifdef MEDIAINFO_MPEGTS_PCR_YES
363         if (Status[User_16])
364             Streams_Update_Duration_Update();
365     #endif //MEDIAINFO_MPEGTS_PCR_YES
366 
367     if (Status[User_17])
368         Streams_Update_Duration_End();
369 
370     if (File_Name.empty() && Config->ParseSpeed>=1.0)
371         Fill(Stream_General, 0, General_FileSize, (File_Offset+Buffer_Offset!=File_Size)?Buffer_TotalBytes:File_Size, 10, true);
372 }
373 
374 //---------------------------------------------------------------------------
Streams_Update_Programs()375 void File_MpegTs::Streams_Update_Programs()
376 {
377     //Per stream
378     bool PerStream_AlwaysParse=ForceStreamDisplay;
379     if (!PerStream_AlwaysParse)
380     {
381         size_t Programs_Size=Complete_Stream->Transport_Streams[Complete_Stream->transport_stream_id].Programs.size();
382         PerStream_AlwaysParse=true;
383         if (Programs_Size<=2)
384         {
385             //Testing if it is a Blu-ray
386             for (complete_stream::transport_stream::programs::iterator Program=Complete_Stream->Transport_Streams[Complete_Stream->transport_stream_id].Programs.begin(); Program!=Complete_Stream->Transport_Streams[Complete_Stream->transport_stream_id].Programs.end(); ++Program)
387                 if (Program->first!=0x0000 && Program->second.registration_format_identifier!=Elements::HDMV)
388                     {
389                         PerStream_AlwaysParse=false;
390                         break;
391                     }
392         }
393     }
394     for (std::set<int16u>::iterator StreamID=Complete_Stream->PES_PIDs.begin(); StreamID!=Complete_Stream->PES_PIDs.end(); ++StreamID)
395         if (PerStream_AlwaysParse || Complete_Stream->Streams[*StreamID]->IsUpdated_IsRegistered || Complete_Stream->Streams[*StreamID]->IsUpdated_Info)
396         {
397             Streams_Update_Programs_PerStream(*StreamID);
398             Complete_Stream->Streams[*StreamID]->IsUpdated_IsRegistered=false;
399             Complete_Stream->Streams[*StreamID]->IsUpdated_Info=false;
400         }
401 
402     //Fill General
403     if (Complete_Stream->transport_stream_id_IsValid)
404     {
405         Fill(Stream_General, 0, General_ID, Complete_Stream->transport_stream_id, 10, true);
406         Fill(Stream_General, 0, General_ID_String, Decimal_Hexa(Complete_Stream->transport_stream_id), true);
407     }
408     if (!Complete_Stream->network_name.empty())
409     {
410         Fill(Stream_General, 0, General_NetworkName, Complete_Stream->network_name, true);
411         Complete_Stream->network_name.clear();
412     }
413     if (!Complete_Stream->original_network_name.empty())
414     {
415         Fill(Stream_General, 0, General_OriginalNetworkName, Complete_Stream->original_network_name, true);
416         Complete_Stream->original_network_name.clear();
417     }
418     Ztring Countries;
419     Ztring TimeZones;
420     for (std::map<Ztring, Ztring>::iterator TimeZone=Complete_Stream->TimeZones.begin(); TimeZone!=Complete_Stream->TimeZones.end(); ++TimeZone)
421     {
422         Countries+=TimeZone->first+__T(" / ");
423         TimeZones+=TimeZone->second+__T(" / ");
424     }
425     if (!Countries.empty())
426     {
427         Countries.resize(Countries.size()-3);
428         Fill(Stream_General, 0, General_Country, Countries, true);
429         Complete_Stream->TimeZones.clear();
430     }
431     if (!TimeZones.empty())
432     {
433         TimeZones.resize(TimeZones.size()-3);
434         Fill(Stream_General, 0, General_TimeZone, TimeZones, true);
435         Complete_Stream->TimeZones.clear();
436     }
437     if (!Complete_Stream->Duration_Start.empty())
438     {
439         Fill(Stream_General, 0, General_Duration_Start, Complete_Stream->Duration_Start, true);
440         Complete_Stream->Duration_Start.clear();
441     }
442     complete_stream::transport_streams::iterator Transport_Stream=Complete_Stream->transport_stream_id_IsValid?Complete_Stream->Transport_Streams.find(Complete_Stream->transport_stream_id):Complete_Stream->Transport_Streams.end();
443     if (Transport_Stream!=Complete_Stream->Transport_Streams.end())
444     {
445         //TS info
446         for (std::map<std::string, ZenLib::Ztring>::iterator Info=Transport_Stream->second.Infos.begin(); Info!=Transport_Stream->second.Infos.end(); ++Info)
447             Fill(Stream_General, 0, Info->first.c_str(), Info->second, true);
448         Transport_Stream->second.Infos.clear();
449 
450         //Per source (ATSC)
451         if (Transport_Stream->second.source_id_IsValid)
452         {
453             complete_stream::sources::iterator Source=Complete_Stream->Sources.find(Transport_Stream->second.source_id);
454             if (Source!=Complete_Stream->Sources.end())
455             {
456                 if (!Source->second.texts.empty())
457                 {
458                     Ztring Texts;
459                     for (std::map<int16u, Ztring>::iterator text=Source->second.texts.begin(); text!=Source->second.texts.end(); ++text)
460                         Texts+=text->second+__T(" - ");
461                     if (!Texts.empty())
462                         Texts.resize(Texts.size()-3);
463                     Fill(Stream_General, 0, General_ServiceProvider, Texts);
464                 }
465             }
466         }
467 
468         //Per program
469         for (complete_stream::transport_stream::programs::iterator Program=Transport_Stream->second.Programs.begin(); Program!=Transport_Stream->second.Programs.end(); ++Program)
470         {
471             if (Program->second.IsParsed)
472             {
473                 // Special case: force text stream display if requested and if video stream is present
474                 if (ForceTextStreamDisplay)
475                 {
476                     for (size_t Pos = 0; Pos < Program->second.elementary_PIDs.size(); Pos++)
477                     {
478                         int16u elementary_PID = Program->second.elementary_PIDs[Pos];
479                         if (Complete_Stream->Streams[elementary_PID]->StreamKind == Stream_Video && Complete_Stream->Streams[elementary_PID]->IsRegistered)
480                         {
481                             // Video stream is present, finding and filling text streams
482                             for (size_t Pos = 0; Pos < Program->second.elementary_PIDs.size(); Pos++)
483                             {
484                                 int16u elementary_PID = Program->second.elementary_PIDs[Pos];
485                                 if (Complete_Stream->Streams[elementary_PID]->StreamKind_FromDescriptor == Stream_Text && !Complete_Stream->Streams[elementary_PID]->IsRegistered)
486                                     Streams_Update_Programs_PerStream(elementary_PID);
487                             }
488                             break;
489                         }
490                     }
491                 }
492 
493                 //Per pid
494                 Ztring Languages, Codecs, Formats, StreamKinds, StreamPoss, elementary_PIDs, elementary_PIDs_String, Delay, LawRating, Title;
495                 for (size_t Pos=0; Pos<Program->second.elementary_PIDs.size(); Pos++)
496                 {
497                     int16u elementary_PID=Program->second.elementary_PIDs[Pos];
498                     if (PerStream_AlwaysParse || Complete_Stream->Streams[elementary_PID]->IsRegistered)
499                     {
500                         #if defined(MEDIAINFO_TELETEXT_YES)
501                         if (!Complete_Stream->Streams[elementary_PID]->Teletexts.empty())
502                         {
503                             for (std::map<int16u, teletext>::iterator Teletext=Complete_Stream->Streams[elementary_PID]->Teletexts.begin(); Teletext!=Complete_Stream->Streams[elementary_PID]->Teletexts.end(); ++Teletext)
504                             {
505                                 Ztring Format;
506                                 Ztring Language;
507                                 if (Teletext->second.StreamKind!=Stream_Max)
508                                 {
509                                     StreamKinds+=Ztring::ToZtring(Teletext->second.StreamKind);
510                                     StreamPoss+=Ztring::ToZtring(Teletext->second.StreamPos);
511                                     Format=Retrieve(Teletext->second.StreamKind, Teletext->second.StreamPos, "Format");
512                                     Language=Retrieve(Teletext->second.StreamKind, Teletext->second.StreamPos, "Language");
513                                 }
514                                 Formats+=Format+__T(" / ");
515                                 Codecs+=Format+__T(" / ");
516                                 StreamKinds+=__T(" / ");
517                                 StreamPoss+=__T(" / ");
518                                 elementary_PIDs+=Ztring::ToZtring(elementary_PID)+__T('-')+Ztring::ToZtring(Teletext->first)+__T(" / ");
519                                 Languages+=Language+__T(" / ");
520                                 Ztring List_String=Decimal_Hexa(elementary_PID)+__T('-')+Ztring::ToZtring(Teletext->first);
521                                 List_String+=__T(" (");
522                                 List_String+=Format;
523                                 if (!Language.empty())
524                                 {
525                                     List_String+=__T(", ");
526                                     List_String+=Language;
527                                 }
528                                 List_String+=__T(")");
529                                 elementary_PIDs_String+=List_String+__T(" / ");
530                             }
531                         }
532                         else
533                         #endif //MEDIAINFO_TELETEXT_YES
534                         {
535                         Ztring Format=Retrieve(Complete_Stream->Streams[elementary_PID]->StreamKind, Complete_Stream->Streams[elementary_PID]->StreamPos, Fill_Parameter(Complete_Stream->Streams[elementary_PID]->StreamKind, Generic_Format));
536                         if (Format.empty())
537                             Format=Mpeg_Psi_stream_type_Format(Complete_Stream->Streams[elementary_PID]->stream_type, Program->second.registration_format_identifier);
538                         if (Format.empty())
539                         {
540                             std::map<std::string, Ztring>::iterator Format_FromInfo=Complete_Stream->Streams[elementary_PID]->Infos.find("Format");
541                             if (Format_FromInfo!=Complete_Stream->Streams[elementary_PID]->Infos.end())
542                                 Format=Format_FromInfo->second;
543                         }
544                         if (Format.empty())
545                             Program->second.HasNotDisplayableStreams=true;
546                         Formats+=Format+__T(" / ");
547                         Codecs+=Retrieve(Complete_Stream->Streams[elementary_PID]->StreamKind, Complete_Stream->Streams[elementary_PID]->StreamPos, Fill_Parameter(Complete_Stream->Streams[elementary_PID]->StreamKind, Generic_Codec))+__T(" / ");
548                         if (Complete_Stream->Streams[elementary_PID]->StreamKind!=Stream_Max)
549                         {
550                             StreamKinds+=Ztring::ToZtring(Complete_Stream->Streams[elementary_PID]->StreamKind);
551                             StreamPoss+=Ztring::ToZtring(Complete_Stream->Streams[elementary_PID]->StreamPos);
552                         }
553                         StreamKinds+=__T(" / ");
554                         StreamPoss+=__T(" / ");
555                         elementary_PIDs+=Ztring::ToZtring(elementary_PID)+__T(" / ");
556                         Ztring Language=Retrieve(Complete_Stream->Streams[elementary_PID]->StreamKind, Complete_Stream->Streams[elementary_PID]->StreamPos, "Language/String");
557                         Languages+=Language+__T(" / ");
558                         Ztring List_String=Decimal_Hexa(elementary_PID);
559                         List_String+=__T(" (");
560                         List_String+=Format;
561                         if (!Language.empty())
562                         {
563                             List_String+=__T(", ");
564                             List_String+=Language;
565                         }
566                         List_String+=__T(")");
567                         elementary_PIDs_String+=List_String+__T(" / ");
568                         }
569 
570                         if (Complete_Stream->Streams[elementary_PID]->IsPCR)
571                         {
572                             Delay=Ztring::ToZtring(((float64)Complete_Stream->Streams[elementary_PID]->TimeStamp_Start)/27000, 6);
573                         }
574 
575                         //Law rating
576                         if (Complete_Stream->Streams[elementary_PID] && Complete_Stream->Streams[elementary_PID]->Parser)
577                         {
578                             Ztring LawRating_Temp=Complete_Stream->Streams[elementary_PID]->Parser->Retrieve(Stream_General, 0, General_LawRating);
579                             if (!LawRating_Temp.empty())
580                                 LawRating+=LawRating_Temp+__T(" / ");
581                             Ztring Title_Temp=Complete_Stream->Streams[elementary_PID]->Parser->Retrieve(Stream_General, 0, General_Title);
582                             if (!Title_Temp.empty())
583                                 Title+=Title_Temp+__T(" / ");
584                         }
585                     }
586                 }
587 
588                 if (Program->second.Update_Needed_Info || Program->second.Update_Needed_IsRegistered || Program->second.Update_Needed_StreamCount || Program->second.Update_Needed_StreamPos)
589                 {
590                     if (!Transport_Stream->second.Programs.empty()
591                      && (Transport_Stream->second.Programs.size()>1
592                       || Transport_Stream->second.Programs.begin()->second.HasNotDisplayableStreams
593                       || !Transport_Stream->second.Programs.begin()->second.Infos.empty()
594                       || !Transport_Stream->second.Programs.begin()->second.DVB_EPG_Blocks.empty()
595                       || (Transport_Stream->second.Programs.begin()->second.source_id_IsValid && Complete_Stream->Sources.find(Transport_Stream->second.Programs.begin()->second.source_id)!=Complete_Stream->Sources.end())
596                       || Config->File_MpegTs_ForceMenu_Get()))
597                     {
598                         if (Program->second.StreamPos==(size_t)-1)
599                         {
600                             size_t StreamPos=(size_t)-1;
601                             for (size_t program_number=0; program_number<Complete_Stream->program_number_Order.size(); program_number++)
602                                 if (Program->first<Complete_Stream->program_number_Order[program_number])
603                                 {
604                                     StreamPos=program_number;
605                                     for (size_t program_number2=program_number; program_number2<Complete_Stream->program_number_Order.size(); program_number2++)
606                                         Transport_Stream->second.Programs[Complete_Stream->program_number_Order[program_number2]].StreamPos++;
607                                     Complete_Stream->program_number_Order.insert(Complete_Stream->program_number_Order.begin()+program_number, Program->first);
608                                     break;
609                                 }
610                             if (StreamPos==(size_t)-1)
611                             {
612                                 Complete_Stream->program_number_Order.push_back(Program->first);
613                             }
614 
615                             Stream_Prepare(Stream_Menu, StreamPos);
616                             Program->second.StreamPos=StreamPos_Last;
617                         }
618                         else
619                             StreamPos_Last=Program->second.StreamPos;
620                         Fill(Stream_Menu, StreamPos_Last, Menu_ID, Program->second.pid, 10, true);
621                         Fill(Stream_Menu, StreamPos_Last, Menu_ID_String, Decimal_Hexa(Program->second.pid), true);
622                         Fill(Stream_Menu, StreamPos_Last, Menu_MenuID, Program->first, 10, true);
623                         Fill(Stream_Menu, StreamPos_Last, Menu_MenuID_String, Decimal_Hexa(Program->first), true);
624                         Clear(Stream_Menu, StreamPos_Last, General_StreamOrder);
625                         for (size_t programs_List_Pos=0; programs_List_Pos<Transport_Stream->second.programs_List.size(); ++programs_List_Pos)
626                             if (Transport_Stream->second.programs_List[programs_List_Pos]==Program->first)
627                                 Fill(Stream_Menu, StreamPos_Last, General_StreamOrder, programs_List_Pos);
628                         for (std::map<std::string, ZenLib::Ztring>::iterator Info=Program->second.Infos.begin(); Info!=Program->second.Infos.end(); ++Info)
629                             Fill(Stream_Menu, StreamPos_Last, Info->first.c_str(), Info->second, true);
630                         Program->second.Infos.clear();
631                         for (std::map<std::string, ZenLib::Ztring>::iterator Info=Program->second.ExtraInfos_Content.begin(); Info!=Program->second.ExtraInfos_Content.end(); ++Info)
632                             Fill(Stream_Menu, StreamPos_Last, Info->first.c_str(), Info->second, true);
633                         Program->second.ExtraInfos_Content.clear();
634                         for (std::map<std::string, ZenLib::Ztring>::iterator Info=Program->second.ExtraInfos_Option.begin(); Info!=Program->second.ExtraInfos_Option.end(); ++Info)
635                             Fill_SetOptions(Stream_Menu, StreamPos_Last, Info->first.c_str(), Info->second.To_UTF8().c_str());
636                         Program->second.ExtraInfos_Option.clear();
637 
638                         if (!Formats.empty())
639                             Formats.resize(Formats.size()-3);
640                         Fill(Stream_Menu, StreamPos_Last, Menu_Format, Formats, true);
641                         if (!Codecs.empty())
642                             Codecs.resize(Codecs.size()-3);
643                         Fill(Stream_Menu, StreamPos_Last, Menu_Codec, Codecs, true);
644                         if (!StreamKinds.empty())
645                             StreamKinds.resize(StreamKinds.size()-3);
646                         Fill(Stream_Menu, StreamPos_Last, Menu_List_StreamKind, StreamKinds, true);
647                         if (!elementary_PIDs_String.empty())
648                             elementary_PIDs_String.resize(elementary_PIDs_String.size()-3);
649                         Fill(Stream_Menu, StreamPos_Last, Menu_List_String, elementary_PIDs_String, true);
650                         if (!elementary_PIDs.empty())
651                             elementary_PIDs.resize(elementary_PIDs.size()-3);
652                         Fill(Stream_Menu, StreamPos_Last, Menu_List, elementary_PIDs, true);
653                         if (!StreamPoss.empty())
654                             StreamPoss.resize(StreamPoss.size()-3);
655                         Fill(Stream_Menu, StreamPos_Last, Menu_List_StreamPos, StreamPoss, true);
656                         if (!Languages.empty())
657                             Languages.resize(Languages.size()-3);
658                         Fill(Stream_Menu, StreamPos_Last, Menu_Language, Languages, true);
659                         if (!LawRating.empty())
660                             LawRating.resize(LawRating.size()-3);
661                         Fill(Stream_Menu, StreamPos_Last, "LawRating", LawRating, true);
662                         if (StreamPos_Last)
663                             Clear(Stream_General, 0, General_LawRating); //More than 1 menu, can not be in General part
664                         if (!Title.empty())
665                             Title.resize(Title.size()-3);
666                         Fill(Stream_Menu, StreamPos_Last, "Title", Title, true);
667                         if (StreamPos_Last)
668                             Clear(Stream_General, 0, General_Title); //More than 1 menu, can not be in General part
669                     }
670                 }
671 
672                 //Delay
673                 if (Program->second.Update_Needed_IsRegistered)
674                 {
675                     switch (Count_Get(Stream_Menu))
676                     {
677                         case 0 : Fill(Stream_General, 0, General_Delay, Delay, true); break;
678                         default: Fill(Stream_Menu, StreamPos_Last, Menu_Delay, Delay, true); break;
679                     }
680                     Program->second.Update_Needed_IsRegistered=false;
681                 }
682                 if (Count_Get(Stream_Menu)==2)
683                     Clear(Stream_General, 0, General_Delay); //Not valid, multiple menus
684             }
685         }
686     }
687 
688     //Commercial name
689     if (Count_Get(Stream_Video)==1
690      && Count_Get(Stream_Audio)==1
691      && Retrieve(Stream_Video, 0, Video_Format)==__T("MPEG Video")
692      && Retrieve(Stream_Video, 0, Video_Format_Commercial_IfAny).find(__T("HDV"))==0
693      && Retrieve(Stream_Audio, 0, Audio_Format)==__T("MPEG Audio")
694      && Retrieve(Stream_Audio, 0, Audio_Format_Version)==__T("Version 1")
695      && Retrieve(Stream_Audio, 0, Audio_Format_Profile)==__T("Layer 2")
696      && Retrieve(Stream_Audio, 0, Audio_BitRate)==__T("384000"))
697         Fill(Stream_General, 0, General_Format_Commercial_IfAny, Retrieve(Stream_Video, 0, Video_Format_Commercial_IfAny));
698 }
699 
700 //---------------------------------------------------------------------------
Streams_Update_Programs_PerStream(size_t StreamID)701 void File_MpegTs::Streams_Update_Programs_PerStream(size_t StreamID)
702 {
703     complete_stream::stream* Temp=Complete_Stream->Streams[StreamID];
704 
705     //No direct handling of Sub streams;
706     if (Temp->stream_type==0x20 && Temp->SubStream_pid) //Stereoscopic is not alone
707         return;
708 
709     if (Temp->Parser)
710         Temp->Parser->Open_Buffer_Update();
711 
712     //Merging from a previous merge
713     size_t Counts[Stream_Max];
714     for (size_t StreamKind=Stream_General+1; StreamKind<Stream_Max; StreamKind++)
715         Counts[StreamKind]=Count_Get((stream_t)StreamKind);
716     if (Temp->StreamKind != Stream_Max && Temp->StreamPos != (size_t)-1 && Temp->Parser)
717     {
718         Merge(*Temp->Parser, Temp->StreamKind, 0, Temp->StreamPos);
719         StreamKind_Last=Temp->StreamKind;
720         StreamPos_Last=Temp->StreamPos;
721     }
722     else
723     {
724         //By the parser
725         StreamKind_Last=Stream_Max;
726         if (Temp->Parser && Temp->Parser->Status[IsAccepted])
727         {
728             if (Temp->SubStream_pid!=0x0000) //With a substream
729                 Fill(Complete_Stream->Streams[Temp->SubStream_pid]->Parser);
730             if (Temp->Parser->Count_Get(Stream_Video) && Temp->Parser->Count_Get(Stream_Text))
731             {
732                 //Special case: Video and Text are together
733                 Stream_Prepare(Stream_Video);
734                 Merge(*Temp->Parser, Stream_Video, 0, StreamPos_Last);
735             }
736             else
737                 Merge(*Temp->Parser);
738 
739             //More from the FMC parser
740             if (Temp->FMC_ES_ID_IsValid)
741             {
742                 complete_stream::transport_stream::iod_ess::iterator IOD_ES=Complete_Stream->Transport_Streams[Complete_Stream->transport_stream_id].IOD_ESs.find(Temp->FMC_ES_ID);
743                 if (IOD_ES!=Complete_Stream->Transport_Streams[Complete_Stream->transport_stream_id].IOD_ESs.end() && IOD_ES->second.Parser)
744                 {
745                     Finish(IOD_ES->second.Parser);
746                     Merge(*IOD_ES->second.Parser, StreamKind_Last, StreamPos_Last, 0);
747                 }
748             }
749 
750             //LATM
751             complete_stream::transport_stream::iod_ess::iterator IOD_ES=Complete_Stream->Transport_Streams[Complete_Stream->transport_stream_id].IOD_ESs.find(Complete_Stream->Streams[StreamID]->FMC_ES_ID);
752             #ifdef MEDIAINFO_MPEG4_YES
753                 if (IOD_ES!=Complete_Stream->Transport_Streams[Complete_Stream->transport_stream_id].IOD_ESs.end() && IOD_ES->second.SLConfig && Retrieve(Stream_Audio, StreamPos_Last, Audio_MuxingMode).empty())
754                     Fill(Stream_Audio, StreamPos_Last, Audio_MuxingMode, "SL");
755             #endif
756             if (Complete_Stream->Streams[StreamID]->stream_type==0x11 && Retrieve(Stream_Audio, StreamPos_Last, Audio_MuxingMode).empty())
757                 Fill(Stream_Audio, StreamPos_Last, Audio_MuxingMode, "LATM");
758         }
759 
760         //By the descriptors
761         if (StreamKind_Last==Stream_Max && Complete_Stream->transport_stream_id_IsValid && !Temp->program_numbers.empty() && !Complete_Stream->Transport_Streams[Complete_Stream->transport_stream_id].Programs.empty())
762         {
763             int32u format_identifier=Complete_Stream->Transport_Streams[Complete_Stream->transport_stream_id].Programs[Temp->program_numbers[0]].registration_format_identifier;
764             if (Temp->IsRegistered
765              && Mpeg_Descriptors_registration_format_identifier_StreamKind(format_identifier)!=Stream_Max)
766             {
767                 StreamKind_Last=Mpeg_Descriptors_registration_format_identifier_StreamKind(format_identifier);
768                 Stream_Prepare(StreamKind_Last);
769                 Fill(StreamKind_Last, StreamPos_Last, Fill_Parameter(StreamKind_Last, Generic_Format), Mpeg_Descriptors_registration_format_identifier_Format(format_identifier));
770                 Fill(StreamKind_Last, StreamPos_Last, Fill_Parameter(StreamKind_Last, Generic_Codec), Mpeg_Descriptors_registration_format_identifier_Format(format_identifier));
771             }
772         }
773 
774         //By registration_format_identifier
775         if (StreamKind_Last==Stream_Max && Temp->registration_format_identifier && Temp->IsRegistered && Mpeg_Descriptors_registration_format_identifier_StreamKind(Temp->registration_format_identifier)!=Stream_Max)
776         {
777             StreamKind_Last=Mpeg_Descriptors_registration_format_identifier_StreamKind(Temp->registration_format_identifier);
778             Stream_Prepare(StreamKind_Last);
779             Fill(StreamKind_Last, StreamPos_Last, Fill_Parameter(StreamKind_Last, Generic_Format), Mpeg_Descriptors_registration_format_identifier_Format(Temp->registration_format_identifier));
780             Fill(StreamKind_Last, StreamPos_Last, Fill_Parameter(StreamKind_Last, Generic_Codec), Mpeg_Descriptors_registration_format_identifier_Format(Temp->registration_format_identifier));
781         }
782 
783         //By the stream_type
784         if (StreamKind_Last==Stream_Max && Complete_Stream->transport_stream_id_IsValid && !Temp->program_numbers.empty() && !Complete_Stream->Transport_Streams[Complete_Stream->transport_stream_id].Programs.empty())
785         {
786             int32u format_identifier=Complete_Stream->Transport_Streams[Complete_Stream->transport_stream_id].Programs[Temp->program_numbers[0]].registration_format_identifier;
787             if (Mpeg_Psi_stream_type_StreamKind(Temp->stream_type, format_identifier)!=Stream_Max && (Temp->IsRegistered || ForceStreamDisplay || format_identifier==Elements::HDMV))
788             {
789                 StreamKind_Last=Mpeg_Psi_stream_type_StreamKind(Temp->stream_type, format_identifier);
790                 if (StreamKind_Last==Stream_General && Temp->Parser) //Only information, no streams
791                 {
792                     Merge (*Temp->Parser, Stream_General, 0, 0);
793                     StreamKind_Last=Stream_Max;
794                 }
795                 Stream_Prepare(StreamKind_Last);
796                 Fill(StreamKind_Last, StreamPos_Last, Fill_Parameter(StreamKind_Last, Generic_Format), Mpeg_Psi_stream_type_Format(Temp->stream_type, format_identifier));
797                 Fill(StreamKind_Last, StreamPos_Last, Fill_Parameter(StreamKind_Last, Generic_Codec), Mpeg_Psi_stream_type_Codec(Temp->stream_type, format_identifier));
798             }
799         }
800 
801         //By the StreamKind
802         if (StreamKind_Last==Stream_Max && Temp->StreamKind_FromDescriptor!=Stream_Max && (Temp->IsRegistered || ForceStreamDisplay || (ForceTextStreamDisplay && Temp->StreamKind_FromDescriptor==Stream_Text) || (!Temp->program_numbers.empty() && Complete_Stream->Transport_Streams[Complete_Stream->transport_stream_id].Programs[Temp->program_numbers[0]].registration_format_identifier==Elements::HDMV)))
803         {
804             Stream_Prepare(Temp->StreamKind_FromDescriptor);
805         }
806     }
807 
808     //More info
809     if (StreamKind_Last!=Stream_Max)
810     {
811         for (size_t StreamKind=Stream_General+1; StreamKind<Stream_Max; StreamKind++)
812         {
813         size_t Counts_Now=Count_Get((stream_t)StreamKind);
814         for (size_t StreamPos=Counts[StreamKind]; StreamPos<Counts_Now; StreamPos++)
815         {
816             Temp->StreamKind=StreamKind_Last;
817             Temp->StreamPos=StreamPos;
818 
819             //Encryption
820             if (Temp->CA_system_ID)
821                 Fill((stream_t)StreamKind, StreamPos, "Encryption", Mpeg_Descriptors_CA_system_ID(Temp->CA_system_ID));
822             else if (Temp->Scrambled_Count>16)
823                 Fill((stream_t)StreamKind, StreamPos, "Encryption", "Encrypted");
824 
825             //TS info
826             for (std::map<std::string, ZenLib::Ztring>::iterator Info=Temp->Infos.begin(); Info!=Temp->Infos.end(); ++Info)
827             {
828                 //Special case: Preselections
829                 string First=Info->first;
830                 if ((stream_t)StreamKind==Stream_Audio && First.rfind("Preselection", 12)==0 && Retrieve_Const((stream_t)Stream_Audio, StreamPos, Audio_Format)==__T("AC-4"))
831                 {
832                     const ZtringListList& More=(*Stream_More)[Stream_Audio][StreamPos];
833                     size_t Count=More.size();
834                     map<int32u, int32u> ID_Mappings;
835                     int32u First_ID=Ztring().From_UTF8(First.substr(12)).To_int32u();
836                     First="Presentation"+Info->first.substr(12);
837                     size_t First_Space=First.find(' ');
838                     if (First_Space!=string::npos)
839                     {
840                         string First_AfterSpace=First.substr(First_Space+1);
841                         if (First_AfterSpace=="ID")
842                             First=First.substr(0, First_Space+1)+"PresentationID";
843                     }
844                     else
845                     {
846                         //Look for ID in descriptor
847                         std::map<std::string, ZenLib::Ztring>::iterator Info_ID=Temp->Infos.find(Info->first+" ID");
848                         if (Info_ID!=Temp->Infos.end())
849                             ID_Mappings[First_ID]=Info_ID->second.To_int32u();
850                     }
851 
852                     //
853                     map<int32u, int32u>::iterator ID_Mapping=ID_Mappings.find(First_ID);
854                     if (ID_Mapping!=ID_Mappings.end())
855                         First_ID=ID_Mapping->second;
856 
857                     //Look for PresentationID in descriptor
858                     size_t Pos=0;
859                     bool Pos_FoundInID=false;
860                     for (;;)
861                     {
862                         Ztring LookingFor=__T("Presentation")+Ztring::ToZtring(Pos);
863                         bool PreselectionIsFound=false;
864                         for (size_t Parameter=0; Parameter<Count; Parameter++)
865                             if (Info_Name<More[Parameter].size() && More[Parameter][Info_Name]==LookingFor)
866                             {
867                                 PreselectionIsFound=true;
868                                 if (Parameter+3<Count && Info_Text<More[Parameter+3].size() && More[Parameter+3][Info_Name]==LookingFor+__T(" PresentationID") && More[Parameter+3][Info_Text]==Ztring::ToZtring(First_ID))
869                                 {
870                                     if (First_Space!=string::npos)
871                                         First=First.substr(First_Space);
872                                     else
873                                         First.clear();
874                                     First.insert(0, LookingFor.To_UTF8());
875                                     PreselectionIsFound=false;
876                                     break;
877                                 }
878                             }
879                         if (!PreselectionIsFound)
880                             break;
881                         Pos++;
882                     }
883                 }
884 
885                 if (Retrieve((stream_t)StreamKind, StreamPos, First.c_str()).empty())
886                 {
887                     //Special case : DTS Neural
888                     if ((stream_t)StreamKind==Stream_Audio && First=="Matrix_ChannelPositions" && Info->second.find(__T("DTS Neural Audio "))==0)
889                     {
890                         int8u Channels=Retrieve(Stream_Audio, StreamPos, Audio_Channel_s_).To_int8u();
891                         if (Channels)
892                         {
893                             int8u config_id=Ztring(Info->second.substr(17, string::npos)).To_int8u();
894                             int8u Matrix_Channels=MpegTs_DtsNeural_Channels(Channels, config_id);
895                             if (Matrix_Channels)
896                             {
897                                 Fill(Stream_Audio, StreamPos, Audio_Matrix_Channel_s_, Matrix_Channels);
898                                 Fill(Stream_Audio, StreamPos, Audio_Matrix_ChannelPositions, MpegTs_DtsNeural_ChannelPositions(Channels, config_id));
899                                 Fill(Stream_Audio, StreamPos, Audio_ChannelPositions_String2, MpegTs_DtsNeural_ChannelPositions2(Channels, config_id));
900                             }
901                         }
902 
903                     }
904                     else
905                     {
906                         Fill((stream_t)StreamKind, StreamPos, First.c_str(), Info->second, true);
907                         std::map<std::string, ZenLib::Ztring>::iterator Option=Temp->Infos_Option.find(First.c_str());
908                         if (Option!=Temp->Infos_Option.end())
909                             Fill_SetOptions((stream_t)StreamKind, StreamPos, First.c_str(), Option->second.To_UTF8().c_str());
910                     }
911                 }
912                 else if (Info->first=="CodecID")
913                 {
914                     Fill((stream_t)StreamKind, StreamPos, Info->first.c_str(), Info->second+__T('-')+Retrieve((stream_t)StreamKind, StreamPos, Info->first.c_str()), true);
915                 }
916                 else if (Info->first.find("HDR_Format")==0)
917                 {
918                     Fill((stream_t)StreamKind, StreamPos, Info->first.c_str(), Info->second+__T(" / ")+Retrieve((stream_t)StreamKind, StreamPos, Info->first.c_str()), true);
919                 }
920             }
921 
922             //Common
923             if (Temp->SubStream_pid!=0x0000) //Wit a substream
924             {
925                 Ztring Format_Profile=Retrieve(Stream_Video, StreamPos, Video_Format_Profile);
926                 Fill(Stream_Video, StreamPos, Video_ID, Ztring::ToZtring(Temp->SubStream_pid)+__T(" / ")+Ztring::ToZtring(StreamID), true);
927                 Fill(Stream_Video, StreamPos, Video_ID_String, Decimal_Hexa(Temp->SubStream_pid)+__T(" / ")+Decimal_Hexa(StreamID), true);
928                 if (!Format_Profile.empty() && Complete_Stream->Streams[Temp->SubStream_pid] && Complete_Stream->Streams[Temp->SubStream_pid]->Parser)
929                     Fill(Stream_Video, StreamPos, Video_Format_Profile, Complete_Stream->Streams[Temp->SubStream_pid]->Parser->Retrieve(Stream_Video, 0, Video_Format_Profile)+__T(" / ")+Format_Profile, true);
930             }
931             else if (Retrieve((stream_t)StreamKind, StreamPos, General_ID).find(__T('-'))!=string::npos)
932             {
933                 Ztring ID=Retrieve((stream_t)StreamKind, StreamPos, General_ID);
934                 size_t ID_Pos=ID.find(__T('-'));
935                 if (ID_Pos!=string::npos)
936                     ID.erase(ID.begin(), ID.begin()+ID_Pos+1); //Removing the PS part
937                 Ztring ID_String=Retrieve((stream_t)StreamKind, StreamPos, General_ID_String);
938                 size_t ID_String_Pos=ID_String.find(__T('-'));
939                 if (ID_String_Pos!=string::npos)
940                     ID_String.erase(ID_String.begin(), ID_String.begin()+ID_String_Pos+1); //Removing the PS part
941                 #ifdef MEDIAINFO_ARIBSTDB24B37_YES
942                     if (FromAribStdB24B37)
943                     {
944                         Fill((stream_t)StreamKind, StreamPos, General_ID, ID, true);
945                         Fill((stream_t)StreamKind, StreamPos, General_ID_String, ID_String, true);
946                     }
947                     else
948                 #endif //MEDIAINFO_ARIBSTDB24B37_YES
949                     {
950                         Fill((stream_t)StreamKind, StreamPos, General_ID, Ztring::ToZtring(StreamID)+__T('-')+ID, true);
951                         Fill((stream_t)StreamKind, StreamPos, General_ID_String, Decimal_Hexa(StreamID)+__T('-')+ID_String, true);
952                     }
953             }
954             else
955             {
956                 Fill((stream_t)StreamKind, StreamPos, General_ID, StreamID, 10, true);
957                 Fill((stream_t)StreamKind, StreamPos, General_ID_String, Decimal_Hexa(StreamID), true);
958             }
959             for (size_t Pos=0; Pos<Temp->program_numbers.size(); Pos++)
960             {
961                 Fill((stream_t)StreamKind, StreamPos, General_MenuID, Temp->program_numbers[Pos], 10, Pos==0);
962                 Fill((stream_t)StreamKind, StreamPos, General_MenuID_String, Decimal_Hexa(Temp->program_numbers[Pos]), Pos==0);
963             }
964 
965             //StreamOrder
966             Clear((stream_t)StreamKind, StreamPos, General_StreamOrder);
967             for (size_t program_FromStream=0; program_FromStream<Temp->program_numbers.size(); ++program_FromStream)
968             {
969                 int16u program_number=Temp->program_numbers[program_FromStream];
970                 std::vector<int16u> &programs_List=Complete_Stream->Transport_Streams[Complete_Stream->transport_stream_id].programs_List;
971                 size_t programs_List_Pos=0;
972                 for (; programs_List_Pos<programs_List.size(); ++programs_List_Pos)
973                     if (programs_List[programs_List_Pos]==program_number)
974                         break;
975                 if (programs_List_Pos<programs_List.size())
976                 {
977                     complete_stream::transport_stream::program &Program=Complete_Stream->Transport_Streams[Complete_Stream->transport_stream_id].Programs[program_number];
978                     for (size_t elementary_PID_Pos=0; elementary_PID_Pos<Program.elementary_PIDs.size(); ++elementary_PID_Pos)
979                         if (Program.elementary_PIDs[elementary_PID_Pos]==StreamID)
980                             Fill((stream_t)StreamKind, StreamPos, General_StreamOrder,  Ztring::ToZtring(programs_List_Pos)+__T('-')+Ztring::ToZtring(elementary_PID_Pos));
981                 }
982             }
983 
984             //Special cases
985             if ((stream_t)StreamKind==Stream_Video && Temp->Parser && Temp->Parser->Count_Get(Stream_Text))
986             {
987             }
988         }
989         }
990         Temp->Infos.clear();
991         Temp->Infos_Option.clear();
992 
993         //Special cases
994         if (Temp->Parser && Temp->Parser->Count_Get(Stream_Video))
995         {
996             //Video and Text may be together
997             size_t Text_Count=Temp->Parser->Count_Get(Stream_Text);
998             for (size_t Text_Pos=0; Text_Pos<Text_Count; Text_Pos++)
999             {
1000                 Ztring Parser_ID=Temp->Parser->Retrieve(Stream_Text, Text_Pos, Text_ID);
1001                 if (Parser_ID.find(__T('-'))!=string::npos)
1002                     Parser_ID.erase(Parser_ID.begin(), Parser_ID.begin()+Parser_ID.find(__T('-'))+1);
1003                 Ztring ID=Retrieve(Stream_Video, Temp->StreamPos, Video_ID)+__T('-')+Parser_ID;
1004                 Ztring ID_String=Retrieve(Stream_Video, Temp->StreamPos, Video_ID_String)+__T('-')+Parser_ID;
1005                 StreamPos_Last=(size_t)-1;
1006                 for (size_t Pos=0; Pos<Count_Get(Stream_Text); Pos++)
1007                     if (Retrieve(Stream_Text, Pos, Text_ID)==ID && Retrieve(Stream_Text, Pos, "MuxingMode")==Temp->Parser->Retrieve(Stream_Text, Text_Pos, "MuxingMode"))
1008                     {
1009                         StreamPos_Last=Pos;
1010                         break;
1011                     }
1012                 if (StreamPos_Last==(size_t)-1)
1013                     Stream_Prepare(Stream_Text, StreamPos_Last);
1014                 if (!IsSub)
1015                     Fill(Stream_Text, StreamPos_Last, "MuxingMode_MoreInfo", __T("Muxed in Video #")+Ztring().From_Number(Temp->StreamPos+1), true);
1016                 Merge(*Temp->Parser, Stream_Text, Text_Pos, StreamPos_Last);
1017 
1018                 Fill(Stream_Text, StreamPos_Last, Text_ID, ID, true);
1019                 Fill(Stream_Text, StreamPos_Last, Text_ID_String, ID_String, true);
1020                 Fill(Stream_Text, StreamPos_Last, Text_StreamOrder, Retrieve(Stream_Video, Temp->StreamPos, Video_StreamOrder), true);
1021                 Fill(Stream_Text, StreamPos_Last, Text_MenuID, Retrieve(Stream_Video, Temp->StreamPos, Video_MenuID), true);
1022                 Fill(Stream_Text, StreamPos_Last, Text_MenuID_String, Retrieve(Stream_Video, Temp->StreamPos, Video_MenuID_String), true);
1023                 Fill(Stream_Text, StreamPos_Last, Text_Duration, Retrieve(Stream_Video, Temp->StreamPos, Video_Duration), true);
1024                 Fill(Stream_Text, StreamPos_Last, Text_Delay, Retrieve(Stream_Video, Temp->StreamPos, Video_Delay), true);
1025                 Fill(Stream_Text, StreamPos_Last, Text_Delay_Source, Retrieve(Stream_Video, Temp->StreamPos, Video_Delay_Source), true);
1026             }
1027 
1028             StreamKind_Last=Temp->StreamKind;
1029             StreamPos_Last=Temp->StreamPos;
1030         }
1031     }
1032 
1033     //Teletext
1034     #if defined(MEDIAINFO_TELETEXT_YES)
1035     bool RelyOnTsInfo=(StreamKind_Last==Stream_Max);
1036     for (std::map<int16u, teletext>::iterator Teletext=Temp->Teletexts.begin(); Teletext!=Temp->Teletexts.end(); ++Teletext)
1037     {
1038         if (RelyOnTsInfo)
1039         {
1040             std::map<std::string, Ztring>::iterator Info_Format=Teletext->second.Infos.find("Format");
1041             Stream_Prepare((Info_Format!=Teletext->second.Infos.end() && Info_Format->second==__T("Teletext"))?Stream_Other:Stream_Text);
1042             Fill(StreamKind_Last, StreamPos_Last, General_ID, Ztring::ToZtring(StreamID)+__T('-')+Ztring::ToZtring(Teletext->first), true);
1043             Fill(StreamKind_Last, StreamPos_Last, General_ID_String, Decimal_Hexa(StreamID)+__T('-')+Ztring::ToZtring(Teletext->first), true);
1044 
1045             for (size_t Pos=0; Pos<Temp->program_numbers.size(); Pos++)
1046             {
1047                 Fill(StreamKind_Last, StreamPos_Last, General_MenuID, Temp->program_numbers[Pos], 10, Pos==0);
1048                 Fill(StreamKind_Last, StreamPos_Last, General_MenuID_String, Decimal_Hexa(Temp->program_numbers[Pos]), Pos==0);
1049             }
1050         }
1051         else
1052         {
1053             StreamKind_Last=Stream_Max;
1054             StreamPos_Last=(size_t)-1;
1055             Ztring ID=Ztring::ToZtring(StreamID)+__T('-')+Ztring::ToZtring(Teletext->first);
1056             for (size_t StreamKind=Stream_General+1; StreamKind<Stream_Max; StreamKind++)
1057                 for (size_t StreamPos=0; StreamPos<Count_Get((stream_t)StreamKind); StreamPos++)
1058                     if (Retrieve((stream_t)StreamKind, StreamPos, General_ID) == ID)
1059                     {
1060                         StreamKind_Last=(stream_t)StreamKind;
1061                         StreamPos_Last=StreamPos;
1062                     }
1063         }
1064 
1065         //TS info
1066         if (StreamKind_Last!=Stream_Max)
1067         {
1068             for (std::map<std::string, ZenLib::Ztring>::iterator Info=Teletext->second.Infos.begin(); Info!=Teletext->second.Infos.end(); ++Info)
1069             {
1070                 if (Retrieve(StreamKind_Last, StreamPos_Last, Info->first.c_str()).empty())
1071                     Fill(StreamKind_Last, StreamPos_Last, Info->first.c_str(), Info->second);
1072             }
1073             Teletext->second.Infos.clear();
1074         }
1075         Teletext->second.StreamKind=StreamKind_Last;
1076         Teletext->second.StreamPos=StreamPos_Last;
1077     }
1078     #endif //MEDIAINFO_TELETEXT_YES
1079 
1080     //From parser General part
1081     MergeGeneral(Temp, General_LawRating);
1082     MergeGeneral(Temp, General_Title);
1083     MergeGeneral(Temp, General_Recorded_Date);
1084     MergeGeneral(Temp, General_Encoded_Application);
1085     MergeGeneral(Temp, General_Encoded_Application_CompanyName);
1086     MergeGeneral(Temp, General_Encoded_Application_Name);
1087 }
1088 
1089 //---------------------------------------------------------------------------
Streams_Update_EPG()1090 void File_MpegTs::Streams_Update_EPG()
1091 {
1092     //EPG
1093     complete_stream::transport_streams::iterator Transport_Stream=Complete_Stream->transport_stream_id_IsValid?Complete_Stream->Transport_Streams.find(Complete_Stream->transport_stream_id):Complete_Stream->Transport_Streams.end();
1094     if (Transport_Stream==Complete_Stream->Transport_Streams.end())
1095         return;
1096 
1097     //Per source (ATSC)
1098     if (Transport_Stream->second.source_id_IsValid)
1099     {
1100         complete_stream::sources::iterator Source=Complete_Stream->Sources.find(Transport_Stream->second.source_id);
1101         if (Source!=Complete_Stream->Sources.end())
1102         {
1103             //EPG
1104             std::map<Ztring, Ztring> EPGs;
1105             for (complete_stream::source::atsc_epg_blocks::iterator ATSC_EPG_Block=Source->second.ATSC_EPG_Blocks.begin(); ATSC_EPG_Block!=Source->second.ATSC_EPG_Blocks.end(); ++ATSC_EPG_Block)
1106                 for (complete_stream::source::atsc_epg_block::events::iterator Event=ATSC_EPG_Block->second.Events.begin(); Event!=ATSC_EPG_Block->second.Events.end(); ++Event)
1107                 {
1108                     Ztring Texts;
1109                     for (std::map<int16u, Ztring>::iterator text=Event->second.texts.begin(); text!=Event->second.texts.end(); ++text)
1110                         Texts+=text->second+__T(" - ");
1111                     if (!Texts.empty())
1112                         Texts.resize(Texts.size()-3);
1113                     EPGs[Ztring().Date_From_Seconds_1970(Event->second.start_time+315964800-Complete_Stream->GPS_UTC_offset)]=Event->second.title+__T(" / ")+Texts+__T(" /  /  / ")+Event->second.duration+__T(" / ");
1114                 }
1115             if (!EPGs.empty())
1116             {
1117                 //Trashing old EPG
1118                 size_t Begin=Retrieve(Stream_General, 0, General_EPG_Positions_Begin).To_int32u();
1119                 size_t End=Retrieve(Stream_General, 0, General_EPG_Positions_End).To_int32u();
1120                 if (Begin && End && Begin<End)
1121                     for (size_t Pos=End-1; Pos>=Begin; Pos--)
1122                         Clear(Stream_General, 0, Pos);
1123 
1124                 //Filling
1125                 Fill(Stream_General, 0, General_EPG_Positions_Begin, Count_Get(Stream_General, 0), 10, true);
1126                 for (std::map<Ztring, Ztring>::iterator EPG=EPGs.begin(); EPG!=EPGs.end(); ++EPG)
1127                     Fill(Stream_General, 0, EPG->first.To_UTF8().c_str(), EPG->second, true);
1128                 Fill(Stream_General, 0, General_EPG_Positions_End, Count_Get(Stream_General, 0), 10, true);
1129             }
1130         }
1131     }
1132 
1133     //Per program
1134     if (!Transport_Stream->second.Programs.empty()
1135      && (Transport_Stream->second.Programs.size()>1
1136       || !Transport_Stream->second.Programs.begin()->second.Infos.empty()
1137       || !Transport_Stream->second.Programs.begin()->second.DVB_EPG_Blocks.empty()
1138       || Complete_Stream->Sources.find(Transport_Stream->second.Programs.begin()->second.source_id)!=Complete_Stream->Sources.end()
1139       || Config->File_MpegTs_ForceMenu_Get()))
1140         for (complete_stream::transport_stream::programs::iterator Program=Transport_Stream->second.Programs.begin(); Program!=Transport_Stream->second.Programs.end(); ++Program)
1141         {
1142             if (Program->second.IsParsed)
1143             {
1144                 bool EPGs_IsUpdated=false;
1145                 std::map<Ztring, Ztring> EPGs;
1146 
1147                 //EPG - DVB
1148                 if (Program->second.DVB_EPG_Blocks_IsUpdated)
1149                 {
1150                     for (complete_stream::transport_stream::program::dvb_epg_blocks::iterator DVB_EPG_Block=Program->second.DVB_EPG_Blocks.begin(); DVB_EPG_Block!=Program->second.DVB_EPG_Blocks.end(); ++DVB_EPG_Block)
1151                         for (complete_stream::transport_stream::program::dvb_epg_block::events::iterator Event=DVB_EPG_Block->second.Events.begin(); Event!=DVB_EPG_Block->second.Events.end(); ++Event)
1152                             if (EPGs.find(Event->second.start_time)==EPGs.end() || DVB_EPG_Block->first==0x4E) //Does not exist or "DVB - event_information_section - actual_transport_stream : return present/following"
1153                                 EPGs[Event->second.start_time]=Event->second.short_event.event_name+__T(" / ")+Event->second.short_event.text+__T(" / ")+Event->second.content+__T(" /  / ")+Event->second.duration+__T(" / ")+Event->second.running_status;
1154                     Program->second.DVB_EPG_Blocks_IsUpdated=false;
1155                     EPGs_IsUpdated=true;
1156                 }
1157 
1158                 //EPG - ATSC
1159                 if (Program->second.source_id_IsValid)
1160                 {
1161                     complete_stream::sources::iterator Source=Complete_Stream->Sources.find(Program->second.source_id);
1162                     if (Source!=Complete_Stream->Sources.end())
1163                     {
1164                         if (!Source->second.texts.empty())
1165                         {
1166                             Ztring Texts;
1167                             for (std::map<int16u, Ztring>::iterator text=Source->second.texts.begin(); text!=Source->second.texts.end(); ++text)
1168                                 Texts+=text->second+__T(" - ");
1169                             if (!Texts.empty())
1170                                 Texts.resize(Texts.size()-3);
1171                             if (Program->second.StreamPos==(size_t)-1)
1172                             {
1173                                 Complete_Stream->program_number_Order.push_back(Program->first);
1174                                 Stream_Prepare(Stream_Menu);
1175                                 Program->second.StreamPos=StreamPos_Last;
1176                             }
1177                             Fill(Stream_Menu, Program->second.StreamPos, Menu_ServiceProvider, Texts, true);
1178                         }
1179                         if (Source->second.ATSC_EPG_Blocks_IsUpdated)
1180                         {
1181                             for (complete_stream::source::atsc_epg_blocks::iterator ATSC_EPG_Block=Source->second.ATSC_EPG_Blocks.begin(); ATSC_EPG_Block!=Source->second.ATSC_EPG_Blocks.end(); ++ATSC_EPG_Block)
1182                                 for (complete_stream::source::atsc_epg_block::events::iterator Event=ATSC_EPG_Block->second.Events.begin(); Event!=ATSC_EPG_Block->second.Events.end(); ++Event)
1183                                     if (Event->second.start_time!=(int32u)-1) //TODO: find the reason when start_time is not set
1184                                     {
1185                                         Ztring Texts;
1186                                         for (std::map<int16u, Ztring>::iterator text=Event->second.texts.begin(); text!=Event->second.texts.end(); ++text)
1187                                             Texts+=text->second+__T(" - ");
1188                                         if (!Texts.empty())
1189                                             Texts.resize(Texts.size()-3);
1190                                         EPGs[Ztring().Date_From_Seconds_1970(Event->second.start_time+315964800-Complete_Stream->GPS_UTC_offset)]=Event->second.title+__T(" / ")+Texts+__T(" /  /  / ")+Event->second.duration+__T(" / ");
1191                                     }
1192                             Source->second.ATSC_EPG_Blocks_IsUpdated=false;
1193                             EPGs_IsUpdated=true;
1194                         }
1195                     }
1196                 }
1197 
1198                 //EPG - Filling
1199                 if (EPGs_IsUpdated)
1200                 {
1201                     if (Program->second.StreamPos==(size_t)-1)
1202                     {
1203                         Complete_Stream->program_number_Order.push_back(Program->first);
1204                         Stream_Prepare(Stream_Menu);
1205                         Program->second.StreamPos=StreamPos_Last;
1206                     }
1207 
1208                     Program->second.EPGs=EPGs;
1209                     Streams_Update_EPG_PerProgram(Program);
1210                 }
1211             }
1212         }
1213 
1214     Complete_Stream->Sources_IsUpdated=false;
1215     Complete_Stream->Programs_IsUpdated=false;
1216 }
1217 
1218 //---------------------------------------------------------------------------
Streams_Update_EPG_PerProgram(complete_stream::transport_stream::programs::iterator Program)1219 void File_MpegTs::Streams_Update_EPG_PerProgram(complete_stream::transport_stream::programs::iterator Program)
1220 {
1221     size_t Chapters_Pos_Begin=Retrieve(Stream_Menu, Program->second.StreamPos, Menu_Chapters_Pos_Begin).To_int32u();
1222     size_t Chapters_Pos_End=Retrieve(Stream_Menu, Program->second.StreamPos, Menu_Chapters_Pos_End).To_int32u();
1223     if (Chapters_Pos_Begin && Chapters_Pos_End)
1224     {
1225         for (size_t Pos=Chapters_Pos_End-1; Pos>=Chapters_Pos_Begin; Pos--)
1226             Clear(Stream_Menu, Program->second.StreamPos, Pos);
1227         Clear(Stream_Menu, Program->second.StreamPos, Menu_Chapters_Pos_Begin);
1228         Clear(Stream_Menu, Program->second.StreamPos, Menu_Chapters_Pos_End);
1229     }
1230     if (!Program->second.EPGs.empty())
1231     {
1232         Fill(Stream_Menu, Program->second.StreamPos, Menu_Chapters_Pos_Begin, Count_Get(Stream_Menu, Program->second.StreamPos), 10, true);
1233         for (std::map<Ztring, Ztring>::iterator EPG=Program->second.EPGs.begin(); EPG!=Program->second.EPGs.end(); ++EPG)
1234             Fill(Stream_Menu, Program->second.StreamPos, EPG->first.To_UTF8().c_str(), EPG->second, true);
1235         Fill(Stream_Menu, Program->second.StreamPos, Menu_Chapters_Pos_End, Count_Get(Stream_Menu, Program->second.StreamPos), 10, true);
1236     }
1237 }
1238 
1239 //---------------------------------------------------------------------------
1240 #ifdef MEDIAINFO_MPEGTS_PCR_YES
Streams_Update_Duration_Update()1241 void File_MpegTs::Streams_Update_Duration_Update()
1242 {
1243     bool IsVbr=false;
1244     bool IsCbr=false;
1245     #if MEDIAINFO_ADVANCED
1246         float64 TimeStamp_InstantaneousBitRate_Min_Raw=DBL_MAX;
1247         float64 TimeStamp_InstantaneousBitRate_Max_Raw=0;
1248         int64u  TimeStamp_Distance_Min=(int64u)-1;
1249         int64u  TimeStamp_Distance_Max=0;
1250         int64u  TimeStamp_Distance_Total=0;
1251         int64u  TimeStamp_Distance_Count=0;
1252         int64u  TimeStamp_HasProblems=0;
1253     #endif // MEDIAINFO_ADVANCED
1254 
1255     int64u Duration_Count=0;
1256     int64u Duration_Max=0;
1257     int64u Duration_Sum=0;
1258     int64u Bytes_Sum=0;
1259     for (std::map<int16u, int16u>::iterator PCR_PID=Complete_Stream->PCR_PIDs.begin(); PCR_PID!=Complete_Stream->PCR_PIDs.end(); ++PCR_PID)
1260     {
1261         complete_stream::streams::iterator Stream=Complete_Stream->Streams.begin()+PCR_PID->first;
1262         if (*Stream && (*Stream)->TimeStamp_End_IsUpdated)
1263         {
1264             if ((*Stream)->TimeStamp_End<0x100000000LL*300 && (*Stream)->TimeStamp_Start>0x100000000LL*300)
1265                 (*Stream)->TimeStamp_End+=0x200000000LL*300; //33 bits, cyclic
1266             if ((*Stream)->TimeStamp_Start<(*Stream)->TimeStamp_End)
1267             {
1268                 int64u  Duration=0;
1269                 int64u  Bytes=0;
1270                 #if MEDIAINFO_ADVANCED
1271                     if (Config->ParseSpeed>=1 && !(*Stream)->TimeStamp_Intermediate.empty())
1272                     {
1273                         Duration=(*Stream)->TimeStamp_Intermediate[0]-(*Stream)->TimeStamp_Start;
1274                         size_t Last=(*Stream)->TimeStamp_Intermediate.size()-1;
1275                         for (size_t Pos=1; Pos+1<Last; Pos+=2)
1276                             Duration+=(*Stream)->TimeStamp_Intermediate[Pos+1]-(*Stream)->TimeStamp_Intermediate[Pos];
1277                         Duration+=(*Stream)->TimeStamp_End-(*Stream)->TimeStamp_Intermediate[Last];
1278                     }
1279                     else
1280                 #endif // MEDIAINFO_ADVANCED
1281                 {
1282                     Duration=(*Stream)->TimeStamp_End-(*Stream)->TimeStamp_Start;
1283                 }
1284                 Bytes=(*Stream)->TimeStamp_End_Offset-(*Stream)->TimeStamp_Start_Offset;
1285 
1286                 if (Duration>Duration_Max)
1287                     Duration_Max=Duration;
1288                 Duration_Count++;
1289                 Duration_Sum+=Duration;
1290                 Bytes_Sum+=Bytes;
1291 
1292                 (*Stream)->TimeStamp_End_IsUpdated=false;
1293                 (*Stream)->IsPCR_Duration=(float64)Duration;
1294 
1295                 //Filling menu duration
1296                 if (Count_Get(Stream_Menu))
1297                 {
1298                     complete_stream::transport_streams::iterator Transport_Stream=Complete_Stream->transport_stream_id_IsValid?Complete_Stream->Transport_Streams.find(Complete_Stream->transport_stream_id):Complete_Stream->Transport_Streams.end();
1299                     if (Transport_Stream!=Complete_Stream->Transport_Streams.end())
1300                     {
1301                         //Per program
1302                         for (size_t Pos=0; Pos<(*Stream)->program_numbers.size(); Pos++)
1303                         {
1304                             int16u program_number=(*Stream)->program_numbers[Pos];
1305                             if (Transport_Stream->second.Programs[program_number].IsRegistered) //Only if the menu is already displayed
1306                                 Fill(Stream_Menu, Transport_Stream->second.Programs[program_number].StreamPos, Menu_Duration, ((float64)Duration)/27000, 6, true);
1307                         }
1308                     }
1309                 }
1310             }
1311 
1312             if ((*Stream)->TimeStamp_InstantaneousBitRate_BitRateMode_IsVbr>=Config_VbrDetection_Occurences)
1313                 IsVbr=true;
1314             if ((*Stream)->TimeStamp_InstantaneousBitRate_BitRateMode_IsCbr)
1315                 IsCbr=true;
1316             #if MEDIAINFO_ADVANCED
1317                 if (Config->ParseSpeed>=1)
1318                 {
1319                     if (TimeStamp_InstantaneousBitRate_Min_Raw>(*Stream)->TimeStamp_InstantaneousBitRate_Min_Raw)
1320                         TimeStamp_InstantaneousBitRate_Min_Raw=(*Stream)->TimeStamp_InstantaneousBitRate_Min_Raw;
1321                     if (TimeStamp_InstantaneousBitRate_Max_Raw<(*Stream)->TimeStamp_InstantaneousBitRate_Max_Raw)
1322                         TimeStamp_InstantaneousBitRate_Max_Raw=(*Stream)->TimeStamp_InstantaneousBitRate_Max_Raw;
1323                     TimeStamp_Distance_Total+=(*Stream)->TimeStamp_Distance_Total;
1324                     TimeStamp_Distance_Count+=(*Stream)->TimeStamp_Distance_Count;
1325                     if (TimeStamp_Distance_Min>(*Stream)->TimeStamp_Distance_Min)
1326                         TimeStamp_Distance_Min=(*Stream)->TimeStamp_Distance_Min;
1327                     if (TimeStamp_Distance_Max<(*Stream)->TimeStamp_Distance_Max)
1328                         TimeStamp_Distance_Max=(*Stream)->TimeStamp_Distance_Max;
1329                     TimeStamp_HasProblems+=(*Stream)->TimeStamp_HasProblems;
1330                 }
1331             #endif // MEDIAINFO_ADVANCED
1332         }
1333     }
1334 
1335     if (Duration_Max)
1336         Fill(Stream_General, 0, General_Duration, ((float64)Duration_Max) / 27000, 6, true);
1337     if (Duration_Count && Duration_Sum && Bytes_Sum)
1338     {
1339         //Filling Duration and bitrate with an average of content from all streams with PCR
1340         //Min and Max are based on a a 1 byte precision in the computed byte count + +/- 500 ns tolerance for hte PCR vale
1341         Fill(Stream_General, 0, General_OverallBitRate, Bytes_Sum * 8 / (((float64)Duration_Sum) / 27000000), 0, true);
1342         Fill(Stream_General, 0, "OverallBitRate_Precision_Min", (Bytes_Sum - Duration_Count) * 8 / (((float64)(Duration_Sum + 13500 * Duration_Count)) / 27000000), 0, true);
1343         Fill_SetOptions(Stream_General, 0, "OverallBitRate_Precision_Min", "N NT");
1344         Fill(Stream_General, 0, "OverallBitRate_Precision_Max", (Bytes_Sum + Duration_Count) * 8 / (((float64)(Duration_Sum - 13500 * Duration_Count)) / 27000000), 0, true);
1345         Fill_SetOptions(Stream_General, 0, "OverallBitRate_Precision_Max", "N NT");
1346     }
1347 
1348     if (IsVbr)
1349         Fill(Stream_General, 0, General_OverallBitRate_Mode, "VBR", Unlimited, true, true);
1350     else if (IsCbr)
1351         Fill(Stream_General, 0, General_OverallBitRate_Mode, "CBR", Unlimited, true, true);
1352     else
1353         Clear(Stream_General, 0, General_OverallBitRate_Mode);
1354     #if MEDIAINFO_ADVANCED
1355         if (Config->ParseSpeed>=1)
1356         {
1357             if ((IsVbr || !IsCbr) && TimeStamp_InstantaneousBitRate_Min_Raw<DBL_MAX)
1358                 Fill(Stream_General, 0, General_OverallBitRate_Minimum, TimeStamp_InstantaneousBitRate_Min_Raw, 0, true);
1359             else
1360                 Clear(Stream_General, 0, General_OverallBitRate_Minimum);
1361             if ((IsVbr || !IsCbr) && TimeStamp_InstantaneousBitRate_Max_Raw)
1362                 Fill(Stream_General, 0, General_OverallBitRate_Maximum, TimeStamp_InstantaneousBitRate_Max_Raw, 0, true);
1363             else
1364                 Clear(Stream_General, 0, General_OverallBitRate_Maximum);
1365             if (TimeStamp_Distance_Count)
1366             {
1367                 Fill(Stream_General, 0, "PCR_Distance_Average", ((float64)TimeStamp_Distance_Total)/27000000/TimeStamp_Distance_Count, 9, true);
1368                 Fill_SetOptions(Stream_General, 0, "PCR_Distance_Average", "N NT");
1369             }
1370             if (TimeStamp_Distance_Min!=(int64u)-1)
1371             {
1372                 Fill(Stream_General, 0, "PCR_Distance_Min", ((float64)TimeStamp_Distance_Min)/27000000, 9, true);
1373                 Fill_SetOptions(Stream_General, 0, "PCR_Distance_Min", "N NT");
1374             }
1375             if (TimeStamp_Distance_Max)
1376             {
1377                 Fill(Stream_General, 0, "PCR_Distance_Max", ((float64)TimeStamp_Distance_Max)/27000000, 9, true);
1378                 Fill_SetOptions(Stream_General, 0, "PCR_Distance_Max", "N NT");
1379             }
1380             {
1381                 Fill(Stream_General, 0, "PCR_Invalid_Count", TimeStamp_HasProblems, 10, true);
1382                 Fill_SetOptions(Stream_General, 0, "PCR_Invalid_Count", "N NT");
1383             }
1384 
1385         }
1386     #endif // MEDIAINFO_ADVANCED
1387 }
1388 #endif //MEDIAINFO_MPEGTS_PCR_YES
1389 
1390 //---------------------------------------------------------------------------
Streams_Update_Duration_End()1391 void File_MpegTs::Streams_Update_Duration_End()
1392 {
1393     //General
1394     Fill(Stream_General, 0, General_Duration_End, Complete_Stream->Duration_End, true);
1395 
1396     Complete_Stream->Duration_End_IsUpdated=false;
1397 }
1398 
1399 //---------------------------------------------------------------------------
Streams_Finish()1400 void File_MpegTs::Streams_Finish()
1401 {
1402     //Per stream
1403     for (size_t StreamID=0; StreamID<0x2000; StreamID++)
1404         if (Complete_Stream->Streams[StreamID]->Parser)
1405         {
1406             if (!Complete_Stream->Streams[StreamID]->Parser->Status[IsFinished])
1407             {
1408                 int64u File_Size_Temp=File_Size;
1409                 File_Size=File_Offset+Buffer_Offset+Element_Offset;
1410                 Open_Buffer_Continue(Complete_Stream->Streams[StreamID]->Parser, Buffer, 0, false);
1411                 File_Size=File_Size_Temp;
1412                 Finish(Complete_Stream->Streams[StreamID]->Parser);
1413                 #if MEDIAINFO_DEMUX
1414                     if (Config->Demux_EventWasSent)
1415                         return;
1416                 #endif //MEDIAINFO_DEMUX
1417             }
1418         }
1419 
1420     #if MEDIAINFO_DUPLICATE
1421         File__Duplicate_Streams_Finish();
1422     #endif //MEDIAINFO_DUPLICATE
1423 
1424     #if MEDIAINFO_IBIUSAGE
1425         if (!IsSub && Config_Ibi_Create)
1426         {
1427             for (ibi::streams::iterator IbiStream_Temp=Ibi.Streams.begin(); IbiStream_Temp!=Ibi.Streams.end(); ++IbiStream_Temp)
1428             {
1429                 if (IbiStream_Temp->second && IbiStream_Temp->second->DtsFrequencyNumerator==1000000000 && IbiStream_Temp->second->DtsFrequencyDenominator==1)
1430                 {
1431                     bool IsOk=true;
1432                     for (size_t Pos=0; Pos<IbiStream_Temp->second->Infos.size(); Pos++)
1433                         if (!IbiStream_Temp->second->Infos[Pos].IsContinuous && Pos+1!=IbiStream_Temp->second->Infos.size())
1434                             IsOk=false;
1435                     if (IsOk) //Only is all items are continuous (partial IBI not yet supported)
1436                     {
1437                         IbiStream_Temp->second->DtsFrequencyNumerator=90000;
1438                         for (size_t Pos=0; Pos<IbiStream_Temp->second->Infos.size(); Pos++)
1439                         {
1440                             int64u Temp=IbiStream_Temp->second->Infos[Pos].Dts*90/1000000;
1441                             IbiStream_Temp->second->Infos[Pos].Dts=Temp;
1442                         }
1443                     }
1444                 }
1445             }
1446         }
1447     #endif //MEDIAINFO_IBIUSAGE
1448 }
1449 
1450 //***************************************************************************
1451 // Buffer - Synchro
1452 //***************************************************************************
1453 
1454 //---------------------------------------------------------------------------
Synchronize()1455 bool File_MpegTs::Synchronize()
1456 {
1457     //Synchronizing
1458     while (       Buffer_Offset+188*16+BDAV_Size*16+TSP_Size*16<=Buffer_Size
1459       && !(Buffer[Buffer_Offset+188* 0+BDAV_Size* 1+TSP_Size* 0]==0x47
1460         && Buffer[Buffer_Offset+188* 1+BDAV_Size* 2+TSP_Size* 1]==0x47
1461         && Buffer[Buffer_Offset+188* 2+BDAV_Size* 3+TSP_Size* 2]==0x47
1462         && Buffer[Buffer_Offset+188* 3+BDAV_Size* 4+TSP_Size* 3]==0x47
1463         && Buffer[Buffer_Offset+188* 4+BDAV_Size* 5+TSP_Size* 4]==0x47
1464         && Buffer[Buffer_Offset+188* 5+BDAV_Size* 6+TSP_Size* 5]==0x47
1465         && Buffer[Buffer_Offset+188* 6+BDAV_Size* 7+TSP_Size* 6]==0x47
1466         && Buffer[Buffer_Offset+188* 7+BDAV_Size* 8+TSP_Size* 7]==0x47
1467         && Buffer[Buffer_Offset+188* 8+BDAV_Size* 9+TSP_Size* 8]==0x47
1468         && Buffer[Buffer_Offset+188* 9+BDAV_Size*10+TSP_Size* 9]==0x47
1469         && Buffer[Buffer_Offset+188*10+BDAV_Size*11+TSP_Size*10]==0x47
1470         && Buffer[Buffer_Offset+188*11+BDAV_Size*12+TSP_Size*11]==0x47
1471         && Buffer[Buffer_Offset+188*12+BDAV_Size*13+TSP_Size*12]==0x47
1472         && Buffer[Buffer_Offset+188*13+BDAV_Size*14+TSP_Size*13]==0x47
1473         && Buffer[Buffer_Offset+188*14+BDAV_Size*15+TSP_Size*14]==0x47
1474         && Buffer[Buffer_Offset+188*15+BDAV_Size*16+TSP_Size*15]==0x47))
1475     {
1476         Buffer_Offset++;
1477         while (       Buffer_Offset+BDAV_Size+1<=Buffer_Size
1478             && Buffer[Buffer_Offset+BDAV_Size]!=0x47)
1479             Buffer_Offset++;
1480     }
1481 
1482     if (Buffer_Offset+188*16+BDAV_Size*16+TSP_Size*16>=Buffer_Size
1483     #ifdef MEDIAINFO_ARIBSTDB24B37_YES
1484      && !FromAribStdB24B37
1485     #endif
1486         )
1487         return false;
1488 
1489     //Synched is OK
1490     return true;
1491 }
1492 
1493 //---------------------------------------------------------------------------
Synched_Test()1494 bool File_MpegTs::Synched_Test()
1495 {
1496     while (Buffer_Offset+TS_Size<=Buffer_Size)
1497     {
1498         //Synchro testing
1499         if (Buffer[Buffer_Offset+BDAV_Size]!=0x47)
1500         {
1501             Synched=false;
1502             #if MEDIAINFO_DUPLICATE
1503                 if (File__Duplicate_Get())
1504                     Trusted++; //We don't want to stop parsing if duplication is requested, TS is not a lot stable, normal...
1505             #endif //MEDIAINFO_DUPLICATE
1506             return true;
1507         }
1508 
1509         //Getting pid
1510         pid=(Buffer[Buffer_Offset+BDAV_Size+1]&0x1F)<<8
1511           |  Buffer[Buffer_Offset+BDAV_Size+2];
1512 
1513         complete_stream::stream* Stream=Complete_Stream->Streams[pid];
1514         if (Stream->Searching)
1515         {
1516             //Trace config
1517             #if MEDIAINFO_TRACE
1518                 if (Config_Trace_Level)
1519                 {
1520                     if (Stream->Kind==complete_stream::stream::pes)
1521                     {
1522                         if (!Trace_Layers[8])
1523                             Trace_Layers_Update(8); //Stream
1524                     }
1525                     else
1526                         Trace_Layers_Update(IsSub?1:0);
1527                 }
1528             #endif //MEDIAINFO_TRACE
1529 
1530             payload_unit_start_indicator=(Buffer[Buffer_Offset+BDAV_Size+1]&0x40)!=0;
1531             if (payload_unit_start_indicator)
1532             {
1533                 //Searching start
1534                 if (Stream->Searching_Payload_Start) //payload_unit_start_indicator
1535                 {
1536                     if (Stream->Kind==complete_stream::stream::psi)
1537                     {
1538                         //Searching table_id
1539                         size_t Version_Pos=BDAV_Size
1540                                           +4 //standart header
1541                                           +((Buffer[Buffer_Offset+BDAV_Size+3]&0x20)?(1+Buffer[Buffer_Offset+BDAV_Size+4]):0); //adaptation_field_control (adaptation) --> adaptation_field_length
1542                         if (Version_Pos>=BDAV_Size+188)
1543                             return true; //There is a problem with this block, accelerated parsing disabled
1544                         Version_Pos+=1+Buffer[Buffer_Offset+Version_Pos]; //pointer_field
1545                         if (Version_Pos>=BDAV_Size+188)
1546                             return true; //There is a problem with this block, accelerated parsing disabled
1547                         int8u table_id=Buffer[Buffer_Offset+Version_Pos]; //table_id
1548                         #if MEDIAINFO_TRACE
1549                             if (Trace_Activated)
1550                                 Stream->Element_Info1=Mpeg_Psi_table_id(table_id);
1551                         #endif //MEDIAINFO_TRACE
1552                         if (table_id==0xCD) //specifc case for ATSC STT
1553                         {
1554                             if (Config_Trace_TimeSection_OnlyFirstOccurrence)
1555                             {
1556                                 if (!TimeSection_FirstOccurrenceParsed)
1557                                     TimeSection_FirstOccurrenceParsed=true;
1558                                 #if MEDIAINFO_TRACE
1559                                 else
1560                                 {
1561                                     Trace_Layers.reset(); //We do not want to display data about other occurences
1562                                     Trace_Layers_Update();
1563                                 }
1564                                 #endif //MEDIAINFO_TRACE
1565                             }
1566                             return true; //Version has no meaning
1567                         }
1568                         #if MEDIAINFO_IBIUSAGE
1569                             if (table_id==0x00)
1570                                 Complete_Stream->Streams[pid]->Ibi_SynchronizationOffset_BeginOfFrame=File_Offset+Buffer_Offset;
1571                             if (table_id==0x02)
1572                                 Complete_Stream->Streams[pid]->Ibi_SynchronizationOffset_BeginOfFrame=Complete_Stream->Streams[0x0000]->Ibi_SynchronizationOffset_BeginOfFrame;
1573                         #endif //MEDIAINFO_IBIUSAGE
1574                         complete_stream::stream::table_ids::iterator Table_ID=Stream->Table_IDs.begin()+table_id;
1575                         if (*Table_ID)
1576                         {
1577                             //Searching table_id_extension, version_number, section_number
1578                             if (!(Buffer[Buffer_Offset+Version_Pos+1]&0x80)) //section_syntax_indicator
1579                             {
1580                                 if (table_id==0x70 && Config_Trace_TimeSection_OnlyFirstOccurrence)
1581                                 {
1582                                     if (!TimeSection_FirstOccurrenceParsed)
1583                                         TimeSection_FirstOccurrenceParsed=true;
1584                                     #if MEDIAINFO_TRACE
1585                                     else
1586                                     {
1587                                         Trace_Layers.reset(); //We do not want to display data about other occurences
1588                                         Trace_Layers_Update();
1589                                     }
1590                                     #endif //MEDIAINFO_TRACE
1591                                 }
1592                                 return true; //No version
1593                             }
1594                             Version_Pos+=3; //Header size
1595                             if (Version_Pos+5>=BDAV_Size+188)
1596                                 return true; //Not able to detect version (too far)
1597                             int16u table_id_extension=(Buffer[Buffer_Offset+Version_Pos]<<8)|Buffer[Buffer_Offset+Version_Pos+1];
1598                             int8u  version_number=(Buffer[Buffer_Offset+Version_Pos+2]&0x3F)>>1;
1599                             int8u  section_number=Buffer[Buffer_Offset+Version_Pos+3];
1600                             complete_stream::stream::table_id::table_id_extensions::iterator Table_ID_Extension=(*Table_ID)->Table_ID_Extensions.find(table_id_extension);
1601                             if (Table_ID_Extension==(*Table_ID)->Table_ID_Extensions.end())
1602                             {
1603                                 if ((*Table_ID)->Table_ID_Extensions_CanAdd)
1604                                 {
1605                                     (*Table_ID)->Table_ID_Extensions[table_id_extension].version_number=version_number;
1606                                     (*Table_ID)->Table_ID_Extensions[table_id_extension].Section_Numbers.resize(0x100);
1607                                     (*Table_ID)->Table_ID_Extensions[table_id_extension].Section_Numbers[section_number]=true;
1608                                     return true; //table_id_extension is not yet parsed
1609                                 }
1610                             }
1611                             else if (Table_ID_Extension->second.version_number!=version_number)
1612                             {
1613                                 if (Table_ID_Extension->second.version_number!=(int8u)-1 && Config_Trace_TimeSection_OnlyFirstOccurrence)
1614                                     break;
1615                                 Table_ID_Extension->second.version_number=version_number;
1616                                 Table_ID_Extension->second.Section_Numbers.clear();
1617                                 Table_ID_Extension->second.Section_Numbers.resize(0x100);
1618                                 Table_ID_Extension->second.Section_Numbers[section_number]=true;
1619                                 return true; //version is different
1620                             }
1621                             else if (!Table_ID_Extension->second.Section_Numbers[section_number])
1622                             {
1623                                 Table_ID_Extension->second.Section_Numbers[section_number]=true;
1624                                 return true; //section is not yet parsed
1625                             }
1626                             else if (table_id==0x02 && Complete_Stream->Transport_Streams[Complete_Stream->transport_stream_id].Programs_NotParsedCount)
1627                             {
1628                                 //PMT is looping, so this is nearly sure that all PMT available in the stream are assigned
1629                                 #ifdef MEDIAINFO_MPEGTS_ALLSTREAMS_YES
1630                                     for (size_t pid=0x10; pid<0x1FFF; pid++) //Wanting 0x10-->0x2F (DVB), 0x1ABC (cea_osd), 0x1FF7-->0x1FFF (ATSC)
1631                                         for (size_t Table_ID=0x00; Table_ID<0xFF; Table_ID++)
1632                                         {
1633                                             Complete_Stream->Streams[pid]->init(Table_ID); //event_information_section - actual_transport_stream, schedule
1634 
1635                                             if (Pos==0x001F)
1636                                                 Pos=0x1ABB; //Skipping normal data
1637                                             if (Pos==0x01ABC)
1638                                                 Pos=0x1FF6; //Skipping normal data
1639                                         }
1640                                 #else //MEDIAINFO_MPEGTS_ALLSTREAMS_YES
1641                                     if (Complete_Stream->Streams[0x0010]->Kind==complete_stream::stream::unknown)
1642                                     {
1643                                         Complete_Stream->Streams[0x0010]->init(0x40); //network_information_section - actual_network
1644                                     }
1645                                     if (Complete_Stream->Streams[0x0011]->Kind==complete_stream::stream::unknown)
1646                                     {
1647                                         Complete_Stream->Streams[0x0011]->init(0x42); //service_description_section - actual_transport_stream
1648                                     }
1649                                     if (Complete_Stream->Streams[0x0012]->Kind==complete_stream::stream::unknown)
1650                                     {
1651                                         Complete_Stream->Streams[0x0012]->init(0x4E); //event_information_section - actual_transport_stream, present/following
1652                                         for (size_t Table_ID=0x50; Table_ID<0x60; Table_ID++)
1653                                             Complete_Stream->Streams[0x0012]->Table_IDs[Table_ID]=new complete_stream::stream::table_id; //event_information_section - actual_transport_stream, schedule
1654                                     }
1655                                     if (Complete_Stream->Streams[0x0014]->Kind==complete_stream::stream::unknown)
1656                                     {
1657                                         Complete_Stream->Streams[0x0014]->init(0x70); //time_date_section
1658                                         Complete_Stream->Streams[0x0014]->Table_IDs[0x73]=new complete_stream::stream::table_id; //time_offset_section
1659                                     }
1660                                     if (Complete_Stream->Streams[0x1FFB]->Kind==complete_stream::stream::unknown)
1661                                     {
1662                                         Complete_Stream->Streams[0x1FFB]->init(0xC7); //Master Guide Table
1663                                         Complete_Stream->Streams[0x1FFB]->Table_IDs[0xCD]=new complete_stream::stream::table_id; //System Time Table
1664                                     }
1665                                 #endif //MEDIAINFO_MPEGTS_ALLSTREAMS_YES
1666                             }
1667                         }
1668                     }
1669                     else
1670                         return true; //No version in this pid
1671                 }
1672             }
1673 
1674             //Searching continue and parser timestamp
1675             if (Stream->Searching_Payload_Continue
1676             #ifdef MEDIAINFO_MPEGTS_PESTIMESTAMP_YES
1677                  || Stream->Searching_ParserTimeStamp_Start
1678                  || Stream->Searching_ParserTimeStamp_End
1679             #endif //MEDIAINFO_MPEGTS_PESTIMESTAMP_YES
1680              )
1681                 return true;
1682 
1683             //Adaptation layer
1684             #ifdef MEDIAINFO_MPEGTS_PCR_YES
1685                 if (( Stream->Searching_TimeStamp_Start
1686                   ||  Stream->Searching_TimeStamp_End)
1687                 #ifdef MEDIAINFO_MPEGTS_PESTIMESTAMP_YES
1688                  &&  !Stream->Searching_ParserTimeStamp_End
1689                 #endif //MEDIAINFO_MPEGTS_PESTIMESTAMP_YES
1690                   )
1691                 {
1692                     if ((Buffer[Buffer_Offset+BDAV_Size+3]&0x20)==0x20) //adaptation_field_control (adaptation)
1693                     {
1694                         int8u adaptation_field_length=Buffer[Buffer_Offset+BDAV_Size+4];
1695                         if (adaptation_field_length>=5) //adaptation_field_length
1696                         {
1697                             bool discontinuity_indicator=(Buffer[Buffer_Offset+BDAV_Size+5]&0x80)!=0;
1698                             bool PCR_flag=(Buffer[Buffer_Offset+BDAV_Size+5]&0x10)!=0;
1699                             if (PCR_flag)
1700                             {
1701                                 int64u program_clock_reference=(  (((int64u)Buffer[Buffer_Offset+BDAV_Size+6])<<25)
1702                                                                 | (((int64u)Buffer[Buffer_Offset+BDAV_Size+7])<<17)
1703                                                                 | (((int64u)Buffer[Buffer_Offset+BDAV_Size+8])<< 9)
1704                                                                 | (((int64u)Buffer[Buffer_Offset+BDAV_Size+9])<< 1)
1705                                                                 | (((int64u)Buffer[Buffer_Offset+BDAV_Size+10])>>7));
1706                                 program_clock_reference*=300;
1707                                 program_clock_reference+=(  (((int64u)Buffer[Buffer_Offset+BDAV_Size+10]&0x01)<<8)
1708                                                           | (((int64u)Buffer[Buffer_Offset+BDAV_Size+11])   ));
1709                                 if (Complete_Stream->Streams[pid]->Searching_TimeStamp_End
1710                                 #ifdef MEDIAINFO_MPEGTS_PESTIMESTAMP_YES
1711                                  && (!Complete_Stream->Streams[pid]->Searching_ParserTimeStamp_End
1712                                   || Complete_Stream->Streams[pid]->IsPCR) //If PCR, we always want it.
1713                                 #endif //MEDIAINFO_MPEGTS_PESTIMESTAMP_YES
1714                                 )
1715                                 {
1716                                     Header_Parse_Events_Duration_Helper(program_clock_reference,discontinuity_indicator);
1717                                 }
1718                                 if (Complete_Stream->Streams[pid]->Searching_TimeStamp_Start)
1719                                 {
1720                                     //This is the first PCR
1721                                     Complete_Stream->Streams[pid]->TimeStamp_Start=program_clock_reference;
1722                                     Complete_Stream->Streams[pid]->TimeStamp_Start_Offset=File_Offset+Buffer_Offset;
1723                                     Complete_Stream->Streams[pid]->TimeStamp_End=program_clock_reference;
1724                                     Complete_Stream->Streams[pid]->TimeStamp_End_IsUpdated=true;
1725                                     Complete_Stream->Streams[pid]->TimeStamp_End_Offset=File_Offset+Buffer_Offset;
1726                                     Complete_Stream->Streams[pid]->Searching_TimeStamp_Start_Set(false);
1727                                     Complete_Stream->Streams[pid]->Searching_TimeStamp_End_Set(true);
1728                                     Complete_Stream->Streams_With_StartTimeStampCount++;
1729                                     {
1730                                         Status[IsUpdated]=true;
1731                                         Status[User_16]=true;
1732                                     }
1733                                 }
1734 
1735                                 //Test if we can find the TS bitrate
1736                                 if (!Complete_Stream->Streams[pid]->EndTimeStampMoreThanxSeconds && Complete_Stream->Streams[pid]->TimeStamp_Start!=(int64u)-1
1737                                 && (File_Offset+Buffer_Offset-Buffer_TotalBytes_FirstSynched)*2<File_Size)
1738                                 {
1739                                     if (program_clock_reference<Complete_Stream->Streams[pid]->TimeStamp_Start)
1740                                     {
1741                                         if (Complete_Stream->Streams[pid]->TimeStamp_Start-program_clock_reference<10LL*90000*300) //Testing if difference is less that 10 seconds (value arbitrary choosen)
1742                                             Complete_Stream->Streams[pid]->TimeStamp_Start=program_clock_reference; //Looks like we have a small jump in the past in a buggy file, accepting it.
1743                                         else
1744                                             program_clock_reference+=0x200000000LL*300; //33 bits, cyclic
1745                                     }
1746                                     if ((program_clock_reference-Complete_Stream->Streams[pid]->TimeStamp_Start)>Begin_MaxDuration)
1747                                     {
1748                                         Complete_Stream->Streams[pid]->EndTimeStampMoreThanxSeconds=true;
1749                                         Complete_Stream->Streams_With_EndTimeStampMoreThanxSecondsCount++;
1750                                         if (Complete_Stream->Streams_NotParsedCount
1751                                          && Complete_Stream->Streams_With_StartTimeStampCount>0
1752                                          && Complete_Stream->Streams_With_StartTimeStampCount==Complete_Stream->Streams_With_EndTimeStampMoreThanxSecondsCount)
1753                                         {
1754                                             //We are already parsing 16 seconds (for all PCRs), we don't hope to have more info
1755                                             MpegTs_JumpTo_Begin=File_Offset+Buffer_Offset-Buffer_TotalBytes_FirstSynched;
1756                                             MpegTs_JumpTo_End=MpegTs_JumpTo_Begin;
1757                                             if (MpegTs_JumpTo_Begin+MpegTs_JumpTo_End>=File_Size)
1758                                             {
1759                                                 if (MpegTs_JumpTo_Begin+MpegTs_JumpTo_End>File_Size)
1760                                                 {
1761                                                     MpegTs_JumpTo_Begin=File_Size;
1762                                                     MpegTs_JumpTo_End=0;
1763                                                 }
1764                                                 else
1765                                                     MpegTs_JumpTo_Begin=File_Size-MpegTs_JumpTo_End;
1766                                             }
1767                                         }
1768                                     }
1769                                 }
1770                             }
1771                         }
1772                     }
1773                 }
1774             #endif //MEDIAINFO_MPEGTS_PCR_YES
1775         }
1776 
1777         #if MEDIAINFO_DUPLICATE
1778             if (Stream->ShouldDuplicate)
1779             {
1780                 Element_Size=TS_Size;
1781                 File__Duplicate_Write();
1782             }
1783         #endif //MEDIAINFO_DUPLICATE
1784 
1785         Header_Parse_Events();
1786 
1787         Buffer_Offset+=TS_Size;
1788     }
1789 
1790     if (File_Offset+Buffer_Size>=File_Size)
1791         Detect_EOF(); //for TRP files
1792 
1793     return false; //Not enough data
1794 }
1795 
1796 //---------------------------------------------------------------------------
Header_Parse_Events_Duration_Helper(int64u & program_clock_reference,const bool discontinuity_indicator)1797 void File_MpegTs::Header_Parse_Events_Duration_Helper(int64u& program_clock_reference, const bool discontinuity_indicator)
1798 {
1799     Header_Parse_Events_Duration(program_clock_reference);
1800     if (program_clock_reference!=Complete_Stream->Streams[pid]->TimeStamp_End) //Some PCRs are buggy (low precision), using the first stream offset in the case of duplicate PCR value
1801     {
1802         if (Complete_Stream->Streams[pid]->TimeStamp_End_Offset!=(int64u)-1)
1803         {
1804             if (program_clock_reference+0x12c00000000LL<Complete_Stream->Streams[pid]->TimeStamp_End)
1805                 program_clock_reference+=0x25800000000LL; //33 bits and *300
1806             if (!discontinuity_indicator && program_clock_reference>Complete_Stream->Streams[pid]->TimeStamp_End && program_clock_reference<Complete_Stream->Streams[pid]->TimeStamp_End+10*27000000) //Not before, not after 10 seconds, else there is a problem
1807             {
1808                 float64 Duration_InstantaneousBitRate_Min=(float64)(program_clock_reference-Complete_Stream->Streams[pid]->TimeStamp_End-(Config_VbrDetection_Delta?0:810));
1809                 float64 Duration_InstantaneousBitRate_Max=(float64)(program_clock_reference-Complete_Stream->Streams[pid]->TimeStamp_End+(Config_VbrDetection_Delta?0:810));
1810                 float64 Bytes_InstantaneousBitRate=(float64)(File_Offset+Buffer_Offset-Complete_Stream->Streams[pid]->TimeStamp_End_Offset);
1811                 float64 TimeStamp_InstantaneousBitRate_Current_Min=Bytes_InstantaneousBitRate*8/Duration_InstantaneousBitRate_Max*27000000*(1-Config_VbrDetection_Delta);
1812                 float64 TimeStamp_InstantaneousBitRate_Current_Raw=Bytes_InstantaneousBitRate*8/Duration_InstantaneousBitRate_Min*27000000;
1813                 float64 TimeStamp_InstantaneousBitRate_Current_Max=Bytes_InstantaneousBitRate*8/Duration_InstantaneousBitRate_Min*27000000*(1+Config_VbrDetection_Delta);
1814                 if (Complete_Stream->Streams[pid]->TimeStamp_InstantaneousBitRate_Current_Min)
1815                 {
1816                     if (TimeStamp_InstantaneousBitRate_Current_Max<Complete_Stream->Streams[pid]->TimeStamp_InstantaneousBitRate_Current_Min || TimeStamp_InstantaneousBitRate_Current_Min>Complete_Stream->Streams[pid]->TimeStamp_InstantaneousBitRate_Current_Max)
1817                     {
1818                         Complete_Stream->Streams[pid]->TimeStamp_InstantaneousBitRate_BitRateMode_IsVbr++;
1819                         #if MEDIAINFO_ADVANCED
1820                             if (Config_VbrDetection_GiveUp && Complete_Stream->Streams[pid]->TimeStamp_InstantaneousBitRate_BitRateMode_IsVbr>=Config_VbrDetection_Occurences)
1821                                 Config->ParseSpeed=0;
1822                         #endif // MEDIAINFO_ADVANCED
1823                     }
1824                     else
1825                         Complete_Stream->Streams[pid]->TimeStamp_InstantaneousBitRate_BitRateMode_IsCbr++;
1826                 }
1827                 float64 Duration_Min=(float64)(program_clock_reference-Complete_Stream->Streams[pid]->TimeStamp_End-1);
1828                 float64 Duration_Raw=(float64)(program_clock_reference-Complete_Stream->Streams[pid]->TimeStamp_End);
1829                 float64 Duration_Max=(float64)(program_clock_reference-Complete_Stream->Streams[pid]->TimeStamp_End+1);
1830                 float64 Bytes=(float64)(File_Offset+Buffer_Offset-Complete_Stream->Streams[pid]->TimeStamp_End_Offset);
1831                 float64 TimeStamp_Min=Bytes*8/Duration_Max*27000000*(1-Config_VbrDetection_Delta);
1832                 float64 TimeStamp_Raw=Bytes*8/Duration_Raw*27000000;
1833                 float64 TimeStamp_Max=Bytes*8/Duration_Min*27000000*(1+Config_VbrDetection_Delta);
1834                 Complete_Stream->Streams[pid]->TimeStamp_InstantaneousBitRate_Current_Min=TimeStamp_Min;
1835                 Complete_Stream->Streams[pid]->TimeStamp_InstantaneousBitRate_Current_Raw=TimeStamp_Raw;
1836                 Complete_Stream->Streams[pid]->TimeStamp_InstantaneousBitRate_Current_Max=TimeStamp_Max;
1837                 #if MEDIAINFO_ADVANCED
1838                     if (Complete_Stream->Streams[pid]->TimeStamp_InstantaneousBitRate_Min_Raw>TimeStamp_InstantaneousBitRate_Current_Raw)
1839                         Complete_Stream->Streams[pid]->TimeStamp_InstantaneousBitRate_Min_Raw=TimeStamp_InstantaneousBitRate_Current_Raw;
1840                     if (Complete_Stream->Streams[pid]->TimeStamp_InstantaneousBitRate_Max_Raw<TimeStamp_InstantaneousBitRate_Current_Raw)
1841                         Complete_Stream->Streams[pid]->TimeStamp_InstantaneousBitRate_Max_Raw=TimeStamp_InstantaneousBitRate_Current_Raw;
1842                     int64u Distance=program_clock_reference-Complete_Stream->Streams[pid]->TimeStamp_End;
1843                     if (Complete_Stream->Streams[pid]->TimeStamp_Distance_Min>Distance)
1844                         Complete_Stream->Streams[pid]->TimeStamp_Distance_Min=Distance;
1845                     if (Complete_Stream->Streams[pid]->TimeStamp_Distance_Max<Distance)
1846                         Complete_Stream->Streams[pid]->TimeStamp_Distance_Max=Distance;
1847                     Complete_Stream->Streams[pid]->TimeStamp_Distance_Total+=Distance;
1848                     Complete_Stream->Streams[pid]->TimeStamp_Distance_Count++;
1849                 #endif // MEDIAINFO_ADVANCED
1850             }
1851             #if MEDIAINFO_ADVANCED
1852                 else
1853                 {
1854                    if (!discontinuity_indicator)
1855                         Complete_Stream->Streams[pid]->TimeStamp_HasProblems++;
1856                    float64 Bytes=(float64)(File_Offset+Buffer_Offset-Complete_Stream->Streams[pid]->TimeStamp_End_Offset);
1857                    int64u TimeToAdd;
1858                    if (Complete_Stream->Streams[pid]->TimeStamp_InstantaneousBitRate_Current_Raw)
1859                        TimeToAdd=float64_int64s(Bytes*8/Complete_Stream->Streams[pid]->TimeStamp_InstantaneousBitRate_Current_Raw*27000000);
1860                    else
1861                        TimeToAdd=0;
1862                    Complete_Stream->Streams[pid]->TimeStamp_Intermediate.push_back(Complete_Stream->Streams[pid]->TimeStamp_End+TimeToAdd);
1863                    Complete_Stream->Streams[pid]->TimeStamp_Intermediate.push_back(program_clock_reference);
1864                 }
1865             #endif // MEDIAINFO_ADVANCED
1866         }
1867         Complete_Stream->Streams[pid]->TimeStamp_End=program_clock_reference;
1868         Complete_Stream->Streams[pid]->TimeStamp_End_IsUpdated=true;
1869         Complete_Stream->Streams[pid]->TimeStamp_End_Offset=File_Offset+Buffer_Offset;
1870         {
1871             Status[IsUpdated]=true;
1872             Status[User_16]=true;
1873         }
1874     }
1875 }
1876 //---------------------------------------------------------------------------
Synched_Init()1877 void File_MpegTs::Synched_Init()
1878 {
1879     Begin_MaxDuration=Config->ParseSpeed>=0.8?(int64u)-1:MediaInfoLib::Config.MpegTs_MaximumScanDuration_Get()*27/1000;
1880 
1881     //Config->File_Filter_Set(462);
1882     //Default values
1883     Complete_Stream=new complete_stream;
1884     Complete_Stream->Streams.resize(0x2000);
1885     for (size_t StreamID=0; StreamID<0x2000; StreamID++)
1886         Complete_Stream->Streams[StreamID]=new complete_stream::stream;
1887     Complete_Stream->Streams[0x0000]->init(0x00); // program_association_section
1888     Complete_Stream->Streams[0x0001]->init(0x01); // CA_section
1889     Complete_Stream->Streams[0x0002]->Searching_Payload_Start_Set(true);
1890     Complete_Stream->Streams[0x0002]->Kind=complete_stream::stream::psi;                        // Transport Stream Description Table
1891     Complete_Stream->Streams[0x0002]->Table_IDs.resize(0x100);
1892     Complete_Stream->Streams[0x0003]->Searching_Payload_Start_Set(true);
1893     Complete_Stream->Streams[0x0003]->Kind=complete_stream::stream::psi;                        // IPMP Control Information Table
1894     Complete_Stream->Streams[0x0003]->Table_IDs.resize(0x100);
1895 
1896     //Config
1897     Config_Trace_TimeSection_OnlyFirstOccurrence=MediaInfoLib::Config.Trace_TimeSection_OnlyFirstOccurrence_Get();
1898     TimeSection_FirstOccurrenceParsed=false;
1899     #if MEDIAINFO_ADVANCED
1900         Config_VbrDetection_Delta=MediaInfoLib::Config.MpegTs_VbrDetection_Delta_Get();
1901         Config_VbrDetection_Occurences=MediaInfoLib::Config.MpegTs_VbrDetection_Occurences_Get();
1902         Config_VbrDetection_GiveUp=MediaInfoLib::Config.MpegTs_VbrDetection_GiveUp_Get();
1903     #endif // MEDIAINFO_ADVANCED
1904 
1905     #ifdef MEDIAINFO_ARIBSTDB24B37_YES
1906         if (FromAribStdB24B37)
1907         {
1908             #if MEDIAINFO_EVENTS
1909                 StreamIDs_Width[0]=0;
1910             #endif //MEDIAINFO_EVENTS
1911             SetAllToPES();
1912         }
1913     #endif //MEDIAINFO_ARIBSTDB24B37_YES
1914 
1915     if (NoPatPmt)
1916         SetAllToPES(); //TODO: do not set up PAT ID when NoPatPmt is set
1917 
1918     //Continue, again, for Duplicate and Filter
1919     Option_Manage();
1920 }
1921 
1922 //***************************************************************************
1923 // Buffer - Global
1924 //***************************************************************************
1925 
1926 //---------------------------------------------------------------------------
Read_Buffer_Unsynched()1927 void File_MpegTs::Read_Buffer_Unsynched()
1928 {
1929     if (Complete_Stream==NULL || Complete_Stream->Streams.empty())
1930         return;
1931 
1932     for (size_t StreamID=0; StreamID<0x2000; StreamID++)//std::map<int64u, stream>::iterator Stream=Streams.begin(); Stream!=Streams.end(); Stream++)
1933     {
1934         //End timestamp is out of date
1935         #if defined(MEDIAINFO_MPEGTS_PCR_YES) || defined(MEDIAINFO_MPEGTS_PESTIMESTAMP_YES)
1936         Complete_Stream->Streams[StreamID]->Searching_TimeStamp_Start_Set(false); //No more searching start
1937         Complete_Stream->Streams[StreamID]->TimeStamp_End=(int64u)-1;
1938         Complete_Stream->Streams[StreamID]->TimeStamp_End_IsUpdated=false;
1939         Complete_Stream->Streams[StreamID]->TimeStamp_End_Offset=(int64u)-1;
1940         if (Complete_Stream->Streams[StreamID]->TimeStamp_Start!=(int64u)-1)
1941             Complete_Stream->Streams[StreamID]->Searching_TimeStamp_End_Set(true); //Searching only for a start found
1942         #endif //defined(MEDIAINFO_MPEGTS_PCR_YES) ||  defined(MEDIAINFO_MPEGTS_PESTIMESTAMP_YES)
1943         if (Complete_Stream->Streams[StreamID]->Parser)
1944         {
1945             #ifdef MEDIAINFO_MPEGTS_PESTIMESTAMP_YES
1946                 Complete_Stream->Streams[StreamID]->Searching_ParserTimeStamp_Start_Set(false); //No more searching start
1947                 if (Complete_Stream->Streams[StreamID]->Kind==complete_stream::stream::pes
1948                 && ((File_MpegPs*)Complete_Stream->Streams[StreamID]->Parser)->HasTimeStamps)
1949                     Complete_Stream->Streams[StreamID]->Searching_ParserTimeStamp_End_Set(true); //Searching only for a start found
1950             #endif //MEDIAINFO_MPEGTS_PESTIMESTAMP_YES
1951             if (File_GoTo==0)
1952                 Complete_Stream->Streams[StreamID]->Parser->Unsynch_Frame_Count=0;
1953             Complete_Stream->Streams[StreamID]->Parser->Open_Buffer_Unsynch();
1954         }
1955         #if MEDIAINFO_IBIUSAGE
1956             Complete_Stream->Streams[StreamID]->Ibi_SynchronizationOffset_BeginOfFrame=(int64u)-1;
1957             for (complete_stream::stream::table_ids::iterator TableID=Complete_Stream->Streams[StreamID]->Table_IDs.begin(); TableID!=Complete_Stream->Streams[StreamID]->Table_IDs.end(); ++TableID)
1958                 if (*TableID)
1959                     for (complete_stream::stream::table_id::table_id_extensions::iterator TableIdExtension=(*TableID)->Table_ID_Extensions.begin(); TableIdExtension!=(*TableID)->Table_ID_Extensions.end(); ++TableIdExtension)
1960                         TableIdExtension->second.version_number=(int8u)-1;
1961         #endif //MEDIAINFO_IBIUSAGE
1962     }
1963     Complete_Stream->Duration_End.clear();
1964 
1965     //Clearing durations
1966     Clear(Stream_General, 0, General_Duration);
1967     Clear(Stream_General, 0, General_Duration_End);
1968     for (size_t StreamPos=0; StreamPos<Count_Get(Stream_Menu); StreamPos++)
1969         Clear(Stream_Menu, StreamPos, Menu_Duration);
1970     #if MEDIAINFO_EVENTS
1971         if (Config->Config_PerPackage)
1972             Config->Config_PerPackage->Unsynch();
1973     #endif //MEDIAINFO_EVENTS
1974 }
1975 
1976 //---------------------------------------------------------------------------
Read_Buffer_Continue()1977 void File_MpegTs::Read_Buffer_Continue()
1978 {
1979     if (!IsSub)
1980     {
1981         if (Config->ParseSpeed>=1.0)
1982             Config->State_Set(((float)Buffer_TotalBytes)/File_Size);
1983         else if (Buffer_TotalBytes>MpegTs_JumpTo_Begin+MpegTs_JumpTo_End)
1984             Config->State_Set((float)0.99); //Nearly the end
1985         else
1986             Config->State_Set(((float)Buffer_TotalBytes)/(MpegTs_JumpTo_Begin+MpegTs_JumpTo_End));
1987     }
1988 
1989     #if MEDIAINFO_DEMUX
1990         if (Complete_Stream && pid<0x2000 && Complete_Stream->Streams[pid]->Kind==complete_stream::stream::pes && Complete_Stream->Streams[pid]->Parser && ((File_MpegPs*)Complete_Stream->Streams[pid]->Parser)->Demux_StreamIsBeingParsed_type!=(int8u)-1)
1991         {
1992             Open_Buffer_Continue(Complete_Stream->Streams[pid]->Parser, Buffer, 0, false);
1993             PES_Parse_Finish();
1994         }
1995     #endif //MEDIAINFO_DEMUX
1996 }
1997 
1998 //---------------------------------------------------------------------------
Read_Buffer_AfterParsing()1999 void File_MpegTs::Read_Buffer_AfterParsing()
2000 {
2001     if (Complete_Stream==NULL)
2002         return; //No synchronization yet
2003 
2004     //Stop parsing if sream is not coherent
2005     if (!Status[IsAccepted] && Buffer_TotalBytes-Buffer_TotalBytes_FirstSynched>=MpegTs_JumpTo_Begin/4)
2006     {
2007         Reject();
2008         return;
2009     }
2010 
2011     if (!Status[IsFilled])
2012     {
2013         //Test if parsing of headers is OK
2014         if ((Complete_Stream->Streams_NotParsedCount==0 && (NoPatPmt || (Complete_Stream->transport_stream_id_IsValid && Complete_Stream->Transport_Streams[Complete_Stream->transport_stream_id].Programs_NotParsedCount==0)))
2015          || (Buffer_TotalBytes-Buffer_TotalBytes_FirstSynched>=MpegTs_JumpTo_Begin && Config->ParseSpeed<0.8)
2016          || File_Offset+Buffer_Size==File_Size)
2017         {
2018             //Filling
2019             for (std::set<int16u>::iterator StreamID=Complete_Stream->PES_PIDs.begin(); StreamID!=Complete_Stream->PES_PIDs.end(); ++StreamID)
2020             {
2021                 if (Complete_Stream->Streams[*StreamID]->Parser)
2022                 {
2023                     Fill(Complete_Stream->Streams[*StreamID]->Parser);
2024 
2025                     Complete_Stream->Streams[*StreamID]->Parser->Status[IsUpdated]=false;
2026                     Complete_Stream->Streams[*StreamID]->IsUpdated_Info=true;
2027                 }
2028 
2029                 for (size_t Pos=0; Pos<Complete_Stream->Streams[*StreamID]->program_numbers.size(); Pos++)
2030                     Complete_Stream->Transport_Streams[Complete_Stream->transport_stream_id].Programs[Complete_Stream->Streams[*StreamID]->program_numbers[Pos]].Update_Needed_IsRegistered=true;
2031             }
2032             Complete_Stream->Streams_NotParsedCount=0;
2033             Fill();
2034 
2035             //Deactivating
2036             if (Config->File_StopSubStreamAfterFilled_Get())
2037                 for (std::set<int16u>::iterator StreamID=Complete_Stream->PES_PIDs.begin(); StreamID!=Complete_Stream->PES_PIDs.end(); ++StreamID)
2038                 {
2039                     Complete_Stream->Streams[*StreamID]->Searching_Payload_Start_Set(false);
2040                     Complete_Stream->Streams[*StreamID]->Searching_Payload_Continue_Set(false);
2041                 }
2042 
2043             //Status
2044             Status[IsUpdated]=true;
2045             Status[User_19]=true;
2046 
2047             //
2048             if (!(Buffer_TotalBytes-Buffer_TotalBytes_FirstSynched>=MpegTs_JumpTo_Begin && Config->ParseSpeed<0.8))
2049             {
2050                 MpegTs_JumpTo_Begin=File_Offset+Buffer_Offset-Buffer_TotalBytes_FirstSynched;
2051                 MpegTs_JumpTo_End=MpegTs_JumpTo_Begin;
2052 
2053                 //Avoid too short duration of the end. e.g. with quick pass, MpegTs_JumpTo_End may have content only for 2 frames which is not enough for catching an I-frame at the end of the file. Forcing to 2 seconds
2054                 if (Config->ParseSpeed < 0.5)
2055                 {
2056                     complete_stream::streams::iterator It_End=Complete_Stream->Streams.end();
2057                     for (complete_stream::streams::iterator It=Complete_Stream->Streams.begin(); It!=It_End; ++It)
2058                     {
2059                         complete_stream::stream* &Stream=*It;
2060 
2061                         if (Stream && Stream->Kind==complete_stream::stream::pes && Stream->TimeStamp_Start!=(int64u)-1 && Stream->TimeStamp_End!=(int64u)-1 && Stream->TimeStamp_Start!=Stream->TimeStamp_End)
2062                         {
2063                             int64u Duration=Stream->TimeStamp_End-Stream->TimeStamp_Start;
2064                             if (Duration<27000000*2) // 2 seconds
2065                             {
2066                                 int64u Ratio = 0;
2067                                 if (Duration)
2068                                     Ratio = (27000000 * 2) / Duration;
2069                                 MpegTs_JumpTo_End*=Ratio;
2070                                 if (MpegTs_JumpTo_End>MediaInfoLib::Config.MpegTs_MaximumOffset_Get()/4)
2071                                     MpegTs_JumpTo_End=MediaInfoLib::Config.MpegTs_MaximumOffset_Get()/4;
2072                                 break; //Using the first PES found
2073                             }
2074                         }
2075                     }
2076                 }
2077 
2078                 if (MpegTs_JumpTo_Begin+MpegTs_JumpTo_End>=File_Size)
2079                 {
2080                     if (MpegTs_JumpTo_Begin+MpegTs_JumpTo_End>File_Size)
2081                     {
2082                         MpegTs_JumpTo_Begin=File_Size;
2083                         MpegTs_JumpTo_End=0;
2084                     }
2085                     else
2086                         MpegTs_JumpTo_Begin=File_Size-MpegTs_JumpTo_End;
2087                 }
2088             }
2089 
2090             //Jumping
2091             if (Config->ParseSpeed<1.0 && Config->File_IsSeekable_Get()
2092             #if MEDIAINFO_ADVANCED
2093              && (!Config->File_IgnoreSequenceFileSize_Get() || Config->File_Names_Pos!=Config->File_Names.size()) // TODO: temporary disabling theses options for MPEG-TS (see above), because it does not work as expected
2094             #endif //MEDIAINFO_ADVANCED
2095              && MpegTs_ScanUpTo == (int64u)-1
2096              && File_Offset+Buffer_Size<File_Size-MpegTs_JumpTo_End && MpegTs_JumpTo_End)
2097             {
2098                 #if !defined(MEDIAINFO_MPEGTS_PCR_YES) && !defined(MEDIAINFO_MPEGTS_PESTIMESTAMP_YES)
2099                     GoToFromEnd(47); //TODO: Should be changed later (when Finalize stuff will be split)
2100                 #else //!defined(MEDIAINFO_MPEGTS_PCR_YES) && !defined(MEDIAINFO_MPEGTS_PESTIMESTAMP_YES)
2101                     #if defined(MEDIAINFO_EIA608_YES) || defined(MEDIAINFO_EIA708_YES)
2102                         if (File_Offset+Buffer_Size<File_Size/2-MpegTs_JumpTo_Begin && File_Size/2+MpegTs_JumpTo_Begin<File_Size-MpegTs_JumpTo_End && ((Config->File_DtvccTransport_Stream_IsPresent && !Config->File_DtvccTransport_Descriptor_IsPresent)
2103                         #if defined(MEDIAINFO_EIA608_YES)
2104                             || Config->File_Scte20_IsPresent
2105                         #endif //defined(MEDIAINFO_EIA608_YES)
2106                             ))
2107                         {
2108                             MpegTs_ScanUpTo=File_Size/2+MpegTs_JumpTo_Begin;
2109                             GoTo(File_Size/2-MpegTs_JumpTo_Begin);
2110                         }
2111                         else
2112                     #endif //defined(MEDIAINFO_EIA608_YES) || defined(MEDIAINFO_EIA708_YES)
2113                         GoToFromEnd(MpegTs_JumpTo_End);
2114                     Searching_TimeStamp_Start=false;
2115                 #endif //!defined(MEDIAINFO_MPEGTS_PCR_YES) && !defined(MEDIAINFO_MPEGTS_PESTIMESTAMP_YES)
2116                 Open_Buffer_Unsynch();
2117             }
2118         }
2119     }
2120 
2121     if (MpegTs_ScanUpTo != (int64u)-1 && File_Offset+Buffer_Size>=MpegTs_ScanUpTo)
2122     {
2123         MpegTs_ScanUpTo = (int64u)-1;
2124         GoToFromEnd(MpegTs_JumpTo_End);
2125         Open_Buffer_Unsynch();
2126     }
2127 }
2128 
2129 //---------------------------------------------------------------------------
2130 #if MEDIAINFO_SEEK
Read_Buffer_Seek(size_t Method,int64u Value,int64u ID)2131 size_t File_MpegTs::Read_Buffer_Seek (size_t Method, int64u Value, int64u ID)
2132 {
2133     //Reset
2134     Seek_Value=(int64u)-1;
2135     Seek_ID=(int64u)-1;
2136     InfiniteLoop_Detect=0;
2137     #if MEDIAINFO_DEMUX
2138         Config->Demux_IsSeeking=false;
2139     #endif //MEDIAINFO_DEMUX
2140 
2141     //Init
2142     if (!Duration_Detected)
2143     {
2144         //External IBI
2145         #if MEDIAINFO_IBIUSAGE
2146             std::string IbiFile=Config->Ibi_Get();
2147             if (!IbiFile.empty())
2148             {
2149                 Ibi.Streams.clear(); //TODO: support IBI data from different inputs
2150 
2151                 File_Ibi MI;
2152                 Open_Buffer_Init(&MI, IbiFile.size());
2153                 MI.Ibi=&Ibi;
2154                 MI.Open_Buffer_Continue((const int8u*)IbiFile.c_str(), IbiFile.size());
2155             }
2156             //Creating base IBI from a quick analysis of the file
2157             else
2158             {
2159                 MediaInfo_Internal MI;
2160                 MI.Option(__T("File_KeepInfo"), __T("1"));
2161                 Ztring ParseSpeed_Save=MI.Option(__T("ParseSpeed_Get"), __T(""));
2162                 Ztring Demux_Save=MI.Option(__T("Demux_Get"), __T(""));
2163                 MI.Option(__T("ParseSpeed"), __T("0"));
2164                 MI.Option(__T("Demux"), Ztring());
2165                 Config->File_Names.Separator_Set(0, ",");
2166                 Ztring File_Names=Config->File_Names.Read();
2167                 MI.Option(__T("File_FileNameFormat"), __T("CSV"));
2168                 size_t MiOpenResult=MI.Open(File_Names);
2169                 MI.Option(__T("ParseSpeed"), ParseSpeed_Save); //This is a global value, need to reset it. TODO: local value
2170                 MI.Option(__T("Demux"), Demux_Save); //This is a global value, need to reset it. TODO: local value
2171                 if (!MiOpenResult)
2172                     return (size_t)-1;
2173                 for (ibi::streams::iterator IbiStream_Temp=((File_MpegTs*)MI.Info)->Ibi.Streams.begin(); IbiStream_Temp!=((File_MpegTs*)MI.Info)->Ibi.Streams.end(); ++IbiStream_Temp)
2174                 {
2175                     if (Ibi.Streams[IbiStream_Temp->first]==NULL)
2176                         Ibi.Streams[IbiStream_Temp->first]=new ibi::stream(*IbiStream_Temp->second);
2177                     Ibi.Streams[IbiStream_Temp->first]->Unsynch();
2178                     for (size_t Pos=0; Pos<IbiStream_Temp->second->Infos.size(); Pos++)
2179                     {
2180                         Ibi.Streams[IbiStream_Temp->first]->Add(IbiStream_Temp->second->Infos[Pos]);
2181                         if (!IbiStream_Temp->second->Infos[Pos].IsContinuous)
2182                             Ibi.Streams[IbiStream_Temp->first]->Unsynch();
2183                     }
2184                     Ibi.Streams[IbiStream_Temp->first]->Unsynch();
2185                 }
2186                 if (Ibi.Streams.empty())
2187                     return 4; //Problem during IBI file parsing
2188             }
2189         #endif //#if MEDIAINFO_IBIUSAGE
2190 
2191         Duration_Detected=true;
2192     }
2193 
2194     //Parsing
2195     switch (Method)
2196     {
2197         case 0  :
2198                     GoTo(Value);
2199                     Open_Buffer_Unsynch();
2200                     return 1;
2201         case 1  :
2202                     GoTo(File_Size*Value/10000);
2203                     Open_Buffer_Unsynch();
2204                     return 1;
2205         case 2  :   //Timestamp
2206                     #if MEDIAINFO_IBIUSAGE
2207                     {
2208                     ibi::streams::iterator IbiStream_Temp;
2209                     if (ID==(int64u)-1)
2210                         IbiStream_Temp=Ibi.Streams.begin();
2211                     else
2212                         IbiStream_Temp=Ibi.Streams.find(ID);
2213                     if (IbiStream_Temp==Ibi.Streams.end() || IbiStream_Temp->second->Infos.empty())
2214                     {
2215                         for (IbiStream_Temp=Ibi.Streams.begin(); IbiStream_Temp!=Ibi.Streams.end(); ++IbiStream_Temp)
2216                             if (!IbiStream_Temp->second->Infos.empty())
2217                                 break;
2218 
2219                         if (IbiStream_Temp==Ibi.Streams.end())
2220                             return 5; //Invalid ID
2221                     }
2222 
2223                     if (!(IbiStream_Temp->second->DtsFrequencyNumerator==1000000000 && IbiStream_Temp->second->DtsFrequencyDenominator==1))
2224                     {
2225                         float64 ValueF=(float64)Value;
2226                         ValueF/=1000000000; //Value is in ns
2227                         ValueF/=IbiStream_Temp->second->DtsFrequencyDenominator;
2228                         ValueF*=IbiStream_Temp->second->DtsFrequencyNumerator;
2229                         Value=float64_int64s(ValueF);
2230                     }
2231 
2232                     for (size_t Pos=0; Pos<IbiStream_Temp->second->Infos.size(); Pos++)
2233                     {
2234                         if (Value<=IbiStream_Temp->second->Infos[Pos].Dts || Pos+1==IbiStream_Temp->second->Infos.size())
2235                         {
2236                             if (Value<IbiStream_Temp->second->Infos[Pos].Dts && Pos)
2237                                 Pos--;
2238 
2239                             //Checking continuity of Ibi
2240                             if (!IbiStream_Temp->second->Infos[Pos].IsContinuous && Pos+1<IbiStream_Temp->second->Infos.size() && InfiniteLoop_Detect<8) //With infinite loop detect
2241                             {
2242                                 InfiniteLoop_Detect++;
2243                                 Config->Demux_IsSeeking=true;
2244                                 Seek_Value=Value;
2245                                 Seek_Value_Maximal=IbiStream_Temp->second->Infos[Pos+1].StreamOffset;
2246                                 Seek_ID=IbiStream_Temp->first;
2247                                 GoTo((IbiStream_Temp->second->Infos[Pos].StreamOffset+IbiStream_Temp->second->Infos[Pos+1].StreamOffset)/2);
2248                                 Open_Buffer_Unsynch();
2249 
2250                                 return 1;
2251                             }
2252 
2253                             InfiniteLoop_Detect=0;
2254                             Config->Demux_IsSeeking=false;
2255                             if (Complete_Stream && Complete_Stream->Streams[(size_t)IbiStream_Temp->first] && Complete_Stream->Streams[(size_t)IbiStream_Temp->first]->Parser)
2256                                 Complete_Stream->Streams[(size_t)IbiStream_Temp->first]->Parser->Unsynch_Frame_Count=IbiStream_Temp->second->Infos[Pos].FrameNumber;
2257                             else
2258                                 Unsynch_Frame_Counts[(int16u)IbiStream_Temp->first]=IbiStream_Temp->second->Infos[Pos].FrameNumber;
2259 
2260                             GoTo(IbiStream_Temp->second->Infos[Pos].StreamOffset);
2261                             Open_Buffer_Unsynch();
2262 
2263                             return 1;
2264                         }
2265                     }
2266 
2267                     return 2; //Invalid value
2268                     }
2269                     #else //MEDIAINFO_IBIUSAGE
2270                     return (size_t)-2; //Not supported / IBI disabled
2271                     #endif //MEDIAINFO_IBIUSAGE
2272         case 3  :   //FrameNumber
2273                     #if MEDIAINFO_IBIUSAGE
2274                     {
2275                     ibi::streams::iterator IbiStream_Temp;
2276                     if (ID==(int64u)-1)
2277                         IbiStream_Temp=Ibi.Streams.begin();
2278                     else
2279                         IbiStream_Temp=Ibi.Streams.find(ID);
2280                     if (IbiStream_Temp==Ibi.Streams.end() || IbiStream_Temp->second->Infos.empty())
2281                     {
2282                         for (IbiStream_Temp=Ibi.Streams.begin(); IbiStream_Temp!=Ibi.Streams.end(); ++IbiStream_Temp)
2283                             if (!IbiStream_Temp->second->Infos.empty())
2284                                 break;
2285 
2286                         if (IbiStream_Temp==Ibi.Streams.end())
2287                             return 5; //Invalid ID
2288                     }
2289 
2290                     for (size_t Pos=0; Pos<IbiStream_Temp->second->Infos.size(); Pos++)
2291                     {
2292                         if (Value<=IbiStream_Temp->second->Infos[Pos].FrameNumber || Pos+1==IbiStream_Temp->second->Infos.size())
2293                         {
2294                             if (Value<IbiStream_Temp->second->Infos[Pos].FrameNumber && Pos)
2295                                 Pos--;
2296 
2297                             Config->Demux_IsSeeking=false;
2298                             if (Complete_Stream && Complete_Stream->Streams[(size_t)IbiStream_Temp->first] && Complete_Stream->Streams[(size_t)IbiStream_Temp->first]->Parser)
2299                                 Complete_Stream->Streams[(size_t)IbiStream_Temp->first]->Parser->Unsynch_Frame_Count=IbiStream_Temp->second->Infos[Pos].FrameNumber;
2300                             else
2301                                 Unsynch_Frame_Counts[(int16u)IbiStream_Temp->first]=IbiStream_Temp->second->Infos[Pos].FrameNumber;
2302 
2303                             GoTo(IbiStream_Temp->second->Infos[Pos].StreamOffset);
2304                             Open_Buffer_Unsynch();
2305 
2306                             return 1;
2307                         }
2308                     }
2309 
2310                     return 2; //Invalid value
2311                     }
2312                     #else //MEDIAINFO_IBIUSAGE
2313                     return (size_t)-2; //Not supported / IBI disabled
2314                     #endif //MEDIAINFO_IBIUSAGE
2315         default :   return (size_t)-1; //Not supported
2316     }
2317 }
2318 #endif //MEDIAINFO_SEEK
2319 
2320 //***************************************************************************
2321 // Buffer - File header
2322 //***************************************************************************
2323 
2324 //---------------------------------------------------------------------------
FileHeader_Begin()2325 bool File_MpegTs::FileHeader_Begin()
2326 {
2327     if (Buffer_Size<8)
2328         return false; //Wait for more data
2329 
2330     //False positives detection: detect some headers from other files, DV parser is not smart enough
2331     if (CC8(Buffer+Buffer_Offset)==0x444C472056312E30LL //DLG
2332      || CC4(Buffer)==0x52494646  //RIFF
2333      || CC4(Buffer+4)==0x66747970  //ftyp
2334      || CC4(Buffer+4)==0x66726565  //free
2335      || CC4(Buffer+4)==0x6D646174  //mdat
2336      || CC4(Buffer+4)==0x6D6F6F76  //moov
2337      || CC4(Buffer+4)==0x736B6970  //skip
2338      || CC4(Buffer+4)==0x77696465  //wide
2339      || CC4(Buffer)==0x060E2B34) //MXF begin
2340     {
2341         Reject("MPEG-TS");
2342         return true;
2343     }
2344 
2345     //Configuring
2346     #if defined(MEDIAINFO_BDAV_YES) || defined(MEDIAINFO_TSP_YES)
2347         TS_Size=188
2348         #if defined(MEDIAINFO_BDAV_YES)
2349             +BDAV_Size
2350         #endif
2351         #if defined(MEDIAINFO_TSP_YES)
2352             +TSP_Size
2353         #endif
2354         ;
2355     #endif
2356 
2357     //Configuration
2358     Option_Manage();
2359 
2360     return true;
2361 }
2362 
2363 //***************************************************************************
2364 // Buffer - Per element
2365 //***************************************************************************
2366 
2367 //---------------------------------------------------------------------------
Header_Parse()2368 void File_MpegTs::Header_Parse()
2369 {
2370     #if MEDIAINFO_TRACE
2371     if (Trace_Activated)
2372     {
2373         //Parsing
2374         bool  adaptation, payload;
2375         if (BDAV_Size)
2376             Skip_B4(                                                "BDAV"); //BDAV supplement
2377         Skip_B1(                                                    "sync_byte");
2378         BS_Begin();
2379         Skip_SB(                                                    "transport_error_indicator");
2380         Get_SB (    payload_unit_start_indicator,                   "payload_unit_start_indicator");
2381         Skip_SB(                                                    "transport_priority");
2382         Get_S2 (13, pid,                                            "pid");
2383         Get_S1 ( 2, transport_scrambling_control,                   "transport_scrambling_control");
2384         Get_SB (    adaptation,                                     "adaptation_field_control (adaptation)");
2385         Get_SB (    payload,                                        "adaptation_field_control (payload)");
2386         Skip_S1( 4,                                                 "continuity_counter");
2387         BS_End();
2388 
2389         //Info
2390         /* Trace: used to display program number(s)
2391         if (!Complete_Stream->Streams[pid]->program_numbers.empty())
2392         {
2393             Ztring Program_Numbers;
2394             for (size_t Pos=0; Pos<Complete_Stream->Streams[pid]->program_numbers.size(); Pos++)
2395                 Program_Numbers+=Ztring::ToZtring_From_CC2(Complete_Stream->Streams[pid]->program_numbers[Pos])+__T('/');
2396             if (!Program_Numbers.empty())
2397                 Program_Numbers.resize(Program_Numbers.size()-1);
2398             Data_Info(Program_Numbers);
2399         }
2400         else
2401             Data_Info("    ");
2402         */
2403         Data_Info(Complete_Stream->Streams[pid]->Element_Info1);
2404 
2405         //Adaptation
2406         if (adaptation)
2407             Header_Parse_AdaptationField();
2408         else
2409         {
2410         }
2411 
2412         //Data
2413         if (payload)
2414         {
2415             //Encryption
2416             if (transport_scrambling_control>0)
2417                 Complete_Stream->Streams[pid]->Scrambled_Count++;
2418         }
2419         else if (Element_Offset+TSP_Size<TS_Size)
2420             Skip_XX(TS_Size-Element_Offset-TSP_Size,            "Junk");
2421 
2422         //Filling
2423         Header_Fill_Code(pid, __T("0x")+Ztring().From_CC2(pid));
2424         Header_Fill_Size(TS_Size);
2425 
2426         Header_Parse_Events();
2427     }
2428     else
2429     {
2430     #endif //MEDIAINFO_TRACE
2431         //Parsing
2432                payload_unit_start_indicator=(Buffer[Buffer_Offset+BDAV_Size+1]&0x40)!=0;
2433                transport_scrambling_control= Buffer[Buffer_Offset+BDAV_Size+3]&0xC0;
2434         bool   adaptation=                  (Buffer[Buffer_Offset+BDAV_Size+3]&0x20)!=0;
2435         bool   payload=                     (Buffer[Buffer_Offset+BDAV_Size+3]&0x10)!=0;
2436         Element_Offset+=BDAV_Size+4;
2437 
2438         //Adaptation
2439         if (adaptation)
2440             Header_Parse_AdaptationField();
2441         else
2442         {
2443         }
2444 
2445         //Data
2446         if (payload)
2447         {
2448             //Encryption
2449             if (transport_scrambling_control>0)
2450                 Complete_Stream->Streams[pid]->Scrambled_Count++;
2451         }
2452 
2453         //Filling
2454         /*Element[1].Next=File_Offset+Buffer_Offset+TS_Size;  //*/Header_Fill_Size(TS_Size);
2455         //Element[1].IsComplete=true;                         //Header_Fill_Size(TS_Size);
2456 
2457         Header_Parse_Events();
2458     #if MEDIAINFO_TRACE
2459     }
2460     #endif //MEDIAINFO_TRACE
2461 }
2462 
2463 //---------------------------------------------------------------------------
Header_Parse_AdaptationField()2464 void File_MpegTs::Header_Parse_AdaptationField()
2465 {
2466     #if MEDIAINFO_TRACE
2467     if (Trace_Activated)
2468     {
2469         int64u Element_Pos_Save=Element_Offset;
2470         Element_Begin1("adaptation_field");
2471         int8u adaptation_field_length;
2472         Get_B1 (adaptation_field_length,                            "adaptation_field_length");
2473         if (adaptation_field_length>188-4-1) //TS size - header - adaptation_field_length
2474         {
2475             adaptation_field_length=188-4-1;
2476             Skip_XX(188-4-1,                                        "stuffing_bytes");
2477         }
2478         else if (adaptation_field_length>0)
2479         {
2480             bool discontinuity_indicator, PCR_flag, OPCR_flag, splicing_point_flag, transport_private_data_flag, adaptation_field_extension_flag;
2481             BS_Begin();
2482             Get_SB (    discontinuity_indicator,                    "discontinuity_indicator");
2483             Skip_SB(                                                "random_access_indicator");
2484             Skip_SB(                                                "elementary_stream_priority_indicator");
2485             Get_SB (    PCR_flag,                                   "PCR_flag");
2486             Get_SB (    OPCR_flag,                                  "OPCR_flag");
2487             Get_SB (    splicing_point_flag,                        "splicing_point_flag");
2488             Get_SB (    transport_private_data_flag,                "transport_private_data_flag");
2489             Get_SB (    adaptation_field_extension_flag,            "adaptation_field_extension_flag");
2490             BS_End();
2491             if (PCR_flag)
2492             {
2493                 #ifdef MEDIAINFO_MPEGTS_PCR_YES
2494                     BS_Begin();
2495                     int64u program_clock_reference_base;
2496                     int16u program_clock_reference_extension;
2497                     Get_S8 (33, program_clock_reference_base,           "program_clock_reference_base"); Param_Info_From_Milliseconds(program_clock_reference_base/90);
2498                     Data_Info_From_Milliseconds(program_clock_reference_base/90);
2499                     Skip_S1( 6,                                         "reserved");
2500                     Get_S2 ( 9, program_clock_reference_extension,      "program_clock_reference_extension");
2501                     int64u program_clock_reference=program_clock_reference_base*300+program_clock_reference_extension;
2502                     Param_Info1(program_clock_reference);
2503                     BS_End();
2504                     if (Complete_Stream->Streams[pid]->Searching_TimeStamp_End
2505                     #ifdef MEDIAINFO_MPEGTS_PESTIMESTAMP_YES
2506                      && (!Complete_Stream->Streams[pid]->Searching_ParserTimeStamp_End
2507                       || Complete_Stream->Streams[pid]->IsPCR) //If PCR, we always want it.
2508                     #endif //MEDIAINFO_MPEGTS_PESTIMESTAMP_YES
2509                      )
2510                     {
2511                         Header_Parse_Events_Duration_Helper(program_clock_reference,discontinuity_indicator);
2512                     }
2513                     if (Complete_Stream->Streams[pid]->Searching_TimeStamp_Start)
2514                     {
2515                         //This is the first PCR
2516                         Complete_Stream->Streams[pid]->TimeStamp_Start=program_clock_reference;
2517                         Complete_Stream->Streams[pid]->TimeStamp_Start_Offset=File_Offset+Buffer_Offset;
2518                         Complete_Stream->Streams[pid]->TimeStamp_End=program_clock_reference;
2519                         Complete_Stream->Streams[pid]->TimeStamp_End_IsUpdated=true;
2520                         Complete_Stream->Streams[pid]->TimeStamp_End_Offset=File_Offset+Buffer_Offset;
2521                         Complete_Stream->Streams[pid]->Searching_TimeStamp_Start_Set(false);
2522                         Complete_Stream->Streams[pid]->Searching_TimeStamp_End_Set(true);
2523                         Complete_Stream->Streams_With_StartTimeStampCount++;
2524                         {
2525                             Status[IsUpdated]=true;
2526                             Status[User_16]=true;
2527                         }
2528                     }
2529 
2530                     //Test if we can find the TS bitrate
2531                     if (!Complete_Stream->Streams[pid]->EndTimeStampMoreThanxSeconds && Complete_Stream->Streams[pid]->TimeStamp_Start!=(int64u)-1
2532                     && (File_Offset+Buffer_Offset-Buffer_TotalBytes_FirstSynched)*2<File_Size)
2533                     {
2534                         if (program_clock_reference<Complete_Stream->Streams[pid]->TimeStamp_Start)
2535                         {
2536                             if (Complete_Stream->Streams[pid]->TimeStamp_Start-program_clock_reference<10LL*90000*300) //Testing if difference is less that 10 seconds (value arbitrary choosen)
2537                                 Complete_Stream->Streams[pid]->TimeStamp_Start=program_clock_reference; //Looks like we have a small jump in the past in a buggy file, accepting it.
2538                             else
2539                                 program_clock_reference+=0x200000000LL*300; //33 bits, cyclic
2540                         }
2541                         if ((program_clock_reference-Complete_Stream->Streams[pid]->TimeStamp_Start)>Begin_MaxDuration)
2542                         {
2543                             Complete_Stream->Streams[pid]->EndTimeStampMoreThanxSeconds=true;
2544                             Complete_Stream->Streams_With_EndTimeStampMoreThanxSecondsCount++;
2545                             if (Complete_Stream->Streams_NotParsedCount
2546                              && Complete_Stream->Streams_With_StartTimeStampCount>0
2547                              && Complete_Stream->Streams_With_StartTimeStampCount==Complete_Stream->Streams_With_EndTimeStampMoreThanxSecondsCount)
2548                             {
2549                                 //We are already parsing 16 seconds (for all PCRs), we don't hope to have more info
2550                                 MpegTs_JumpTo_Begin=File_Offset+Buffer_Offset-Buffer_TotalBytes_FirstSynched;
2551                                 MpegTs_JumpTo_End=MpegTs_JumpTo_Begin;
2552                                 if (MpegTs_JumpTo_Begin+MpegTs_JumpTo_End>=File_Size)
2553                                 {
2554                                     if (MpegTs_JumpTo_Begin+MpegTs_JumpTo_End>File_Size)
2555                                     {
2556                                         MpegTs_JumpTo_Begin=File_Size;
2557                                         MpegTs_JumpTo_End=0;
2558                                     }
2559                                     else
2560                                         MpegTs_JumpTo_Begin=File_Size-MpegTs_JumpTo_End;
2561                                 }
2562                             }
2563                         }
2564                     }
2565                 #else //MEDIAINFO_MPEGTS_PCR_YES
2566                     Skip_B6(                                        "program_clock_reference");
2567                 #endif //MEDIAINFO_MPEGTS_PCR_YES
2568             }
2569             if (OPCR_flag)
2570             {
2571                 BS_Begin();
2572                 Skip_S8(33,                                         "original_program_clock_reference_base");
2573                 Skip_S1( 6,                                         "reserved");
2574                 Skip_S2( 9,                                         "original_program_clock_reference_extension");
2575                 BS_End();
2576             }
2577             if (splicing_point_flag)
2578             {
2579                 Skip_B1(                                            "splice_countdown");
2580             }
2581             if (transport_private_data_flag)
2582             {
2583                 int8u transport_private_data_length;
2584                 Get_B1 (transport_private_data_length,              "transport_private_data_length");
2585                 if (Element_Offset+transport_private_data_length<=Element_Pos_Save+1+adaptation_field_length)
2586                     transport_private_data(transport_private_data_length);
2587                 else
2588                     Skip_XX(Element_Pos_Save+1+adaptation_field_length-Element_Offset, "problem");
2589             }
2590             if (adaptation_field_extension_flag)
2591             {
2592                 int8u adaptation_field_extension_length;
2593                 Get_B1 (adaptation_field_extension_length,          "adaptation_field_extension_length");
2594                 if (Element_Offset+adaptation_field_extension_length<=Element_Pos_Save+1+adaptation_field_length)
2595                 {
2596                     Element_Begin1("adaptation_field_extension");
2597                     int64u End=Element_Offset+adaptation_field_extension_length;
2598                     bool ltw_flag, piecewise_rate_flag, seamless_splice_flag;
2599                     BS_Begin();
2600                     Get_SB (    ltw_flag,                                   "ltw_flag");
2601                     Get_SB (    piecewise_rate_flag,                        "piecewise_rate_flag");
2602                     Get_SB (    seamless_splice_flag,                       "seamless_splice_flag");
2603                     Skip_S1( 5,                                             "reserved");
2604                     if (ltw_flag)
2605                     {
2606                         Skip_SB(                                            "ltw_valid_flag");
2607                         Skip_S2(15,                                         "ltw_offset");
2608                     }
2609                     if (piecewise_rate_flag)
2610                     {
2611                         Skip_S1( 2,                                         "reserved");
2612                         Skip_S3(22,                                         "piecewise_rate");
2613                     }
2614                     if (seamless_splice_flag)
2615                     {
2616                         Skip_S1( 4,                                         "splice_type");
2617                         int16u DTS_29, DTS_14;
2618                         int8u  DTS_32;
2619                         Element_Begin1("DTS");
2620                         Get_S1 ( 3, DTS_32,                                 "DTS_32");
2621                         Mark_1();
2622                         Get_S2 (15, DTS_29,                                 "DTS_29");
2623                         Mark_1();
2624                         Get_S2 (15, DTS_14,                                 "DTS_14");
2625                         Mark_1();
2626 
2627                         //Filling
2628                         int64u DTS;
2629                         DTS=(((int64u)DTS_32)<<30)
2630                           | (((int64u)DTS_29)<<15)
2631                           | (((int64u)DTS_14));
2632                         Element_Info_From_Milliseconds(DTS/90);
2633                         Element_End0();
2634                     }
2635                     BS_End();
2636                     if (Element_Offset<End)
2637                         Skip_XX(End-Element_Offset,                         "reserved");
2638                     Element_End0();
2639                 }
2640                 else
2641                     Skip_XX(Element_Pos_Save+1+adaptation_field_length-Element_Offset, "problem");
2642             }
2643         }
2644 
2645         if (Element_Offset<Element_Pos_Save+1+adaptation_field_length)
2646             Skip_XX(Element_Pos_Save+1+adaptation_field_length-Element_Offset, "stuffing_bytes");
2647         Element_End0();
2648     }
2649     else
2650     {
2651     #endif //MEDIAINFO_TRACE
2652         int8u adaptation_field_length=Buffer[Buffer_Offset+BDAV_Size+4];
2653         #ifdef MEDIAINFO_MPEGTS_PCR_YES
2654             if (adaptation_field_length>188-4-1) //TS size - header - adaptation_field_length
2655                 adaptation_field_length=188-4-1;
2656             else if (adaptation_field_length)
2657             {
2658                 bool discontinuity_indicator=(Buffer[Buffer_Offset+BDAV_Size+5]&0x80)!=0;
2659                 bool PCR_flag=(Buffer[Buffer_Offset+BDAV_Size+5]&0x10)!=0;
2660                 bool OPCR_flag=(Buffer[Buffer_Offset+BDAV_Size+5]&0x08)!=0;
2661                 bool splicing_point_flag=(Buffer[Buffer_Offset+BDAV_Size+5]&0x04)!=0;
2662                 bool transport_private_data_flag=(Buffer[Buffer_Offset+BDAV_Size+5]&0x02)!=0;
2663                 if (PCR_flag)
2664                 {
2665                     int64u program_clock_reference=(  (((int64u)Buffer[Buffer_Offset+BDAV_Size+6])<<25)
2666                                                     | (((int64u)Buffer[Buffer_Offset+BDAV_Size+7])<<17)
2667                                                     | (((int64u)Buffer[Buffer_Offset+BDAV_Size+8])<< 9)
2668                                                     | (((int64u)Buffer[Buffer_Offset+BDAV_Size+9])<< 1)
2669                                                     | (((int64u)Buffer[Buffer_Offset+BDAV_Size+10])>>7));
2670                     program_clock_reference*=300;
2671                     program_clock_reference+=(  (((int64u)Buffer[Buffer_Offset+BDAV_Size+10]&0x01)<<8)
2672                                               | (((int64u)Buffer[Buffer_Offset+BDAV_Size+11])   ));
2673                     if (Complete_Stream->Streams[pid]->Searching_TimeStamp_End
2674                     #ifdef MEDIAINFO_MPEGTS_PESTIMESTAMP_YES
2675                      && (!Complete_Stream->Streams[pid]->Searching_ParserTimeStamp_End
2676                       || Complete_Stream->Streams[pid]->IsPCR) //If PCR, we always want it.
2677                     #endif //MEDIAINFO_MPEGTS_PESTIMESTAMP_YES
2678                      )
2679                     {
2680                         Header_Parse_Events_Duration(program_clock_reference);
2681                         if (program_clock_reference!=Complete_Stream->Streams[pid]->TimeStamp_End) //Some PCRs are buggy (low precision), using the first stream offset in the case of duplicate PCR value
2682                         {
2683                             if (Complete_Stream->Streams[pid]->TimeStamp_End_Offset!=(int64u)-1)
2684                             {
2685                                 if (program_clock_reference+0x12c00000000LL<Complete_Stream->Streams[pid]->TimeStamp_End)
2686                                     program_clock_reference+=0x25800000000LL; //33 bits and *300
2687                                 if (!discontinuity_indicator && program_clock_reference>Complete_Stream->Streams[pid]->TimeStamp_End && program_clock_reference<Complete_Stream->Streams[pid]->TimeStamp_End+10*27000000) //Not before, not after 10 seconds, else there is a problem
2688                                 {
2689                                     float64 Duration_InstantaneousBitRate_Min=(float64)(program_clock_reference-Complete_Stream->Streams[pid]->TimeStamp_End-(Config_VbrDetection_Delta?0:810));
2690                                     float64 Duration_InstantaneousBitRate_Max=(float64)(program_clock_reference-Complete_Stream->Streams[pid]->TimeStamp_End+(Config_VbrDetection_Delta?0:810));
2691                                     float64 Bytes_InstantaneousBitRate=(float64)(File_Offset+Buffer_Offset-Complete_Stream->Streams[pid]->TimeStamp_End_Offset);
2692                                     float64 TimeStamp_InstantaneousBitRate_Current_Min=Bytes_InstantaneousBitRate*8/Duration_InstantaneousBitRate_Max*27000000*(1-Config_VbrDetection_Delta);
2693                                     float64 TimeStamp_InstantaneousBitRate_Current_Max=Bytes_InstantaneousBitRate*8/Duration_InstantaneousBitRate_Min*27000000*(1+Config_VbrDetection_Delta);
2694                                     if (Complete_Stream->Streams[pid]->TimeStamp_InstantaneousBitRate_Current_Min)
2695                                     {
2696                                         if (TimeStamp_InstantaneousBitRate_Current_Max<Complete_Stream->Streams[pid]->TimeStamp_InstantaneousBitRate_Current_Min || TimeStamp_InstantaneousBitRate_Current_Min>Complete_Stream->Streams[pid]->TimeStamp_InstantaneousBitRate_Current_Max)
2697                                         {
2698                                             Complete_Stream->Streams[pid]->TimeStamp_InstantaneousBitRate_BitRateMode_IsVbr++;
2699                                             #if MEDIAINFO_ADVANCED
2700                                                 if (Config_VbrDetection_GiveUp && Complete_Stream->Streams[pid]->TimeStamp_InstantaneousBitRate_BitRateMode_IsVbr>=Config_VbrDetection_Occurences)
2701                                                     Config->ParseSpeed=0;
2702                                             #endif // MEDIAINFO_ADVANCED
2703                                         }
2704                                         else
2705                                             Complete_Stream->Streams[pid]->TimeStamp_InstantaneousBitRate_BitRateMode_IsCbr++;
2706                                     }
2707                                     float64 Duration_Min=(float64)(program_clock_reference-Complete_Stream->Streams[pid]->TimeStamp_End-1);
2708                                     float64 Duration_Raw=(float64)(program_clock_reference-Complete_Stream->Streams[pid]->TimeStamp_End);
2709                                     float64 Duration_Max=(float64)(program_clock_reference-Complete_Stream->Streams[pid]->TimeStamp_End+1);
2710                                     float64 Bytes=(float64)(File_Offset+Buffer_Offset-Complete_Stream->Streams[pid]->TimeStamp_End_Offset);
2711                                     float64 InstantaneousBitRate_Min=Bytes*8/Duration_Max*27000000*(1-Config_VbrDetection_Delta);
2712                                     float64 InstantaneousBitRate_Raw=Bytes*8/Duration_Raw*27000000;
2713                                     float64 InstantaneousBitRate_Max=Bytes*8/Duration_Min*27000000*(1+Config_VbrDetection_Delta);
2714                                     Complete_Stream->Streams[pid]->TimeStamp_InstantaneousBitRate_Current_Min=InstantaneousBitRate_Min;
2715                                     Complete_Stream->Streams[pid]->TimeStamp_InstantaneousBitRate_Current_Raw=InstantaneousBitRate_Raw;
2716                                     Complete_Stream->Streams[pid]->TimeStamp_InstantaneousBitRate_Current_Max=InstantaneousBitRate_Max;
2717                                     #if MEDIAINFO_ADVANCED
2718                                         if (Complete_Stream->Streams[pid]->TimeStamp_InstantaneousBitRate_Min_Raw>InstantaneousBitRate_Raw)
2719                                             Complete_Stream->Streams[pid]->TimeStamp_InstantaneousBitRate_Min_Raw=InstantaneousBitRate_Raw;
2720                                         if (Complete_Stream->Streams[pid]->TimeStamp_InstantaneousBitRate_Max_Raw<InstantaneousBitRate_Raw)
2721                                             Complete_Stream->Streams[pid]->TimeStamp_InstantaneousBitRate_Max_Raw=InstantaneousBitRate_Raw;
2722                                         int64u Distance=program_clock_reference-Complete_Stream->Streams[pid]->TimeStamp_End;
2723                                         if (Complete_Stream->Streams[pid]->TimeStamp_Distance_Min>Distance)
2724                                             Complete_Stream->Streams[pid]->TimeStamp_Distance_Min=Distance;
2725                                         if (Complete_Stream->Streams[pid]->TimeStamp_Distance_Max<Distance)
2726                                             Complete_Stream->Streams[pid]->TimeStamp_Distance_Max=Distance;
2727                                         Complete_Stream->Streams[pid]->TimeStamp_Distance_Total+=Distance;
2728                                         Complete_Stream->Streams[pid]->TimeStamp_Distance_Count++;
2729                                     #endif // MEDIAINFO_ADVANCED
2730                                 }
2731                                 #if MEDIAINFO_ADVANCED
2732                                     else
2733                                     {
2734                                        if (!discontinuity_indicator)
2735                                             Complete_Stream->Streams[pid]->TimeStamp_HasProblems++;
2736                                        float64 Bytes=(float64)(File_Offset+Buffer_Offset-Complete_Stream->Streams[pid]->TimeStamp_End_Offset);
2737                                        int64u TimeToAdd;
2738                                        if (Complete_Stream->Streams[pid]->TimeStamp_InstantaneousBitRate_Current_Raw)
2739                                            TimeToAdd=float64_int64s(Bytes*8/Complete_Stream->Streams[pid]->TimeStamp_InstantaneousBitRate_Current_Raw*27000000);
2740                                        else
2741                                            TimeToAdd=0;
2742                                        Complete_Stream->Streams[pid]->TimeStamp_Intermediate.push_back(Complete_Stream->Streams[pid]->TimeStamp_End+TimeToAdd);
2743                                        Complete_Stream->Streams[pid]->TimeStamp_Intermediate.push_back(program_clock_reference);
2744                                     }
2745                                 #endif // MEDIAINFO_ADVANCED
2746                             }
2747                             Complete_Stream->Streams[pid]->TimeStamp_End=program_clock_reference;
2748                             Complete_Stream->Streams[pid]->TimeStamp_End_IsUpdated=true;
2749                             Complete_Stream->Streams[pid]->TimeStamp_End_Offset=File_Offset+Buffer_Offset;
2750                             {
2751                                 Status[IsUpdated]=true;
2752                                 Status[User_16]=true;
2753                             }
2754                         }
2755                     }
2756                     if (Complete_Stream->Streams[pid]->Searching_TimeStamp_Start)
2757                     {
2758                         //This is the first PCR
2759                         Complete_Stream->Streams[pid]->TimeStamp_Start=program_clock_reference;
2760                         Complete_Stream->Streams[pid]->TimeStamp_Start_Offset=File_Offset+Buffer_Offset;
2761                         Complete_Stream->Streams[pid]->TimeStamp_End=program_clock_reference;
2762                         Complete_Stream->Streams[pid]->TimeStamp_End_IsUpdated=true;
2763                         Complete_Stream->Streams[pid]->TimeStamp_End_Offset=File_Offset+Buffer_Offset;
2764                         Complete_Stream->Streams[pid]->Searching_TimeStamp_Start_Set(false);
2765                         Complete_Stream->Streams[pid]->Searching_TimeStamp_End_Set(true);
2766                         Complete_Stream->Streams_With_StartTimeStampCount++;
2767                         {
2768                             Status[IsUpdated]=true;
2769                             Status[User_16]=true;
2770                         }
2771                     }
2772 
2773                     //Test if we can find the TS bitrate
2774                     if (!Complete_Stream->Streams[pid]->EndTimeStampMoreThanxSeconds && Complete_Stream->Streams[pid]->TimeStamp_Start!=(int64u)-1
2775                     && (File_Offset+Buffer_Offset-Buffer_TotalBytes_FirstSynched)*2<File_Size)
2776                     {
2777                         if (program_clock_reference<Complete_Stream->Streams[pid]->TimeStamp_Start)
2778                         {
2779                             if (Complete_Stream->Streams[pid]->TimeStamp_Start-program_clock_reference<10LL*90000*300) //Testing if difference is less that 10 seconds (value arbitrary choosen)
2780                                 Complete_Stream->Streams[pid]->TimeStamp_Start=program_clock_reference; //Looks like we have a small jump in the past in a buggy file, accepting it.
2781                             else
2782                                 program_clock_reference+=0x200000000LL*300; //33 bits, cyclic
2783                         }
2784                         if ((program_clock_reference-Complete_Stream->Streams[pid]->TimeStamp_Start)>Begin_MaxDuration)
2785                         {
2786                             Complete_Stream->Streams[pid]->EndTimeStampMoreThanxSeconds=true;
2787                             Complete_Stream->Streams_With_EndTimeStampMoreThanxSecondsCount++;
2788                             if (Complete_Stream->Streams_NotParsedCount
2789                              && Complete_Stream->Streams_With_StartTimeStampCount>0
2790                              && Complete_Stream->Streams_With_StartTimeStampCount==Complete_Stream->Streams_With_EndTimeStampMoreThanxSecondsCount)
2791                             {
2792                                 //We are already parsing 16 seconds (for all PCRs), we don't hope to have more info
2793                                 MpegTs_JumpTo_Begin=File_Offset+Buffer_Offset-Buffer_TotalBytes_FirstSynched;
2794                                 MpegTs_JumpTo_End=MpegTs_JumpTo_Begin;
2795                                 if (MpegTs_JumpTo_Begin+MpegTs_JumpTo_End>=File_Size)
2796                                 {
2797                                     if (MpegTs_JumpTo_Begin+MpegTs_JumpTo_End>File_Size)
2798                                     {
2799                                         MpegTs_JumpTo_Begin=File_Size;
2800                                         MpegTs_JumpTo_End=0;
2801                                     }
2802                                     else
2803                                         MpegTs_JumpTo_Begin=File_Size-MpegTs_JumpTo_End;
2804                                 }
2805                             }
2806                         }
2807                     }
2808                 }
2809                 if (transport_private_data_flag && adaptation_field_length>1+(PCR_flag?6:0)+(OPCR_flag?6:0)+(splicing_point_flag?1:0)+1)
2810                 {
2811                     int8u transport_private_data_length=Buffer[Buffer_Offset+BDAV_Size+5+1+(PCR_flag?6:0)+(OPCR_flag?6:0)+(splicing_point_flag?1:0)];
2812                     if (1+(PCR_flag?6:0)+(OPCR_flag?6:0)+(splicing_point_flag?1:0)+1+transport_private_data_length<=adaptation_field_length)
2813                     {
2814                         int64u Element_Offset_Save=Element_Offset;
2815                         Element_Offset=5+1+(PCR_flag?6:0)+(OPCR_flag?6:0)+(splicing_point_flag?1:0)+1;
2816                         transport_private_data(transport_private_data_length);
2817                         Element_Offset=Element_Offset_Save;
2818                     }
2819                 }
2820             }
2821         #endif //MEDIAINFO_MPEGTS_PCR_YES
2822         Element_Offset+=1+adaptation_field_length;
2823     #if MEDIAINFO_TRACE
2824     }
2825     #endif //MEDIAINFO_TRACE
2826 }
2827 
2828 //---------------------------------------------------------------------------
2829 #if MEDIAINFO_EVENTS
Header_Parse_Events()2830 void File_MpegTs::Header_Parse_Events()
2831 {
2832 }
2833 #endif //MEDIAINFO_EVENTS
2834 
2835 //---------------------------------------------------------------------------
2836 #if MEDIAINFO_EVENTS
Header_Parse_Events_Duration(int64u program_clock_reference)2837 void File_MpegTs::Header_Parse_Events_Duration(int64u program_clock_reference)
2838 {
2839 }
2840 #endif //MEDIAINFO_EVENTS
2841 
2842 //---------------------------------------------------------------------------
2843 #if MEDIAINFO_ADVANCED2
Read_Buffer_SegmentChange()2844 void File_MpegTs::Read_Buffer_SegmentChange()
2845 {
2846     if (Complete_Stream==NULL || Complete_Stream->Streams.empty())
2847         return;
2848 
2849     for (size_t StreamID=0; StreamID<0x2000; StreamID++)//std::map<int64u, stream>::iterator Stream=Streams.begin(); Stream!=Streams.end(); Stream++)
2850         if (Complete_Stream->Streams[StreamID]->Parser)
2851             Complete_Stream->Streams[StreamID]->Parser->Open_Buffer_SegmentChange();
2852 }
2853 #endif //MEDIAINFO_ADVANCED2
2854 
2855 //---------------------------------------------------------------------------
Data_Parse()2856 void File_MpegTs::Data_Parse()
2857 {
2858     //Counting
2859     Frame_Count++;
2860 
2861     //TSP specific
2862     if (TSP_Size)
2863         Element_Size-=TSP_Size;
2864 
2865     #if MEDIAINFO_DUPLICATE
2866         if (Complete_Stream->Streams[pid]->ShouldDuplicate)
2867             File__Duplicate_Write();
2868     #endif //MEDIAINFO_DUPLICATE
2869 
2870     //Parsing
2871     if (!Complete_Stream->Streams[pid]->Searching_Payload_Start
2872      && !Complete_Stream->Streams[pid]->Searching_Payload_Continue
2873      #ifdef MEDIAINFO_MPEGTS_PESTIMESTAMP_YES
2874          && !Complete_Stream->Streams[pid]->Searching_ParserTimeStamp_Start
2875          && !Complete_Stream->Streams[pid]->Searching_ParserTimeStamp_End
2876      #endif //MEDIAINFO_MPEGTS_PESTIMESTAMP_YES
2877      )
2878         Skip_XX(Element_Size,                                   "data");
2879     else
2880         switch (Complete_Stream->Streams[pid]->Kind)
2881         {
2882             case complete_stream::stream::pes : PES(); break;
2883             case complete_stream::stream::psi : PSI(); break;
2884             default: ;
2885         }
2886 
2887     //TSP specific
2888     if (TSP_Size)
2889     {
2890         Element_Size+=TSP_Size;
2891         switch(TSP_Size)
2892         {
2893             case 16: Skip_B16(                                  "TSP"); break; //TSP supplement
2894             default: Skip_XX(TSP_Size,                          "TSP");
2895         }
2896     }
2897 }
2898 
2899 //***************************************************************************
2900 // Elements
2901 //***************************************************************************
2902 
2903 //---------------------------------------------------------------------------
PES()2904 void File_MpegTs::PES()
2905 {
2906     //Info
2907     DETAILS_INFO(if (Complete_Stream->transport_stream_id_IsValid) Element_Info1(Mpeg_Psi_stream_type_Info(Complete_Stream->Streams[pid]->stream_type, Complete_Stream->Transport_Streams[Complete_Stream->transport_stream_id].Programs[Complete_Stream->Streams[pid]->program_numbers[0]].registration_format_identifier));)
2908 
2909     //Demux
2910     #if MEDIAINFO_DEMUX
2911         Element_Code=pid;
2912         Demux(Buffer+Buffer_Offset, (size_t)Element_Size, ContentType_MainStream);
2913     #endif //MEDIAINFO_DEMUX
2914 
2915     //Exists
2916     if (!Complete_Stream->Streams[pid]->IsRegistered)
2917     {
2918         Complete_Stream->Streams[pid]->IsRegistered=true;
2919         for (size_t Pos=0; Pos<Complete_Stream->Streams[pid]->program_numbers.size(); Pos++)
2920             if (!Complete_Stream->Transport_Streams[Complete_Stream->transport_stream_id].Programs[Complete_Stream->Streams[pid]->program_numbers[Pos]].IsRegistered)
2921             {
2922                 Complete_Stream->Transport_Streams[Complete_Stream->transport_stream_id].Programs[Complete_Stream->Streams[pid]->program_numbers[Pos]].Update_Needed_IsRegistered=true;
2923 
2924                 Complete_Stream->Transport_Streams[Complete_Stream->transport_stream_id].Programs[Complete_Stream->Streams[pid]->program_numbers[Pos]].IsRegistered=true;
2925             }
2926 
2927         Complete_Stream->Streams[pid]->IsUpdated_IsRegistered=true;
2928         Complete_Stream->PES_PIDs.insert(pid);
2929 
2930         Status[IsUpdated]=true;
2931         Status[User_19]=true;
2932     }
2933 
2934     //Case of encrypted streams
2935     if (transport_scrambling_control)
2936     {
2937         if (!Complete_Stream->Streams[pid]->Searching_Payload_Continue)
2938             Complete_Stream->Streams[pid]->Searching_Payload_Continue_Set(true); //In order to count the packets
2939 
2940         if (Complete_Stream->Streams[pid]->Scrambled_Count>16)
2941         {
2942             //Don't need anymore
2943             Complete_Stream->Streams[pid]->Searching_Payload_Start_Set(false);
2944             Complete_Stream->Streams[pid]->Searching_Payload_Continue_Set(false);
2945             #ifdef MEDIAINFO_MPEGTS_PESTIMESTAMP_YES
2946                 Complete_Stream->Streams[pid]->Searching_ParserTimeStamp_Start_Set(false);
2947             #endif //MEDIAINFO_MPEGTS_PESTIMESTAMP_YES
2948             if (!Complete_Stream->Streams[pid]->IsParsed && Complete_Stream->Streams_NotParsedCount)
2949             {
2950                 Complete_Stream->Streams[pid]->IsParsed=true;
2951                 Complete_Stream->Streams_NotParsedCount--;
2952             }
2953         }
2954         Skip_XX(Element_Size-Element_Offset,                    "Scrambled data");
2955 
2956         return;
2957     }
2958     else if (Complete_Stream->Streams[pid]->Scrambled_Count)
2959         Complete_Stream->Streams[pid]->Scrambled_Count--;
2960 
2961     //Parser creation
2962     if (Complete_Stream->Streams[pid]->Parser==NULL)
2963     {
2964         //Waiting for first payload_unit_start_indicator
2965         if (!payload_unit_start_indicator)
2966         {
2967             Element_DoNotShow(); //We don't want to show this item because there is no interessant info
2968             return; //This is not the start of the PES
2969         }
2970 
2971         //If unknown stream_type
2972         if (Complete_Stream->transport_stream_id_IsValid
2973          && Mpeg_Psi_stream_type_StreamKind(Complete_Stream->Streams[pid]->stream_type, Complete_Stream->Transport_Streams[Complete_Stream->transport_stream_id].Programs[Complete_Stream->Streams[pid]->program_numbers[0]].registration_format_identifier)==Stream_Max
2974          && Complete_Stream->Streams[pid]->stream_type!=0x06 //Exception for private data
2975          && Complete_Stream->Streams[pid]->stream_type<=0x7F //Exception for private data
2976          && Mpeg_Descriptors_registration_format_identifier_StreamKind(Complete_Stream->Transport_Streams[Complete_Stream->transport_stream_id].Programs[Complete_Stream->Streams[pid]->program_numbers[0]].registration_format_identifier)==Stream_Max //From Descriptor
2977          && Config->File_MpegTs_stream_type_Trust_Get())
2978         {
2979             Complete_Stream->Streams[pid]->Searching_Payload_Start_Set(false);
2980             Complete_Stream->Streams[pid]->Searching_Payload_Continue_Set(false);
2981             #ifdef MEDIAINFO_MPEGTS_PESTIMESTAMP_YES
2982                 Complete_Stream->Streams[pid]->Searching_ParserTimeStamp_Start_Set(false);
2983                 Complete_Stream->Streams[pid]->Searching_ParserTimeStamp_End_Set(false);
2984             #endif //MEDIAINFO_MPEGTS_PESTIMESTAMP_YES
2985             if (!Complete_Stream->Streams[pid]->IsParsed && Complete_Stream->Streams_NotParsedCount)
2986             {
2987                 Complete_Stream->Streams[pid]->IsParsed=true;
2988                 Complete_Stream->Streams_NotParsedCount--;
2989             }
2990             return;
2991         }
2992 
2993         //Allocating an handle if needed
2994         #if defined(MEDIAINFO_MPEGPS_YES)
2995             Complete_Stream->Streams[pid]->Parser=new File_MpegPs;
2996             #if MEDIAINFO_SEEK
2997                 if (Unsynch_Frame_Counts.find(pid)!=Unsynch_Frame_Counts.end())
2998                 {
2999                     ((File_MpegPs*)Complete_Stream->Streams[pid]->Parser)->Unsynch_Frame_Count_Temp=Unsynch_Frame_Counts[pid];
3000                     Unsynch_Frame_Counts.erase(pid);
3001                 }
3002             #endif //MEDIAINFO_SEEK
3003             #if MEDIAINFO_DEMUX
3004                 if (Config_Demux)
3005                 {
3006                     if (Complete_Stream->Streams[pid]->stream_type==0x20 && Complete_Stream->Streams[pid]->SubStream_pid)
3007                     {
3008                         //Creating the demux buffer
3009                         ((File_MpegPs*)Complete_Stream->Streams[pid]->Parser)->SubStream_Demux=new File_MpegPs::demux;
3010                         //If main parser is already created, associating the new demux buffer
3011                         if (Complete_Stream->Streams[Complete_Stream->Streams[pid]->SubStream_pid]->Parser)
3012                             ((File_MpegPs*)Complete_Stream->Streams[Complete_Stream->Streams[pid]->SubStream_pid]->Parser)->SubStream_Demux=((File_MpegPs*)Complete_Stream->Streams[pid]->Parser)->SubStream_Demux;
3013                     }
3014                     if (Complete_Stream->Streams[pid]->stream_type!=0x20 && Complete_Stream->Streams[pid]->SubStream_pid && (File_MpegPs*)Complete_Stream->Streams[Complete_Stream->Streams[pid]->SubStream_pid]->Parser)
3015                     {
3016                         //If SubStream parser is already created, associating the SubStream demux buffer
3017                         ((File_MpegPs*)Complete_Stream->Streams[pid]->Parser)->SubStream_Demux=((File_MpegPs*)Complete_Stream->Streams[Complete_Stream->Streams[pid]->SubStream_pid]->Parser)->SubStream_Demux;
3018                     }
3019                 }
3020             #endif //MEDIAINFO_DEMUX
3021             #if defined(MEDIAINFO_ARIBSTDB24B37_YES)
3022                 if (FromAribStdB24B37)
3023                     ((File_MpegPs*)Complete_Stream->Streams[pid]->Parser)->FromAribStdB24B37=true;
3024             #endif //defined(MEDIAINFO_ARIBSTDB24B37_YES)
3025             #ifdef MEDIAINFO_MPEGTS_PESTIMESTAMP_YES
3026                 if (Searching_TimeStamp_Start)
3027                     Complete_Stream->Streams[pid]->Searching_ParserTimeStamp_Start_Set(true);
3028                 ((File_MpegPs*)Complete_Stream->Streams[pid]->Parser)->Searching_TimeStamp_Start=Complete_Stream->Streams[pid]->Searching_ParserTimeStamp_Start;
3029             #endif //MEDIAINFO_MPEGTS_PESTIMESTAMP_YES
3030             ((File_MpegPs*)Complete_Stream->Streams[pid]->Parser)->FromTS=true;
3031             if (Config->File_MpegTs_stream_type_Trust_Get())
3032                 ((File_MpegPs*)Complete_Stream->Streams[pid]->Parser)->FromTS_stream_type=Complete_Stream->Streams[pid]->stream_type;
3033             ((File_MpegPs*)Complete_Stream->Streams[pid]->Parser)->FromTS_descriptor_tag=Complete_Stream->Streams[pid]->descriptor_tag;
3034             if (!Complete_Stream->Streams[pid]->program_numbers.empty())
3035                 ((File_MpegPs*)Complete_Stream->Streams[pid]->Parser)->FromTS_program_format_identifier=Complete_Stream->Transport_Streams[Complete_Stream->transport_stream_id].Programs[Complete_Stream->Streams[pid]->program_numbers[0]].registration_format_identifier;
3036             ((File_MpegPs*)Complete_Stream->Streams[pid]->Parser)->FromTS_format_identifier=Complete_Stream->Streams[pid]->registration_format_identifier;
3037             ((File_MpegPs*)Complete_Stream->Streams[pid]->Parser)->MPEG_Version=2;
3038             complete_stream::transport_stream::iod_ess::iterator IOD_ES=Complete_Stream->Transport_Streams[Complete_Stream->transport_stream_id].IOD_ESs.find(Complete_Stream->Streams[pid]->FMC_ES_ID);
3039             if (IOD_ES!=Complete_Stream->Transport_Streams[Complete_Stream->transport_stream_id].IOD_ESs.end())
3040             {
3041                 #ifdef MEDIAINFO_MPEG4_YES
3042                     ((File_MpegPs*)Complete_Stream->Streams[pid]->Parser)->ParserFromTs=IOD_ES->second.Parser; IOD_ES->second.Parser=NULL;
3043                     ((File_MpegPs*)Complete_Stream->Streams[pid]->Parser)->SLConfig=IOD_ES->second.SLConfig; IOD_ES->second.SLConfig=NULL;
3044                 #endif
3045             }
3046             #ifdef MEDIAINFO_MPEGTS_PESTIMESTAMP_YES
3047                 Complete_Stream->Streams[pid]->Parser->ShouldContinueParsing=true;
3048             #endif //MEDIAINFO_MPEGTS_PESTIMESTAMP_YES
3049             Complete_Stream->Streams[pid]->Searching_Payload_Continue_Set(true);
3050         #else
3051             //Filling
3052             Streams[pid]->Parser=new File_Unknown();
3053         #endif
3054         Complete_Stream->Streams[pid]->Parser->CA_system_ID_MustSkipSlices=Complete_Stream->Streams[pid]->CA_system_ID_MustSkipSlices;
3055         #if MEDIAINFO_IBIUSAGE
3056             if (Ibi.Streams[pid]==NULL)
3057                 Ibi.Streams[pid]=new ibi::stream;
3058             Complete_Stream->Streams[pid]->Parser->IbiStream=Ibi.Streams[pid];
3059         #endif //MEDIAINFO_IBIUSAGE
3060         Open_Buffer_Init(Complete_Stream->Streams[pid]->Parser);
3061     }
3062 
3063     //If unsynched, waiting for first payload_unit_start_indicator
3064     if (!Complete_Stream->Streams[pid]->Parser->Synched && !payload_unit_start_indicator)
3065     {
3066         Element_DoNotShow(); //We don't want to show this item because there is no interessant info
3067         return; //This is not the start of the PES
3068     }
3069 
3070     //Parsing
3071     if (Complete_Stream->Streams[pid]->Kind==complete_stream::stream::pes && Complete_Stream->Streams[pid]->IsPCR)
3072         ((File_MpegPs*)Complete_Stream->Streams[pid]->Parser)->FrameInfo.PCR=Complete_Stream->Streams[pid]->TimeStamp_End==(int64u)-1?(int64u)-1:Complete_Stream->Streams[pid]->TimeStamp_End*1000/27; //27 MHz
3073     #if MEDIAINFO_IBIUSAGE
3074         if (Complete_Stream->transport_stream_id!=(int16u)-1 && !Complete_Stream->Streams[pid]->program_numbers.empty())
3075         {
3076             int16u Program_PID=Complete_Stream->Transport_Streams[Complete_Stream->transport_stream_id].Programs[Complete_Stream->Streams[pid]->program_numbers[0]].pid;
3077             Complete_Stream->Streams[pid]->Parser->Ibi_SynchronizationOffset_Current=Complete_Stream->Streams[Program_PID]->Ibi_SynchronizationOffset_BeginOfFrame;
3078             if (Complete_Stream->Streams[pid]->Parser->Ibi_SynchronizationOffset_Current==(int64u)-1)
3079                 return; //Not yet synchronized
3080         }
3081         else
3082             Complete_Stream->Streams[pid]->Parser->Ibi_SynchronizationOffset_Current=File_Offset+Buffer_Offset-Header_Size;
3083     #endif //MEDIAINFO_IBIUSAGE
3084 
3085     #if defined(MEDIAINFO_ARIBSTDB24B37_YES)
3086         if (FromAribStdB24B37)
3087             Complete_Stream->Streams[pid]->Parser->FrameInfo=FrameInfo;
3088     #endif //defined(MEDIAINFO_ARIBSTDB24B37_YES)
3089 
3090     //EIA-608/EIA-708 descriptors
3091     #if defined(MEDIAINFO_EIA608_YES) || defined(MEDIAINFO_EIA708_YES)
3092         Complete_Stream->Streams[pid]->Parser->ServiceDescriptors=NULL;
3093         if (Complete_Stream->Streams[pid]->ServiceDescriptors_IsPresent)
3094             Complete_Stream->Streams[pid]->Parser->ServiceDescriptors=&Complete_Stream->Streams[pid]->ServiceDescriptors;
3095         if (Complete_Stream->Streams[pid]->Parser->ServiceDescriptors==NULL)
3096         {
3097             for (size_t ProgramPos=0; ProgramPos<Complete_Stream->Streams[pid]->program_numbers.size(); ++ProgramPos)
3098             {
3099                 Complete_Stream->Streams[pid]->Parser->ServiceDescriptors=Complete_Stream->Transport_Streams[Complete_Stream->transport_stream_id].Programs[Complete_Stream->Streams[pid]->program_numbers[ProgramPos]].ServiceDescriptors;
3100                 if (Complete_Stream->Streams[pid]->Parser->ServiceDescriptors)
3101                     break;
3102             }
3103         }
3104         if (Complete_Stream->Streams[pid]->Parser->ServiceDescriptors==NULL)
3105         {
3106             for (size_t ProgramPos=0; ProgramPos<Complete_Stream->Streams[pid]->program_numbers.size(); ++ProgramPos)
3107                 if (Complete_Stream->Transport_Streams[Complete_Stream->transport_stream_id].Programs[Complete_Stream->Streams[pid]->program_numbers[ProgramPos]].source_id_IsValid)
3108                 {
3109                     int16u source_id=Complete_Stream->Transport_Streams[Complete_Stream->transport_stream_id].Programs[Complete_Stream->Streams[pid]->program_numbers[ProgramPos]].source_id;
3110                     complete_stream::sources::iterator Source=Complete_Stream->Sources.find(source_id);
3111                     if (Source!=Complete_Stream->Sources.end())
3112                         for (complete_stream::source::atsc_epg_blocks::iterator ATSC_EPG_Block=Source->second.ATSC_EPG_Blocks.begin(); ATSC_EPG_Block!=Source->second.ATSC_EPG_Blocks.end(); ++ATSC_EPG_Block)
3113                             for (complete_stream::source::atsc_epg_block::events::iterator Event=ATSC_EPG_Block->second.Events.begin(); Event!=ATSC_EPG_Block->second.Events.end(); ++Event)
3114                                 if (Event->second.ServiceDescriptors)
3115                                 {
3116                                     Complete_Stream->Streams[pid]->Parser->ServiceDescriptors=Event->second.ServiceDescriptors;
3117                                     break;
3118                                 }
3119                 }
3120         }
3121         if (Complete_Stream->Streams[pid]->Parser->ServiceDescriptors==NULL)
3122             Complete_Stream->Streams[pid]->Parser->ServiceDescriptors=&Complete_Stream->Streams[pid]->ServiceDescriptors; //Default to empty descriptor present in order to say descriptor info is supported
3123     #endif
3124 
3125     //Teletext descriptors
3126     #if defined(MEDIAINFO_TELETEXT_YES)
3127         Complete_Stream->Streams[pid]->Parser->Teletexts=&Complete_Stream->Streams[pid]->Teletexts;
3128     #endif
3129 
3130     Open_Buffer_Continue(Complete_Stream->Streams[pid]->Parser);
3131     PES_Parse_Finish();
3132 }
3133 
3134 //---------------------------------------------------------------------------
PES_Parse_Finish()3135 void File_MpegTs::PES_Parse_Finish()
3136 {
3137     //Test if parsing of headers is OK
3138     if (NoPatPmt && !Status[IsAccepted])
3139         Accept("MPEG-TS");
3140 
3141     if (Complete_Stream->Streams[pid]->Parser->Status[IsUpdated])
3142     {
3143         Complete_Stream->Streams[pid]->Parser->Status[IsUpdated]=false;
3144         Complete_Stream->Streams[pid]->IsUpdated_Info=true;
3145         for (size_t Pos=0; Pos<Complete_Stream->Streams[pid]->program_numbers.size(); Pos++)
3146             Complete_Stream->Transport_Streams[Complete_Stream->transport_stream_id].Programs[Complete_Stream->Streams[pid]->program_numbers[Pos]].Update_Needed_IsRegistered=true;
3147 
3148         Status[IsUpdated]=true;
3149         Status[User_19]=true;
3150     }
3151 
3152     #if defined(MEDIAINFO_MPEGPS_YES) && defined(MEDIAINFO_MPEGTS_PESTIMESTAMP_YES)
3153         if (Complete_Stream->Streams[pid]->Kind==complete_stream::stream::pes
3154          && MpegTs_JumpTo_Begin+MpegTs_JumpTo_End>File_Size
3155          && !Complete_Stream->Streams[pid]->Searching_ParserTimeStamp_End
3156          && ((File_MpegPs*)Complete_Stream->Streams[pid]->Parser)->HasTimeStamps)
3157         {
3158             Complete_Stream->Streams[pid]->Searching_ParserTimeStamp_Start_Set(false);
3159             Complete_Stream->Streams[pid]->Searching_ParserTimeStamp_End_Set(true);
3160         }
3161     #endif //MEDIAINFO_MPEGTS_PESTIMESTAMP_YES
3162 
3163     //Need anymore?
3164     if (Complete_Stream->Streams[pid]->Parser->Status[IsFilled]
3165      || Complete_Stream->Streams[pid]->Parser->Status[IsFinished])
3166     {
3167         if ((Complete_Stream->Streams[pid]->Searching_Payload_Start || Complete_Stream->Streams[pid]->Searching_Payload_Continue) && Config->ParseSpeed<1 && MpegTs_JumpTo_End)
3168         {
3169             if (Config->File_StopSubStreamAfterFilled_Get())
3170             {
3171                 Complete_Stream->Streams[pid]->Searching_Payload_Start_Set(false);
3172                 Complete_Stream->Streams[pid]->Searching_Payload_Continue_Set(false);
3173             }
3174             if (!Complete_Stream->Streams[pid]->IsParsed && Complete_Stream->Streams_NotParsedCount)
3175             {
3176                 Complete_Stream->Streams[pid]->IsParsed=true;
3177                 Complete_Stream->Streams_NotParsedCount--;
3178             }
3179         }
3180         #ifdef MEDIAINFO_MPEGTS_PESTIMESTAMP_YES
3181             if (Complete_Stream->Streams[pid]->Searching_ParserTimeStamp_Start)
3182                 Complete_Stream->Streams[pid]->Searching_ParserTimeStamp_Start_Set(false);
3183         #else //MEDIAINFO_MPEGTS_PESTIMESTAMP_YES
3184             if (Config->ParseSpeed<1.0)
3185                 Finish(Complete_Stream->Streams[pid]->Parser);
3186         #endif //MEDIAINFO_MPEGTS_PESTIMESTAMP_YES
3187     }
3188 
3189     #if MEDIAINFO_SEEK && MEDIAINFO_IBIUSAGE
3190         if (Seek_ID!=(int64u)-1)
3191         {
3192             if (Ibi.Streams[Seek_ID]->IsModified)
3193             {
3194                 Read_Buffer_Seek(2, Seek_Value, Seek_ID);
3195             }
3196             else if (Ibi.Streams[Seek_ID]->Infos_Pos>=2 && Ibi.Streams[Seek_ID]->IsSynchronized && Ibi.Streams[Seek_ID]->Infos[Ibi.Streams[Seek_ID]->Infos_Pos-1].StreamOffset>=Seek_Value_Maximal)
3197             {
3198                 InfiniteLoop_Detect++;
3199                 if (InfiniteLoop_Detect>16)
3200                 {
3201                     //Infinite loop
3202                     Seek_ID=(int64u)-1;
3203                     Seek_Value=(int64u)-1;
3204                     InfiniteLoop_Detect=0;
3205                     Config->Demux_IsSeeking=false;
3206                 }
3207                 else
3208                 {
3209                     //No intermediate seek point found, going to previous seek point
3210                     GoTo(Ibi.Streams[Seek_ID]->Infos[Ibi.Streams[Seek_ID]->Infos_Pos-2].StreamOffset);
3211                     Open_Buffer_Unsynch();
3212                 }
3213             }
3214         }
3215     #endif //MEDIAINFO_SEEK && MEDIAINFO_IBIUSAGE
3216 }
3217 
3218 //---------------------------------------------------------------------------
PSI()3219 void File_MpegTs::PSI()
3220 {
3221     //Initializing
3222     if (payload_unit_start_indicator)
3223     {
3224         #if MEDIAINFO_EVENTS
3225             StreamIDs[StreamIDs_Size-1]=pid;
3226         #endif //MEDIAINFO_EVENTS
3227         delete ((File_Mpeg_Psi*)Complete_Stream->Streams[pid]->Parser); Complete_Stream->Streams[pid]->Parser=new File_Mpeg_Psi;
3228         Open_Buffer_Init(Complete_Stream->Streams[pid]->Parser);
3229         ((File_Mpeg_Psi*)Complete_Stream->Streams[pid]->Parser)->Complete_Stream=Complete_Stream;
3230         ((File_Mpeg_Psi*)Complete_Stream->Streams[pid]->Parser)->pid=pid;
3231     }
3232     else if (Complete_Stream->Streams[pid]->Parser==NULL)
3233     {
3234         Skip_XX(Element_Size,                                   "data");
3235         return; //This is not the start of the PSI
3236     }
3237 
3238     //Parsing
3239     #if MEDIAINFO_IBIUSAGE
3240         Complete_Stream->Streams[pid]->Parser->Ibi_SynchronizationOffset_Current=File_Offset+Buffer_Offset-Header_Size;
3241     #endif //MEDIAINFO_IBIUSAGE
3242     Open_Buffer_Continue(Complete_Stream->Streams[pid]->Parser);
3243 
3244     //Filling
3245     if (Complete_Stream->Streams[pid]->Parser->Status[IsFilled])
3246     {
3247         //Accept
3248         if (!Status[IsAccepted] && pid==0x0000 && Complete_Stream->Streams[pid]->Parser->Status[IsAccepted])
3249             Accept("MPEG-TS");
3250 
3251         //Disabling this pid
3252         delete Complete_Stream->Streams[pid]->Parser; Complete_Stream->Streams[pid]->Parser=NULL;
3253         Complete_Stream->Streams[pid]->Searching_Payload_Start_Set(true);
3254         Complete_Stream->Streams[pid]->Searching_Payload_Continue_Set(false);
3255 
3256         //EPG
3257         if (Complete_Stream->Sources_IsUpdated || Complete_Stream->Programs_IsUpdated)
3258         {
3259             Status[IsUpdated]=true;
3260             Status[User_18]=true;
3261         }
3262 
3263         //Duration
3264         if (Complete_Stream->Duration_End_IsUpdated)
3265         {
3266             Status[IsUpdated]=true;
3267             Status[User_17]=true;
3268         }
3269 
3270         //Program change
3271         if (pid==0x0000)
3272         {
3273             Status[IsFilled]=false;
3274 
3275             Status[IsUpdated]=true;
3276             Status[User_19]=true;
3277         }
3278         if (!Complete_Stream->Streams[pid]->Table_IDs.empty() && Complete_Stream->Streams[pid]->Table_IDs[0x02])
3279         {
3280             Status[IsFilled]=false;
3281 
3282             //Status[IsUpdated]=true;
3283             //Status[User_19]=true;
3284         }
3285 
3286         //Item removal
3287         if (pid==0x0000 || (!Complete_Stream->Streams[pid]->Table_IDs.empty() && Complete_Stream->Streams[pid]->Table_IDs[0x02]))
3288         {
3289             for (size_t StreamKind=Stream_General+1; StreamKind<Stream_Max; StreamKind++)
3290                 if (!Complete_Stream->StreamPos_ToRemove[StreamKind].empty())
3291                 {
3292                     sort(Complete_Stream->StreamPos_ToRemove[StreamKind].begin(), Complete_Stream->StreamPos_ToRemove[StreamKind].end());
3293                     size_t Pos=Complete_Stream->StreamPos_ToRemove[StreamKind].size();
3294                     do
3295                     {
3296                         Pos--;
3297 
3298                         //Erasing text substreams
3299                         Ztring ID_ToFind=Retrieve((stream_t)StreamKind, Complete_Stream->StreamPos_ToRemove[StreamKind][Pos], General_ID)+__T('-');
3300                         for (size_t TextPos=0; TextPos<Count_Get(Stream_Text); TextPos++)
3301                             if (Retrieve(Stream_Text, TextPos, General_ID).find(ID_ToFind)==0)
3302                                  Stream_Erase(Stream_Text, TextPos);
3303 
3304                         //Erasing the stream
3305                         Stream_Erase((stream_t)StreamKind, Complete_Stream->StreamPos_ToRemove[StreamKind][Pos]);
3306 
3307                         //Moving other StreamPos
3308                         for (size_t Pos2=Pos+1; Pos2<Complete_Stream->StreamPos_ToRemove[StreamKind].size(); Pos2++)
3309                             Complete_Stream->StreamPos_ToRemove[StreamKind][Pos2]--;
3310 
3311                         //Informing that the menu must be recalculated - TODO: only the related programs
3312                         if (StreamKind!=Stream_Menu)
3313                         {
3314                             for (complete_stream::transport_stream::programs::iterator Program=Complete_Stream->Transport_Streams[Complete_Stream->transport_stream_id].Programs.begin(); Program!=Complete_Stream->Transport_Streams[Complete_Stream->transport_stream_id].Programs.end(); ++Program)
3315                                 Program->second.Update_Needed_StreamPos=true;
3316                         }
3317                         else if (Complete_Stream->StreamPos_ToRemove[StreamKind][Pos]<Complete_Stream->program_number_Order.size())
3318                         {
3319                             Complete_Stream->program_number_Order.erase(Complete_Stream->program_number_Order.begin()+Complete_Stream->StreamPos_ToRemove[StreamKind][Pos]);
3320                         }
3321                     }
3322                     while (Pos);
3323                     Complete_Stream->StreamPos_ToRemove[StreamKind].clear();
3324                 }
3325 
3326             Status[IsUpdated]=true;
3327             Status[User_19]=true;
3328         }
3329     }
3330     else
3331         //Waiting for more data
3332         Complete_Stream->Streams[pid]->Searching_Payload_Continue_Set(true);
3333 }
3334 
3335 //---------------------------------------------------------------------------
SetAllToPES()3336 void File_MpegTs::SetAllToPES()
3337 {
3338     Complete_Stream->Streams_NotParsedCount=(size_t)-1;
3339     for (size_t StreamID=0; StreamID<0x2000; StreamID++)
3340     {
3341         delete Complete_Stream->Streams[StreamID]; Complete_Stream->Streams[StreamID]=new complete_stream::stream;
3342     }
3343     #ifdef MEDIAINFO_ARIBSTDB24B37_YES
3344         size_t StreamID=FromAribStdB24B37?0x00:0x20;
3345     #else //MEDIAINFO_ARIBSTDB24B37_YES
3346         size_t StreamID=0x20;
3347     #endif //MEDIAINFO_ARIBSTDB24B37_YES
3348     for (; StreamID<0x1FFF; StreamID++)
3349     {
3350         Complete_Stream->Streams[StreamID]->Kind=complete_stream::stream::pes;
3351         Complete_Stream->Streams[StreamID]->Searching_Payload_Start_Set(true);
3352         Complete_Stream->Streams[StreamID]->Searching_Payload_Continue_Set(false);
3353         #if MEDIAINFO_TRACE
3354             if (Trace_Activated)
3355                 Complete_Stream->Streams[StreamID]->Element_Info1="PES";
3356         #endif //MEDIAINFO_TRACE
3357         #ifdef MEDIAINFO_MPEGTS_PCR_YES
3358             Complete_Stream->Streams[StreamID]->Searching_TimeStamp_Start_Set(true);
3359             Complete_Stream->Streams[StreamID]->Searching_TimeStamp_End_Set(false);
3360         #endif //MEDIAINFO_MPEGTS_PCR_YES
3361         #ifdef MEDIAINFO_MPEGTS_PESTIMESTAMP_YES
3362             Complete_Stream->Streams[StreamID]->Searching_ParserTimeStamp_Start_Set(true);
3363             Complete_Stream->Streams[StreamID]->Searching_ParserTimeStamp_End_Set(false);
3364         #endif //MEDIAINFO_MPEGTS_PESTIMESTAMP_YES
3365     }
3366 }
3367 
3368 //---------------------------------------------------------------------------
transport_private_data(int8u transport_private_data_length)3369 void File_MpegTs::transport_private_data(int8u transport_private_data_length)
3370 {
3371     //Trying SCTE 128
3372     int64u End=Element_Offset+transport_private_data_length;
3373     #if MEDIAINFO_TRACE
3374         bool Trace_Activated_Save=Trace_Activated;
3375         Trace_Activated=false;
3376     #endif //MEDIAINFO_TRACE
3377     Element_Begin1("SCTE 128 coherency test");
3378     bool IsOk=true;
3379     while (Element_Offset+2<=End)
3380     {
3381         int8u tag, length;
3382         Get_B1 (tag,                                "tag");
3383         Get_B1 (length,                             "length");
3384         if (Element_Offset+length>End || (tag==0xDF && length<4))
3385         {
3386             Skip_XX(End-Element_Offset,             "problem");
3387             IsOk=false;
3388         }
3389         else
3390             Skip_XX(length,                         "data");
3391     }
3392     if (Element_Offset<End)
3393     {
3394         Skip_XX(End-Element_Offset,                 "problem");
3395         IsOk=false;
3396     }
3397     Element_End0();
3398     #if MEDIAINFO_TRACE
3399         Trace_Activated=Trace_Activated_Save;
3400     #endif //MEDIAINFO_TRACE
3401     if (IsOk)
3402     {
3403         Element_Offset=End-transport_private_data_length;
3404         while (Element_Offset+2<=End)
3405         {
3406             Element_Begin0();
3407             int8u tag, length;
3408             Get_B1 (tag,                                "tag"); Param_Info1(Scte128_tag(tag)); Element_Name(Scte128_tag(tag));
3409             Get_B1 (length,                             "length");
3410             if (tag==0xDF && length>=4)
3411             {
3412                 int32u format_identifier;
3413                 Get_C4 (format_identifier,              "format identifier");
3414                 switch (format_identifier)
3415                 {
3416                     case 0x45425030 : //EBP0
3417                                         {
3418                                             int64u End2=Element_Offset+length-4;
3419                                             Element_Info1("CableLabs - Encoder Boundary Point");
3420                                             BS_Begin();
3421                                             bool EBP_fragment_flag, EBP_segment_flag, EBP_SAP_flag, EBP_grouping_flag, EBP_time_flag, EBP_concealment_flag, EBP_extension_flag;
3422                                             Get_SB (EBP_fragment_flag,      "EBP_fragment_flag");
3423                                             Get_SB (EBP_segment_flag,       "EBP_segment_flag");
3424                                             Get_SB (EBP_SAP_flag,           "EBP_SAP_flag");
3425                                             Get_SB (EBP_grouping_flag,      "EBP_grouping_flag");
3426                                             Get_SB (EBP_time_flag,          "EBP_time_flag");
3427                                             Get_SB (EBP_concealment_flag,   "EBP_concealment_flag");
3428                                             Skip_SB(                        "Reserved");
3429                                             Get_SB (EBP_extension_flag,     "EBP_extension_flag");
3430                                             if (EBP_extension_flag)
3431                                             {
3432                                                 Skip_SB(                    "EBP_ext_partition_flag");
3433                                                 Skip_S1(7,                  "reserved");
3434                                             }
3435                                             if (EBP_SAP_flag)
3436                                             {
3437                                                 Skip_S1(3,                  "EBP_SAP_type");
3438                                                 Skip_S1(5,                  "reserved");
3439                                             }
3440                                             if (EBP_grouping_flag)
3441                                             {
3442                                                 bool EBP_grouping_ext_flag=true;
3443                                                 while (EBP_grouping_ext_flag && Element_Offset<End2)
3444                                                 {
3445                                                     Get_SB (EBP_grouping_ext_flag, "EBP_grouping_ext_flag");
3446                                                     Skip_S1(7,              "EBP_grouping_id");
3447                                                 }
3448                                             }
3449                                             BS_End();
3450                                             if (EBP_time_flag)
3451                                             {
3452                                                 Element_Begin1("EBP_acquisition_time");
3453                                                 if (Complete_Stream->Streams[pid] && !Complete_Stream->Streams[pid]->EBP_Marker_Detected)
3454                                                 {
3455                                                     int32u Seconds, Fraction;
3456                                                     Get_B4 (Seconds, "Seconds");  Param_Info1(Ztring().Date_From_Seconds_1970((int32u)(Seconds-2208988800))); //Param_Info1(Ztring().Date_From_Seconds_1900(Seconds)); //Temp for old ZenLib
3457                                                     Get_B4 (Fraction, "Fraction"); Param_Info1(Ztring::ToZtring(((float64)Fraction)/0x100000000LL, 9));
3458                                                     Complete_Stream->Streams[pid]->Infos["EBP_AcquisitionTime"]=Ztring().Date_From_Seconds_1970((int32u)(Seconds-2208988800))+__T('.')+Ztring::ToZtring(((float64)Fraction)/0x100000000LL, 9).substr(2); //.Date_From_Seconds_1900(Seconds)); //Temp for old ZenLib
3459                                                     Complete_Stream->Streams[pid]->EBP_Marker_Detected=true;
3460                                                 }
3461                                                 else
3462                                                 {
3463                                                     Info_B4(Seconds, "Seconds"); Param_Info1(Ztring().Date_From_Seconds_1970((int32u)(Seconds-2208988800))); //Param_Info1(Ztring().Date_From_Seconds_1900(Seconds)); //Temp for old ZenLib
3464                                                     Info_B4(Fraction, "Fraction"); Param_Info1(Ztring::ToZtring(((float64)Fraction)/0x100000000LL, 9));
3465                                                 }
3466                                                 Element_End0();
3467                                             }
3468                                             if (EBP_concealment_flag)
3469                                             {
3470                                                 Skip_B8(                    "EBP_ext_partitions");
3471                                             }
3472                                             if (Element_Offset<End)
3473                                                 Skip_XX(End-Element_Offset, "EBP_reserved_bytes");
3474                                         }
3475                                         break;
3476                     default         :   Skip_XX(length-4, "data");
3477                 }
3478             }
3479             else
3480                 Skip_XX(length,                         "data");
3481             Element_End0();
3482         }
3483     }
3484     else
3485         Skip_XX(transport_private_data_length,          "transport_private_data");
3486 }
3487 
3488 //---------------------------------------------------------------------------
MergeGeneral(complete_stream::stream * Stream,general Parameter)3489 void File_MpegTs::MergeGeneral(complete_stream::stream* Stream, general Parameter)
3490 {
3491     if (!Stream->Parser)
3492         return;
3493 
3494     const Ztring& Value = Stream->Parser->Retrieve_Const(Stream_General, 0, Parameter);
3495     if (Value.empty())
3496         return;
3497 
3498     if (Count_Get(Stream_Menu))
3499     {
3500         Ztring MenuID = Retrieve(Stream->StreamKind, Stream->StreamPos, General_MenuID);
3501         for (size_t Pos = 0; Pos<Count_Get(Stream_Menu); Pos++)
3502             if (Retrieve(Stream_Menu, Pos, General_MenuID) == MenuID)
3503                 Fill(Stream_Menu, Pos, Stream->Parser->Retrieve(Stream_General, 0, Parameter, Info_Name).To_UTF8().c_str(), Value, true);
3504     }
3505     else
3506         Fill(Stream_General, 0, Parameter, Value, true);
3507 }
3508 
3509 
3510 } //NameSpace
3511 
3512 #endif //MEDIAINFO_MPEGTS_YES
3513