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_SKM_YES)
21 //---------------------------------------------------------------------------
22 
23 //---------------------------------------------------------------------------
24 #include "MediaInfo/Multiple/File_Skm.h"
25 #if defined(MEDIAINFO_MPEG4V_YES)
26     #include "MediaInfo/Video/File_Mpeg4v.h"
27 #endif
28 #include "ZenLib/Utils.h"
29 //---------------------------------------------------------------------------
30 
31 namespace MediaInfoLib
32 {
33 
34 //***************************************************************************
35 // Constructor/Destructor
36 //***************************************************************************
37 
38 //---------------------------------------------------------------------------
File_Skm()39 File_Skm::File_Skm()
40 :File__Analyze()
41 {
42     //Configuration
43     MustSynchronize=true;
44 }
45 
46 //***************************************************************************
47 // Streams management
48 //***************************************************************************
49 
50 //---------------------------------------------------------------------------
Streams_Finish()51 void File_Skm::Streams_Finish()
52 {
53     if (Stream.Parser)
54     {
55         Finish(Stream.Parser);
56         Merge(*Stream.Parser);
57     }
58 }
59 
60 //***************************************************************************
61 // Buffer - File header
62 //***************************************************************************
63 
64 //---------------------------------------------------------------------------
FileHeader_Begin()65 bool File_Skm::FileHeader_Begin()
66 {
67     if (Buffer_Size<5)
68         return false;
69     if (CC5(Buffer)!=0x444D534B4DLL) //DMSKM
70     {
71         Reject("SKM");
72         return false;
73     }
74     return true;
75 }
76 
77 //---------------------------------------------------------------------------
FileHeader_Parse()78 void File_Skm::FileHeader_Parse()
79 {
80     Skip_C5(                                                    "Signature");
81 
82     FILLING_BEGIN();
83         Accept("SKM");
84 
85         Fill(Stream_General, 0, General_Format, "SKM");
86     FILLING_END();
87 }
88 
89 //***************************************************************************
90 // Buffer - Synchro
91 //***************************************************************************
92 
93 //---------------------------------------------------------------------------
Synched_Test()94 bool File_Skm::Synched_Test()
95 {
96     //Must have enough buffer for having header
97     if (Buffer_Offset+3>Buffer_Size)
98         return false;
99 
100     //Quick test of synchro
101     if (CC3(Buffer+Buffer_Offset)!=0x000001)
102         Synched=false;
103 
104     //We continue
105     return true;
106 }
107 
108 //***************************************************************************
109 // Buffer - Per element
110 //***************************************************************************
111 
112 //---------------------------------------------------------------------------
Header_Parse()113 void File_Skm::Header_Parse()
114 {
115     //Parsing
116     int32u BodyLength;
117     int8u Type;
118     Skip_B4(                                                    "PreviousTagSize");
119     if (File_Offset+Buffer_Offset+4<File_Size)
120     {
121         Get_B1 (Type,                                           "Type"); //Param_Info1(Type<19?Flv_Type[Type]:__T("Unknown"));
122         Get_B3 (BodyLength,                                     "BodyLength");
123         Skip_B3(                                                "Timestamp_Base"); //in ms
124         Skip_B1(                                                "Timestamp_Extended"); //TimeStamp = Timestamp_Extended*0x01000000+Timestamp_Base
125         Skip_B3(                                                "StreamID");
126     }
127     else
128     {
129         Type=0;
130         BodyLength=0;
131     }
132 
133     //Filling
134     Header_Fill_Code(Type, Ztring().From_Number(Type, 16));
135     Header_Fill_Size(Element_Offset+BodyLength);
136 }
137 
138 //---------------------------------------------------------------------------
Header_Parse_Fill_Size()139 bool File_Skm::Header_Parse_Fill_Size()
140 {
141     //Look for next Sync word
142     if (Buffer_Offset_Temp==0) //Buffer_Offset_Temp is not 0 if Header_Parse_Fill_Size() has already parsed first frames
143         Buffer_Offset_Temp=Buffer_Offset+4;
144     while (Buffer_Offset_Temp+4<=Buffer_Size
145         && CC3(Buffer+Buffer_Offset_Temp)!=0x000001)
146     {
147         Buffer_Offset_Temp+=2;
148         while(Buffer_Offset_Temp<Buffer_Size && Buffer[Buffer_Offset_Temp]!=0x00)
149             Buffer_Offset_Temp+=2;
150         if (Buffer[Buffer_Offset_Temp-1]==0x00)
151             Buffer_Offset_Temp--;
152     }
153 
154     //Must wait more data?
155     if (Buffer_Offset_Temp+4>Buffer_Size)
156     {
157         if (File_Offset+Buffer_Size==File_Size)
158             Buffer_Offset_Temp=Buffer_Size; //We are sure that the next bytes are a start
159         else
160             return false;
161     }
162 
163     //OK, we continue
164     Header_Fill_Size(Buffer_Offset_Temp-Buffer_Offset);
165     Buffer_Offset_Temp=0;
166     return true;
167 }
168 
169 //***************************************************************************
170 // Elements
171 //***************************************************************************
172 
173 //---------------------------------------------------------------------------
Data_Parse()174 void File_Skm::Data_Parse()
175 {
176     #if defined(MEDIAINFO_MPEG4V_YES)
177         Stream.Parser=new File_Mpeg4v();
178         Open_Buffer_Init(Stream.Parser);
179         ((File_Mpeg4v*)Stream.Parser)->FrameIsAlwaysComplete=true;
180         ((File_Mpeg4v*)Stream.Parser)->OnlyVOP();
181         Open_Buffer_Continue(Stream.Parser);
182         Finish("SKM");
183     #endif
184 }
185 
186 } //NameSpace
187 
188 #endif //MEDIAINFO_SKM_YES
189