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 //
9 // Information about MPEG files
10 //
11 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
12 
13 //---------------------------------------------------------------------------
14 #ifndef MediaInfo_MpegPsH
15 #define MediaInfo_MpegPsH
16 //---------------------------------------------------------------------------
17 
18 //---------------------------------------------------------------------------
19 #include "MediaInfo/File__Analyze.h"
20 #include "MediaInfo/Multiple/File_Mpeg4_Descriptors.h"
21 //---------------------------------------------------------------------------
22 
23 namespace MediaInfoLib
24 {
25 
26 //***************************************************************************
27 // Class File_Mpeg
28 //***************************************************************************
29 
30 class File_MpegPs : public File__Analyze
31 {
32 public :
33     //In
34     bool   FromTS;                      //Indicate if stream comes from TS
35     int8u  FromTS_stream_type;          //ID from TS
36     int32u FromTS_program_format_identifier; //Registration from TS
37     int32u FromTS_format_identifier;    //Registration from TS
38     int8u  FromTS_descriptor_tag;       //Descriptor from TS
39     int8u  MPEG_Version;                //MPEG Version (or automaticly detected)
40     bool   Searching_TimeStamp_Start;
41     #ifdef MEDIAINFO_MPEG4_YES
42         File__Analyze* ParserFromTs;
43         File_Mpeg4_Descriptors::slconfig* SLConfig;
44     #endif
45     #if MEDIAINFO_DEMUX
46         struct demux
47         {
48             struct buffer
49             {
50                 int64u  DTS;
51                 size_t  Buffer_Size;
52                 size_t  Buffer_Size_Max;
53                 int8u*  Buffer;
54 
bufferdemux::buffer55                 buffer()
56                 {
57                     DTS=(int64u)-1;
58                     Buffer_Size=0;
59                     Buffer_Size_Max=0;
60                     Buffer=NULL;
61                 }
62 
~bufferdemux::buffer63                 ~buffer()
64                 {
65                     delete[] Buffer;
66                 }
67             };
68             std::vector<buffer*> Buffers;
69 
demuxdemux70             demux()
71             {
72             }
73 
~demuxdemux74             ~demux()
75             {
76                 for (size_t Pos=0; Pos<Buffers.size(); Pos++)
77                     delete Buffers[Pos]; //Buffers[Pos]=NULL;
78             }
79         };
80         demux* SubStream_Demux;
81         int8u Demux_StreamIsBeingParsed_type;
82         int8u Demux_StreamIsBeingParsed_stream_id;
83     #endif //MEDIAINFO_DEMUX
84     #if MEDIAINFO_SEEK
85         int64u Unsynch_Frame_Count_Temp;
86     #endif //MEDIAINFO_SEEK
87     #if defined(MEDIAINFO_ARIBSTDB24B37_YES)
88         bool FromAribStdB24B37;
89     #endif //defined(MEDIAINFO_ARIBSTDB24B37_YES)
90 
91     //Out
92     bool   HasTimeStamps;
93 
94     //Constructor/Destructor
95     File_MpegPs();
96     ~File_MpegPs();
97 
98 private :
99     //Streams management
100     void Streams_Fill();
101     void Streams_Update();
102     void Streams_Finish();
103 
104     //Buffer - File header
FileHeader_Begin()105     bool FileHeader_Begin() {return FileHeader_Begin_0x000001();}
106 
107     void Bitrate_Calc();
108 
109     //Buffer - Synchro
110     bool Synchronize();
111     bool Synched_Test();
112     void Synched_Init();
113 
114     //Buffer - Global
115     void Read_Buffer_Init ();
116     #if MEDIAINFO_ADVANCED2
117     void Read_Buffer_SegmentChange();
118     #endif //MEDIAINFO_ADVANCED2
119     void Read_Buffer_Unsynched();
120     #if MEDIAINFO_SEEK
121     size_t Read_Buffer_Seek (size_t Method, int64u Value, int64u ID);
122     #endif //MEDIAINFO_SEEK
123     void Read_Buffer_Continue ();
124     void Read_Buffer_AfterParsing();
125 
126     //Buffer - Per element
127     void Header_Parse();
128     bool Header_Parse_Fill_Size();
129     bool Header_Parse_PES_packet(int8u stream_id);
130     void Header_Parse_PES_packet_MPEG1(int8u stream_id);
131     void Header_Parse_PES_packet_MPEG2(int8u stream_id);
132     void Data_Parse();
133     bool BookMark_Needed();
134 
135     //Packet
136     void MPEG_program_end();    //0xB9
137     void pack_start();          //0xBA
138     void system_header_start(); //0xBB
139     void program_stream_map();  //0xBC
140     void private_stream_1();    //0xBD
141     void padding_stream();      //0xBE
142     void private_stream_2();    //0xBF
143     void audio_stream();        //0xC0 --> 0xDF
144     void video_stream();        //0xE0 --> 0xEF
145     void SL_packetized_stream();//0xFA
146     void extension_stream();    //0xFD
147 
148     //private_stream_1 specific
149     bool           private_stream_1_Choose_DVD_ID();
150     File__Analyze* private_stream_1_ChooseParser();
151     const ZenLib::Char* private_stream_1_ChooseExtension();
152     #if MEDIAINFO_TRACE
153     void           private_stream_1_Element_Info1();
154     #endif //MEDIAINFO_TRACE
155     int8u          private_stream_1_ID;
156     size_t         private_stream_1_Offset;
157     bool           private_stream_1_IsDvdVideo;
158 
159     //private_stream_2 specific
160     void           private_stream_2_TSHV_A0();
161     void           private_stream_2_TSHV_A1();
162 
163     //extension_stream specific
164     const ZenLib::Char*  extension_stream_ChooseExtension();
165 
166     //Count
167     int8u video_stream_Count;
168     int8u audio_stream_Count;
169     int8u private_stream_1_Count;
170     int8u private_stream_2_Count;
171     int8u extension_stream_Count;
172     int8u SL_packetized_stream_Count;
173 
174     //From packets
175     int32u program_mux_rate;
176 
177     //PS
178     struct ps_stream : public stream_time
179     {
180         struct Mpeg_TimeStamp
181         {
182             struct Mpeg_TimeStamp_TS
183             {
184                 int64u File_Pos;
185                 int64u TimeStamp;
Resetps_stream::Mpeg_TimeStamp::Mpeg_TimeStamp_TS186                 void Reset()
187                 {
188                     File_Pos = (int64u)-1;
189                     TimeStamp = (int64u)-1;
190                 }
Mpeg_TimeStamp_TSps_stream::Mpeg_TimeStamp::Mpeg_TimeStamp_TS191                 Mpeg_TimeStamp_TS()
192                 {
193                     Reset();
194                 }
195             };
196 
197             Mpeg_TimeStamp_TS PTS;
198             Mpeg_TimeStamp_TS DTS;
199         };
200 
201         stream_t       StreamKind;
202         size_t         StreamPos;
203         size_t         Count; //TODO: in case there are different stream kinds
204         int8u          stream_type;
205         int32u         program_format_identifier;
206         int32u         format_identifier;
207         int8u          descriptor_tag;
208         int8u          DVD_Identifier;
209         std::vector<File__Analyze*> Parsers; //Sometimes, we need to do parallel tests
210         Mpeg_TimeStamp TimeStamp_Start;
211         Mpeg_TimeStamp TimeStamp_End;
212         size_t         StreamRegistration_Count;
213         size_t         StreamOrder;
214         size_t         FirstPacketOrder;
215         bool           IsFilled;
216 
Streams_Updateps_stream217         void Streams_Update()
218         {
219              for (size_t Pos = 0; Pos<Parsers.size(); Pos++)
220                   Parsers[Pos]->Open_Buffer_Update();
221         }
Set_Unsynch_Frame_Countps_stream222         void Set_Unsynch_Frame_Count(const int64u Count, const bool IsSub)
223         {
224             TimeStamp_End.PTS.Reset();
225             TimeStamp_End.DTS.Reset();
226             Searching_TimeStamp_Start = false;
227             for (size_t Pos = 0; Pos<Parsers.size(); Pos++)
228                 if (Parsers[Pos])
229                 {
230 #if MEDIAINFO_SEEK
231                     if(IsSub)
232                        Parsers[Pos]->Unsynch_Frame_Count = Count;
233 #endif //MEDIAINFO_SEEK
234                     Parsers[Pos]->Open_Buffer_Unsynch();
235                 }
236         }
ps_streamps_stream237         ps_stream()
238         {
239             StreamKind=Stream_Max;
240             StreamPos=0;
241             Count=0;
242             stream_type=0;
243             program_format_identifier=0x00000000; //No info
244             format_identifier=0x00000000; //No info
245             descriptor_tag=0x00; //No info
246             DVD_Identifier=0;
247             StreamRegistration_Count=0;
248             StreamOrder=(size_t)-1;
249             FirstPacketOrder=(size_t)-1;
250             Init_Stream(false);
251             IsFilled=false;
252         }
253 
~ps_streamps_stream254         ~ps_stream()
255         {
256             for (size_t Pos=0; Pos<Parsers.size(); Pos++)
257                 delete Parsers[Pos]; //Parsers[Pos]=NULL;
258         }
259     };
260     std::vector<ps_stream> Streams;
261     std::vector<ps_stream> Streams_Private1; //There can have multiple streams in one private stream
262     std::vector<ps_stream> Streams_Extension; //There can have multiple streams in one private stream
263     int8u stream_id;
264 
265     //Temp
266     int64u SizeToAnalyze; //Total size of a chunk to analyse, it may be changed by the parser
267     int8u  stream_id_extension;
268     bool   video_stream_Unlimited;
269     int16u Buffer_DataSizeToParse;
270     std::vector<int64u> video_stream_PTS;
271     size_t StreamOrder_CountOfPrivateStreams_Minus1;
272     size_t StreamOrder_CountOfPrivateStreams_Temp;
273     size_t FirstPacketOrder_Last;
274 
275     //Helpers
276     bool Header_Parser_QuickSearch();
277 
278     //Parsers
279     File__Analyze* ChooseParser_Mpegv();
280     File__Analyze* ChooseParser_Mpeg4v();
281     File__Analyze* ChooseParser_Avc();
282     File__Analyze* ChooseParser_Hevc();
283     File__Analyze* ChooseParser_VC1();
284     File__Analyze* ChooseParser_Dirac();
285     File__Analyze* ChooseParser_Mpega();
286     File__Analyze* ChooseParser_Mpegh3da();
287     File__Analyze* ChooseParser_Adts();
288     File__Analyze* ChooseParser_Latm();
289     File__Analyze* ChooseParser_AC3();
290     File__Analyze* ChooseParser_AC4();
291     File__Analyze* ChooseParser_DTS();
292     File__Analyze* ChooseParser_SDDS();
293     File__Analyze* ChooseParser_AAC();
294     File__Analyze* ChooseParser_PCM();
295     File__Analyze* ChooseParser_SmpteSt0302();
296     File__Analyze* ChooseParser_RLE();
297     File__Analyze* ChooseParser_AribStdB24B37(bool HasCcis=false);
298     File__Analyze* ChooseParser_DvbSubtitle();
299     File__Analyze* ChooseParser_PGS();
300     File__Analyze* ChooseParser_Teletext();
301     File__Analyze* ChooseParser_PS2();
302     File__Analyze* ChooseParser_NULL();
303 
304     //File__Analyze helpers
305     enum kindofstream
306     {
307         KindOfStream_Main,
308         KindOfStream_Private,
309         KindOfStream_Extension,
310     };
311     void Streams_Fill_PerStream(size_t StreamID, ps_stream &Temp, kindofstream KindOfStream);
312     void Streams_Fill_PerStream_PerKind(size_t StreamID, ps_stream &Temp, kindofstream KindOfStream, size_t Count);
313     void Streams_Finish_PerStream(size_t StreamID, ps_stream &Temp, kindofstream KindOfStream);
314     void xxx_stream_Parse(ps_stream &Temp, int8u &stream_Count);
315     void MergeGeneral(File__Analyze* Parser, general Parameter);
316 
317     //Output buffer
318     size_t Output_Buffer_Get (const String &Value);
319     size_t Output_Buffer_Get (size_t Pos);
320 
321     #if MEDIAINFO_SEEK
322         std::map<int16u, int64u>    Unsynch_Frame_Counts;
323         int64u                      Seek_Value;
324         int64u                      Seek_Value_Maximal;
325         int64u                      Seek_ID;
326         bool                        Duration_Detected;
327     #endif //MEDIAINFO_SEEK
328 };
329 
330 } //NameSpace
331 
332 #endif
333