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 #include "MediaInfo/File__Analyze.h"
21 #include "MediaInfo/MediaInfo_Config_MediaInfo.h"
22 #include "MediaInfo/MediaInfo_Config.h"
23 #include "MediaInfo/MediaInfo_Internal.h" //Only for XML escape. TODO: move XML escape function somewhere more generic
24 #if MEDIAINFO_IBIUSAGE && MEDIAINFO_SEEK
25 #include "MediaInfo/Multiple/File_Ibi.h"
26 #endif //MEDIAINFO_IBIUSAGE && MEDIAINFO_SEEK
27 #if MEDIAINFO_IBIUSAGE
28 #include "MediaInfo/Multiple/File_Ibi_Creation.h"
29 #endif //MEDIAINFO_IBIUSAGE
30 #include <cstring>
31 using namespace std;
32 using namespace tinyxml2;
33 #if MEDIAINFO_EVENTS
34 #include "MediaInfo/MediaInfo_Events_Internal.h"
35 #endif //MEDIAINFO_EVENTS
36 #ifdef MEDIAINFO_SSE2_YES
37 #ifndef ZENLIB_MEMUTILS_SSE2
38 #define ZENLIB_MEMUTILS_SSE2
39 #endif //ZENLIB_MEMUTILS_SSE2
40 #include "ZenLib/MemoryUtils.h"
41 #else //MEDIAINFO_SSE2_YES
42 #define memcpy_Unaligned_Unaligned std::memcpy
43 #define memcpy_Unaligned_Unaligned_Once1024 std::memcpy
44 #endif //MEDIAINFO_SSE2_YES
45 //---------------------------------------------------------------------------
46
47 namespace MediaInfoLib
48 {
49
50 //---------------------------------------------------------------------------
51 extern MediaInfo_Config Config;
52 //---------------------------------------------------------------------------
53
54 //***************************************************************************
55 // Info
56 //***************************************************************************
57
58 //---------------------------------------------------------------------------
59 extern const wchar_t ISO_6937_2_Tables[] = // ISO 6937-2 to Unicode
60 { // 0xC0-xCF (6937-2 diacritical marks) x 0x40-0x7F (ASCII letters)
61 // 0 1 2 3 4 5 6 7 8 9 A B C D E F
62 L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //4 //C0
63 L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //5
64 L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //6
65 L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //7
66 // 0 1 2 3 4 5 6 7 8 9 A B C D E F
67 L'\x0000', L'\x00C0', L'\x0000', L'\x0000', L'\x0000', L'\x00C8', L'\x0000', L'\x0000', L'\x0000', L'\x00CC', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x00D2', //4 //C1
68 L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x00D9', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //5
69 L'\x0000', L'\x00E0', L'\x0000', L'\x0000', L'\x0000', L'\x00E8', L'\x0000', L'\x0000', L'\x0000', L'\x00EC', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x00F2', //6
70 L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x00F9', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //7
71 // 0 1 2 3 4 5 6 7 8 9 A B C D E F
72 L'\x0000', L'\x00C1', L'\x0000', L'\x0106', L'\x0000', L'\x00C9', L'\x0000', L'\x0000', L'\x0000', L'\x00CD', L'\x0000', L'\x0000', L'\x0139', L'\x0000', L'\x0143', L'\x00D3', //4 //C2
73 L'\x0000', L'\x0000', L'\x0154', L'\x015A', L'\x0000', L'\x00DA', L'\x0000', L'\x0000', L'\x0000', L'\x00DD', L'\x0179', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //5
74 L'\x0000', L'\x00E1', L'\x0000', L'\x0107', L'\x0000', L'\x00E9', L'\x0000', L'\x0000', L'\x0000', L'\x00ED', L'\x0000', L'\x0000', L'\x013A', L'\x0000', L'\x0144', L'\x00F3', //6
75 L'\x0000', L'\x0155', L'\x015B', L'\x0000', L'\x0000', L'\x00FA', L'\x0000', L'\x0000', L'\x0000', L'\x00FD', L'\x017A', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //7
76 // 0 1 2 3 4 5 6 7 8 9 A B C D E F
77 L'\x0000', L'\x00C2', L'\x0000', L'\x0108', L'\x0000', L'\x00CA', L'\x0000', L'\x011C', L'\x0124', L'\x00CE', L'\x0134', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x00D4', //4 //C3
78 L'\x0000', L'\x0000', L'\x0000', L'\x015C', L'\x0000', L'\x00DB', L'\x0000', L'\x0174', L'\x0000', L'\x0176', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //5
79 L'\x0000', L'\x00E2', L'\x0000', L'\x0109', L'\x0000', L'\x00EA', L'\x0000', L'\x011D', L'\x0125', L'\x00EE', L'\x0135', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x00F4', //6
80 L'\x0000', L'\x0000', L'\x0000', L'\x015D', L'\x0000', L'\x00FB', L'\x0000', L'\x0175', L'\x0000', L'\x0177', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //7
81 // 0 1 2 3 4 5 6 7 8 9 A B C D E F
82 L'\x0000', L'\x00C3', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0128', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x00D1', L'\x00D5', //4 //C4
83 L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0168', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //5
84 L'\x0000', L'\x00E3', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0129', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x00F1', L'\x0000', //6
85 L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0169', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //7
86 // 0 1 2 3 4 5 6 7 8 9 A B C D E F
87 L'\x0000', L'\x0100', L'\x0000', L'\x0000', L'\x0000', L'\x0112', L'\x0000', L'\x0000', L'\x0000', L'\x012A', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //4 //C5
88 L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x016A', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //5
89 L'\x0000', L'\x0101', L'\x0000', L'\x0000', L'\x0000', L'\x0113', L'\x0000', L'\x0000', L'\x0000', L'\x012B', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x014D', //6
90 L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x016B', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //7
91 // 0 1 2 3 4 5 6 7 8 9 A B C D E F
92 L'\x0000', L'\x0102', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x011E', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //4 //C6
93 L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x016C', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //5
94 L'\x0000', L'\x0103', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x011F', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //6
95 L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x016D', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //7
96 // 0 1 2 3 4 5 6 7 8 9 A B C D E F
97 L'\x0000', L'\x0000', L'\x0000', L'\x010A', L'\x0000', L'\x0116', L'\x0000', L'\x0120', L'\x0000', L'\x0130', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //4 //C7
98 L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x017B', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //5
99 L'\x0000', L'\x0000', L'\x0000', L'\x010B', L'\x0000', L'\x0117', L'\x0000', L'\x0121', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //6
100 L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x017C', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //7
101 // 0 1 2 3 4 5 6 7 8 9 A B C D E F
102 L'\x0000', L'\x00C4', L'\x0000', L'\x0000', L'\x0000', L'\x00CB', L'\x0000', L'\x0000', L'\x0000', L'\x00CF', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x00D6', //4 //C8
103 L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x00DC', L'\x0000', L'\x0000', L'\x0000', L'\x0178', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //5
104 L'\x0000', L'\x00E4', L'\x0000', L'\x0000', L'\x0000', L'\x00EB', L'\x0000', L'\x0000', L'\x0000', L'\x00EF', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x00F6', //6
105 L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x00FC', L'\x0000', L'\x0000', L'\x0000', L'\x00FF', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //7
106 // 0 1 2 3 4 5 6 7 8 9 A B C D E F
107 L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //4 //C9
108 L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //5
109 L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //6
110 L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //7
111 // 0 1 2 3 4 5 6 7 8 9 A B C D E F
112 L'\x00C5', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //4 //CA
113 L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x016E', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //5
114 L'\x00E5', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //6
115 L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x016F', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //7
116 // 0 1 2 3 4 5 6 7 8 9 A B C D E F
117 L'\x0000', L'\x0000', L'\x0000', L'\x00C7', L'\x0000', L'\x0000', L'\x0000', L'\x0122', L'\x0000', L'\x0000', L'\x0000', L'\x0136', L'\x013B', L'\x0000', L'\x0145', L'\x0000', //4 //CB
118 L'\x0000', L'\x0000', L'\x0156', L'\x015E', L'\x0162', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //5
119 L'\x0000', L'\x0162', L'\x0000', L'\x00E7', L'\x0000', L'\x0000', L'\x0000', L'\x0123', L'\x0000', L'\x0000', L'\x0000', L'\x0137', L'\x013C', L'\x0000', L'\x0146', L'\x0000', //6
120 L'\x0000', L'\x0000', L'\x0157', L'\x015F', L'\x0163', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //7
121 // 0 1 2 3 4 5 6 7 8 9 A B C D E F
122 L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //4 //CC
123 L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //5
124 L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //6
125 L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //7
126 // 0 1 2 3 4 5 6 7 8 9 A B C D E F
127 L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0150', //4 //CD
128 L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0170', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //5
129 L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0151', //6
130 L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0171', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //7
131 // 0 1 2 3 4 5 6 7 8 9 A B C D E F
132 L'\x0104', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0118', L'\x0000', L'\x0000', L'\x0000', L'\x012E', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //4 //CE
133 L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0172', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //5
134 L'\x0105', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0119', L'\x0000', L'\x0000', L'\x0000', L'\x012F', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //6
135 L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0173', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //7
136 // 0 1 2 3 4 5 6 7 8 9 A B C D E F
137 L'\x0000', L'\x0000', L'\x0000', L'\x010C', L'\x010E', L'\x011A', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x013D', L'\x0000', L'\x0147', L'\x0000', //4 //CF
138 L'\x0000', L'\x0000', L'\x0158', L'\x0160', L'\x0164', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x017D', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //5
139 L'\x0000', L'\x0000', L'\x0000', L'\x010D', L'\x010F', L'\x011B', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x013E', L'\x0000', L'\x0148', L'\x0000', //6
140 L'\x0000', L'\x0000', L'\x0159', L'\x0161', L'\x0165', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x017E', L'\x0000', L'\x0000', L'\x0000', L'\x0000', L'\x0000', //7
141 };
142
143 //---------------------------------------------------------------------------
144 // Do not use int128::toString(), it is not thread-safe
uint128toString(uint128 ii,int radix)145 string uint128toString(uint128 ii, int radix)
146 {
147 if (!ii)
148 return string(1, '0');
149 if (radix < 2 || radix > 37)
150 return string();
151
152 char sz[256];
153 memset(sz, 0, 256);
154
155 uint128 r;
156 int i = 255;
157
158 while (!!ii && i) {
159 ii = ii.div(radix, r);
160 sz[--i] = (char)(r.toUint() + ((r.toUint() > 9) ? 'A' - 10 : '0'));
161 };
162
163 return string(&sz[i]);
164 }
165
166 //***************************************************************************
167 // Constructor/Destructor
168 //***************************************************************************
169
170 //---------------------------------------------------------------------------
File__Analyze()171 File__Analyze::File__Analyze ()
172 :File__Base()
173 {
174 //Info for speed optimization
175 #if MEDIAINFO_TRACE
176 Config_Trace_Level=MediaInfoLib::Config.Trace_Level_Get();
177 Config_Trace_Layers=MediaInfoLib::Config.Trace_Layers_Get();
178 Config_Trace_Format=MediaInfoLib::Config.Trace_Format_Get();
179 Trace_DoNotSave=false;
180 Trace_Layers.set();
181 Trace_Layers_Update();
182 #endif //MEDIAINFO_TRACE
183 Config_Demux=MediaInfoLib::Config.Demux_Get();
184 Config_LineSeparator=MediaInfoLib::Config.LineSeparator_Get();
185 IsSub=false;
186 StreamSource=IsContainer;
187
188 //In
189 #if MEDIAINFO_EVENTS
190 StreamIDs_Size=1;
191 ParserIDs[0]=0x0;
192 StreamIDs[0]=0;
193 StreamIDs_Width[0]=0;
194 #endif //MEDIAINFO_EVENTS
195 #if MEDIAINFO_DEMUX
196 Demux_Level=1; //Frame
197 Demux_random_access=false;
198 Demux_UnpacketizeContainer=false;
199 Demux_IntermediateItemFound=true;
200 Demux_Offset=0;
201 Demux_TotalBytes=0;
202 Demux_CurrentParser=NULL;
203 Demux_EventWasSent_Accept_Specific=false;
204 #endif //MEDIAINFO_DEMUX
205 PTS_DTS_Needed=false;
206 PTS_Begin=(int64u)-1;
207 #if MEDIAINFO_ADVANCED2
208 PTS_Begin_Segment=(int64u)-1;
209 #endif //MEDIAINFO_ADVANCED2
210 PTS_End=0;
211 DTS_Begin=(int64u)-1;
212 DTS_End=0;
213 Frequency_c=0;
214 Frequency_b=0;
215 #if MEDIAINFO_ADVANCED2
216 PTSb=NoTs;
217 DTSb=NoTs;
218 #endif //MEDIAINFO_ADVANCED2
219 Offsets_Pos=(size_t)-1;
220 OriginalBuffer=NULL;
221 OriginalBuffer_Size=0;
222 OriginalBuffer_Capacity=0;
223 #if defined(MEDIAINFO_EIA608_YES) || defined(MEDIAINFO_EIA708_YES)
224 ServiceDescriptors=NULL;
225 #endif
226 #if defined(MEDIAINFO_TELETEXT_YES)
227 Teletexts=NULL;
228 #endif
229
230 //Out
231 Frame_Count=0;
232 Frame_Count_Previous=0;
233 Frame_Count_InThisBlock=0;
234 Field_Count=0;
235 Field_Count_Previous=0;
236 Field_Count_InThisBlock=0;
237 Frame_Count_NotParsedIncluded=(int64u)-1;
238 FrameNumber_PresentationOrder=(int64u)-1;
239
240 //Configuration
241 DataMustAlwaysBeComplete=true;
242 MustUseAlternativeParser=false;
243 MustSynchronize=false;
244 CA_system_ID_MustSkipSlices=false;
245 FillAllMergedStreams=false;
246
247 //Buffer
248 #if MEDIAINFO_SEEK
249 Seek_Duration_Detected=false;
250 #endif //MEDIAINFO_SEEK
251 Buffer=NULL;
252 Buffer_Temp=NULL;
253 Buffer_Size=0;
254 Buffer_Temp_Size=0;
255 Buffer_Temp_Size_Max=0;
256 Buffer_Offset=0;
257 Buffer_Offset_Temp=0;
258 Buffer_MinimumSize=0;
259 Buffer_MaximumSize=16*1024*1024;
260 Buffer_TotalBytes_FirstSynched=0;
261 Buffer_TotalBytes_LastSynched=0;
262 Buffer_TotalBytes=0;
263 if (MediaInfoLib::Config.FormatDetection_MaximumOffset_Get())
264 Buffer_TotalBytes_FirstSynched_Max=MediaInfoLib::Config.FormatDetection_MaximumOffset_Get();
265 else
266 Buffer_TotalBytes_FirstSynched_Max=1024*1024;
267 if (Buffer_TotalBytes_FirstSynched_Max<(int64u)-1-64*1024*1024)
268 Buffer_TotalBytes_Fill_Max=Buffer_TotalBytes_FirstSynched_Max+64*1024*1024;
269 else
270 Buffer_TotalBytes_Fill_Max=(int64u)-1;
271 Buffer_PaddingBytes=0;
272 Buffer_JunkBytes=0;
273 Stream_BitRateFromContainer=0;
274
275 //Synchro
276 MustParseTheHeaderFile=true;
277 Synched=false;
278 UnSynched_IsNotJunk=false;
279 MustExtendParsingDuration=false;
280 Trusted=Error;
281 Trusted_Multiplier=1;
282
283 //Header
284 Header_Size=0;
285
286 //Elements
287 Element_WantNextLevel=false;
288
289 //Element
290 Element_Offset=0;
291 Element_Size=0;
292
293 //Elements
294 Element.resize(64);
295 Element[0].Code=0;
296 Element[0].Next=File_Size;
297 Element[0].WaitForMoreData=false;
298 Element[0].UnTrusted=false;
299 Element[0].IsComplete=false;
300 #if MEDIAINFO_TRACE
301 //TraceNode part
302 if (Config_Trace_Level!=0)
303 Element[0].TraceNode.Init();
304 #endif //MEDIAINFO_TRACE
305 Element_Level_Base=0;
306 Element_Level=0;
307
308 //BitStream
309 BS=new BitStream_Fast;
310 BT=new BitStream_LE;
311 #if MEDIAINFO_TRACE
312 BS_Size=0;
313 #endif //MEDIAINFO_TRACE
314
315 //Temp
316 Status[IsAccepted]=false;
317 Status[IsFilled]=false;
318 Status[IsUpdated]=false;
319 Status[IsFinished]=false;
320 ShouldContinueParsing=false;
321
322 //Events data
323 PES_FirstByte_IsAvailable=false;
324
325 //AES
326 #if MEDIAINFO_AES
327 AES=NULL;
328 AES_IV=NULL;
329 AES_Decrypted=NULL;
330 AES_Decrypted_Size=0;
331 #endif //MEDIAINFO_AES
332
333 //Hash
334 #if MEDIAINFO_HASH
335 Hash=NULL;
336 Hash_Offset=0;
337 Hash_ParseUpTo=0;
338 #endif //MEDIAINFO_HASH
339
340 Unsynch_Frame_Count=(int64u)-1;
341 #if MEDIAINFO_IBIUSAGE
342 Ibi_SynchronizationOffset_Current=0;
343 Ibi_SynchronizationOffset_BeginOfFrame=0;
344 #endif //MEDIAINFO_IBIUSAGE
345 #if MEDIAINFO_IBIUSAGE
346 Config_Ibi_Create=false;
347 IbiStream=NULL;
348 #endif //MEDIAINFO_IBIUSAGE
349 }
350
351 //---------------------------------------------------------------------------
~File__Analyze()352 File__Analyze::~File__Analyze ()
353 {
354 //Buffer
355 delete[] Buffer_Temp; //Buffer_Temp=NULL;
356 delete[] OriginalBuffer;
357
358 //BitStream
359 delete BS; //BS=NULL;
360 delete BT; //BS=NULL;
361
362 //AES
363 #if MEDIAINFO_AES
364 delete AES; //AES=NULL;
365 delete [] AES_IV; //AES_IV=NULL;
366 delete [] AES_Decrypted; //AES_Decrypted=NULL;
367 #endif //MEDIAINFO_AES
368
369 //Hash
370 #if MEDIAINFO_HASH
371 delete Hash; //Hash=NULL;
372 #endif //MEDIAINFO_HASH
373
374 #if MEDIAINFO_IBIUSAGE
375 if (!IsSub)
376 delete IbiStream; //IbiStream=NULL;
377 #endif //MEDIAINFO_IBIUSAGE
378 }
379
380 //***************************************************************************
381 // Open
382 //***************************************************************************
383
384 //---------------------------------------------------------------------------
Open_Buffer_Init(int64u File_Size_)385 void File__Analyze::Open_Buffer_Init (int64u File_Size_)
386 {
387 //Preparing
388 File_Size=File_Size_;
389 Element[0].Next=File_Size;
390
391 //Buffer - Global
392 Read_Buffer_Init();
393
394 //Integrity
395 if (File_Offset>File_Size)
396 {
397 Reject();
398 return; //There is a problem
399 }
400
401 //Jump handling
402 if (File_GoTo!=(int64u)-1)
403 {
404 Open_Buffer_Unsynch();
405 File_GoTo=(int64u)-1;
406 }
407
408 //Configuring
409 if (MediaInfoLib::Config.FormatDetection_MaximumOffset_Get())
410 Buffer_TotalBytes_FirstSynched_Max=MediaInfoLib::Config.FormatDetection_MaximumOffset_Get();
411 Config->File_ParseSpeed_Set(MediaInfoLib::Config.ParseSpeed_Get(), true);
412 EOF_AlreadyDetected=(Config->ParseSpeed>=1.0)?true:false;
413 if (Config->File_IsSub_Get())
414 IsSub=true;
415 #if MEDIAINFO_DEMUX
416 if (Demux_Level&1 && !IsSub && Config->Demux_Unpacketize_Get()) //If Demux_Level is Frame
417 {
418 if (!(Demux_Level&2)) // Special case when a stream is both container and stream: keep it
419 Demux_Level=2; //Container
420 Demux_UnpacketizeContainer=true;
421 }
422 #endif //MEDIAINFO_DEMUX
423 #if MEDIAINFO_EVENTS
424 if (StreamIDs_Size && StreamSource==IsStream)
425 StreamIDs[StreamIDs_Size-1]=(int64u)-1;
426 if (!IsSub)
427 {
428 ZtringListList SubFile_IDs;
429 SubFile_IDs.Separator_Set(0, EOL);
430 SubFile_IDs.Separator_Set(1, __T(","));
431 SubFile_IDs.Write(Config->SubFile_IDs_Get());
432 if (!SubFile_IDs.empty())
433 {
434 StreamIDs_Size=1+SubFile_IDs.size();
435 StreamIDs[SubFile_IDs.size()]=StreamSource==IsStream?(int64u)-1:StreamIDs[0];
436 StreamIDs_Width[SubFile_IDs.size()]=StreamIDs_Width[0];
437 ParserIDs[SubFile_IDs.size()]=ParserIDs[0];
438 for (size_t Pos=0; Pos<SubFile_IDs.size(); Pos++)
439 {
440 StreamIDs[Pos]=SubFile_IDs[Pos](0).To_int64u();
441 StreamIDs_Width[Pos]=SubFile_IDs[Pos](1).To_int8u();
442 ParserIDs[Pos]=SubFile_IDs[Pos](2).To_int8u();
443 }
444 }
445 }
446 #endif //MEDIAINFO_EVENTS
447 #if MEDIAINFO_IBIUSAGE
448 Config_Ibi_Create=Config->Ibi_Create_Get() && Config->ParseSpeed>=1.0;
449 if (Config_Ibi_Create && !IsSub && IbiStream==NULL)
450 IbiStream=new ibi::stream;
451 #endif //MEDIAINFO_IBIUSAGE
452 }
453
Open_Buffer_Init(File__Analyze * Sub)454 void File__Analyze::Open_Buffer_Init (File__Analyze* Sub)
455 {
456 Open_Buffer_Init(Sub, File_Size);
457 }
458
Open_Buffer_Init(File__Analyze * Sub,int64u File_Size_)459 void File__Analyze::Open_Buffer_Init (File__Analyze* Sub, int64u File_Size_)
460 {
461 //Integrity
462 if (Sub==NULL
463 #if MEDIAINFO_EVENTS
464 || StreamIDs_Size==0
465 #endif
466 )
467 return;
468
469 //Parsing
470 #if MEDIAINFO_TRACE
471 Sub->Init(Config, Details);
472 #else //MEDIAINFO_TRACE
473 Sub->Init(Config);
474 #endif //MEDIAINFO_TRACE
475 #if MEDIAINFO_EVENTS
476 Sub->ParserIDs[StreamIDs_Size]=Sub->ParserIDs[0];
477 Sub->StreamIDs_Width[StreamIDs_Size]=Sub->StreamIDs_Width[0];
478 for (size_t Pos=0; Pos<StreamIDs_Size; Pos++)
479 {
480 Sub->ParserIDs[Pos]=ParserIDs[Pos];
481 Sub->StreamIDs[Pos]=StreamIDs[Pos];
482 Sub->StreamIDs_Width[Pos]=StreamIDs_Width[Pos];
483 }
484 Sub->StreamIDs[StreamIDs_Size-1]=Element_Code;
485 Sub->StreamIDs_Size=StreamIDs_Size+1;
486 #endif //MEDIAINFO_EVENTS
487 Sub->IsSub=true;
488 Sub->File_Name_WithoutDemux=IsSub?File_Name_WithoutDemux:File_Name;
489 Sub->Open_Buffer_Init(File_Size_);
490 }
491
Open_Buffer_OutOfBand(File__Analyze * Sub,size_t Size)492 void File__Analyze::Open_Buffer_OutOfBand (File__Analyze* Sub, size_t Size)
493 {
494 if (Sub==NULL)
495 {
496 Skip_XX(Size, "Unknown");
497 return;
498 }
499
500 //Sub
501 if (Sub->File_GoTo!=(int64u)-1)
502 Sub->File_GoTo=(int64u)-1;
503 Sub->File_Offset=File_Offset+Buffer_Offset+Element_Offset;
504 if (Sub->File_Size!=File_Size)
505 {
506 for (size_t Pos=0; Pos<=Sub->Element_Level; Pos++)
507 if (Sub->Element[Pos].Next==Sub->File_Size)
508 Sub->Element[Pos].Next=File_Size;
509 Sub->File_Size=File_Size;
510 }
511 #if MEDIAINFO_TRACE
512 Sub->Element_Level_Base=Element_Level_Base+Element_Level;
513 #endif
514
515 #if MEDIAINFO_DEMUX
516 bool Demux_EventWasSent_Save=Config->Demux_EventWasSent;
517 Config->Demux_EventWasSent=false;
518 #endif //MEDIAINFO_DEMUX
519 Sub->Open_Buffer_OutOfBand(Buffer+Buffer_Offset+(size_t)Element_Offset, Size);
520 Element_Offset+=Size;
521 #if MEDIAINFO_DEMUX
522 if (Demux_EventWasSent_Save)
523 Config->Demux_EventWasSent=true;
524 #endif //MEDIAINFO_DEMUX
525
526 #if MEDIAINFO_TRACE
527 Trace_Details_Handling(Sub);
528 #endif // MEDIAINFO_TRACE
529 }
530 #if MEDIAINFO_TRACE
Trace_Details_Handling(File__Analyze * Sub)531 void File__Analyze::Trace_Details_Handling(File__Analyze* Sub)
532 {
533 if (Trace_Activated)
534 {
535 //Details handling
536 if ((!Sub->Element[0].TraceNode.Name_Is_Empty() || Sub->Element[Sub->Element_Level].TraceNode.Children.size()) && !Trace_DoNotSave)
537 {
538 //From Sub
539 if (!Sub->Element[0].TraceNode.Name_Is_Empty())
540 while (Sub->Element_Level)
541 Sub->Element_End0();
542
543 //Add Sub to this node
544 Element[Element_Level].TraceNode.Add_Child(&Sub->Element[Sub->Element_Level].TraceNode);
545 Sub->Element[Sub->Element_Level].TraceNode.Init();
546 }
547 else
548 Element[Element_Level].TraceNode.NoShow = true; //We don't want to show this item because there is no info in it
549 }
550 }
551 #endif // MEDIAINFO_TRACE
552 //---------------------------------------------------------------------------
Open_Buffer_Continue(const int8u * ToAdd,size_t ToAdd_Size)553 void File__Analyze::Open_Buffer_Continue (const int8u* ToAdd, size_t ToAdd_Size)
554 {
555 //Deleyed events
556 #if MEDIAINFO_DEMUX
557 if (Config->Events_Delayed_CurrentSource)
558 {
559 File__Analyze* Temp=Config->Events_Delayed_CurrentSource;
560 Config->Events_Delayed_CurrentSource=NULL;
561 Config->Event_Accepted(Temp);
562 if (Config->Events_Delayed_CurrentSource)
563 return;
564 }
565 #endif //MEDIAINFO_DEMUX
566
567 if (ToAdd_Size)
568 {
569 Frame_Count_InThisBlock=0;
570 Field_Count_InThisBlock=0;
571 }
572
573 //Hash
574 #if MEDIAINFO_HASH
575 if (ToAdd_Size)
576 {
577 if (!IsSub && !Buffer_Temp_Size && File_Offset==Config->File_Current_Offset && Config->File_Hash_Get().to_ulong())
578 {
579 delete Hash; Hash=new HashWrapper(Config->File_Hash_Get().to_ulong());
580 }
581 if (Hash)
582 {
583 if (File_Offset+Buffer_Size==Hash_Offset)
584 {
585 Hash->Update(ToAdd, ToAdd_Size);
586 Hash_Offset+=ToAdd_Size;
587 }
588 else if (Hash_Offset>File_Offset+Buffer_Size && Hash_Offset<File_Offset+Buffer_Size+ToAdd_Size)
589 {
590 size_t ToAdd_ToHashSize=(size_t)(File_Offset+Buffer_Size+ToAdd_Size-Hash_Offset);
591 Hash->Update(ToAdd+ToAdd_Size-ToAdd_ToHashSize, ToAdd_ToHashSize);
592 Hash_Offset+=ToAdd_ToHashSize;
593 }
594 }
595 }
596 #endif //MEDIAINFO_HASH
597
598 //AES
599 #if MEDIAINFO_AES
600 if (ToAdd_Size)
601 {
602 if (!IsSub && !Buffer_Temp_Size && File_Offset==Config->File_Current_Offset
603 && Config->Encryption_Format_Get()==Encryption_Format_Aes
604 && Config->Encryption_Key_Get().size()==16
605 && Config->Encryption_Method_Get()==Encryption_Method_Segment
606 && Config->Encryption_Mode_Get()==Encryption_Mode_Cbc
607 && Config->Encryption_Padding_Get()==Encryption_Padding_Pkcs7
608 && Config->Encryption_InitializationVector_Get()=="Sequence number")
609 {
610 delete AES; AES=new AESdecrypt;
611 AES->key128((const unsigned char*)Config->Encryption_Key_Get().c_str());
612 AES_IV=new int8u[16];
613 int128u2BigEndian(AES_IV, int128u((int64u)Config->File_Names_Pos-1));
614 }
615 if (AES)
616 {
617 if (AES_Decrypted_Size<ToAdd_Size)
618 {
619 delete [] AES_Decrypted; AES_Decrypted=new int8u[ToAdd_Size*2];
620 AES_Decrypted_Size=ToAdd_Size*2;
621 }
622 AES->cbc_decrypt(ToAdd, AES_Decrypted, (int)ToAdd_Size, AES_IV); //TODO: handle the case where ToAdd_Size is more than 2GB
623 if (File_Offset+Buffer_Size+ToAdd_Size>=Config->File_Current_Size)
624 {
625 int8u LastByte=AES_Decrypted[ToAdd_Size-1];
626 ToAdd_Size-=LastByte;
627 if (Config->File_Names_Pos && Config->File_Names_Pos-1<Config->File_Sizes.size())
628 Config->File_Sizes[Config->File_Names_Pos-1]-=LastByte;
629 Config->File_Current_Size-=LastByte;
630 }
631 ToAdd=AES_Decrypted;
632 }
633 }
634 #endif //MEDIAINFO_AES
635
636 #if MEDIAINFO_HASH
637 //Hash parsing only
638 if (Hash_ParseUpTo>File_Offset+Buffer_Size+ToAdd_Size)
639 {
640 File_Offset+=ToAdd_Size;
641 return; //No need of this piece of data
642 }
643 if (Hash_ParseUpTo>=File_Offset && Hash_ParseUpTo<=File_Offset+ToAdd_Size)
644 {
645 Buffer_Offset+=(size_t)(Hash_ParseUpTo-File_Offset);
646 Hash_ParseUpTo=0;
647 }
648 #endif //MEDIAINFO_HASH
649
650 //Integrity
651 if (Status[IsFinished])
652 return;
653 //{File F; F.Open(Ztring(__T("d:\\direct"))+Ztring::ToZtring((size_t)this, 16), File::Access_Write_Append); F.Write(ToAdd, ToAdd_Size);}
654
655 //Demand to go elsewhere
656 if (File_GoTo!=(int64u)-1)
657 {
658 if (File_GoTo<File_Offset)
659 return; //Seek must be done before
660 if (File_GoTo>=File_Offset+ToAdd_Size)
661 {
662 File_Offset+=ToAdd_Size;
663 return; //No need of this piece of data
664 }
665 }
666
667 if (Buffer_Temp_Size) //There is buffered data from before
668 {
669 //Allocating new buffer if needed
670 if (Buffer_Temp_Size+ToAdd_Size>Buffer_Temp_Size_Max)
671 {
672 int8u* Old=Buffer_Temp;
673 size_t Buffer_Temp_Size_Max_ToAdd=ToAdd_Size>32768?ToAdd_Size:32768;
674 if (Buffer_Temp_Size_Max_ToAdd<Buffer_Temp_Size_Max) Buffer_Temp_Size_Max_ToAdd=Buffer_Temp_Size_Max;
675 Buffer_Temp_Size_Max+=Buffer_Temp_Size_Max_ToAdd;
676 Buffer_Temp=new int8u[Buffer_Temp_Size_Max];
677 memcpy_Unaligned_Unaligned(Buffer_Temp, Old, Buffer_Temp_Size);
678 delete[] Old; //Old=NULL;
679 }
680
681 //Copying buffer
682 if (ToAdd_Size>0)
683 {
684 memcpy_Unaligned_Unaligned(Buffer_Temp+Buffer_Size, ToAdd, ToAdd_Size);
685 Buffer_Temp_Size+=ToAdd_Size;
686 }
687
688 //Buffer
689 Buffer=Buffer_Temp;
690 Buffer_Size=Buffer_Temp_Size;
691 }
692 else
693 {
694 Buffer=ToAdd;
695 Buffer_Size=ToAdd_Size;
696 }
697
698 //Preparing
699 Trusted=(Buffer_Size>2*8*1024?Buffer_Size/8/1024:2)*Trusted_Multiplier; //Never less than 2 acceptable errors
700 if (!MustSynchronize)
701 Element[Element_Level].UnTrusted=false;
702
703 //Demand to go elsewhere
704 if (File_GoTo!=(int64u)-1)
705 {
706 //The needed offset is in the new buffer
707 Buffer_Offset+=(size_t)(File_GoTo-File_Offset);
708 File_GoTo=(int64u)-1;
709 }
710
711 //Parsing
712 if (!IsSub)
713 {
714 if (Config->File_Size && Config->File_Size!=(int64u)-1)
715 Config->State_Set(((float)Buffer_TotalBytes)/Config->File_Size);
716 else if (Config->File_Names.size()>1)
717 Config->State_Set(((float)Config->File_Names_Pos)/Config->File_Names.size());
718 }
719 if (Buffer_Size>=Buffer_MinimumSize || File_Offset+Buffer_Size==File_Size) //Parsing only if we have enough buffer
720 while (Open_Buffer_Continue_Loop());
721
722 //Hash
723 #if MEDIAINFO_HASH
724 if (Hash_ParseUpTo>File_Size)
725 Hash_ParseUpTo=File_Size;
726
727 if (Hash && Hash_Offset>=Config->File_Current_Size && Status[IsAccepted])
728 {
729 for (size_t Hash_Pos=0; Hash_Pos<HashWrapper::HashFunction_Max; ++Hash_Pos)
730 {
731 string Hash_Name(HashWrapper::Name((HashWrapper::HashFunction)Hash_Pos));
732 Ztring Temp;
733 Temp.From_UTF8(Hash->Generate((HashWrapper::HashFunction)Hash_Pos));
734 string HashPos=Config->File_Names.size()>1?("Source_List_"+Hash_Name+"_Generated"):(Hash_Name+"_Generated");
735 if (Config->File_Names_Pos<=1 && !Retrieve(Stream_General, 0, HashPos.c_str()).empty() && Retrieve(Stream_General, 0, HashPos.c_str())==Temp)
736 Clear(Stream_General, 0, HashPos.c_str());
737 Fill(Stream_General, 0, HashPos.c_str(), Temp);
738 if (Config->File_Names_Pos<=1)
739 Fill_SetOptions(Stream_General, 0, HashPos.c_str(), "N NT");
740 }
741
742 delete Hash; Hash=NULL;
743 }
744
745 if (Hash && Buffer_Offset>=Buffer_Size && Hash_Offset>File_Offset+Buffer_Size && Buffer_Offset<Buffer_Size+16*1024*1024)
746 {
747 //We need the next data
748 Hash_ParseUpTo=File_Offset+Buffer_Offset;
749 Buffer_Offset=Buffer_Size;
750 }
751 else if (Hash && File_GoTo>Hash_Offset && File_GoTo<Hash_Offset + 16 * 1024 * 1024)
752 {
753 //We need the next data
754 Hash_ParseUpTo=File_GoTo;
755 File_GoTo=Hash_Offset;
756 }
757 #endif //MEDIAINFO_HASH
758
759 //Should parse again?
760 if (((File_GoTo==File_Size && File_Size!=(int64u)-1) || (File_GoTo==(int64u)-1 && File_Offset+Buffer_Offset>=File_Size))
761 && !Config->File_IsGrowing
762 #if MEDIAINFO_DEMUX
763 && !Config->Demux_EventWasSent
764 #endif //MEDIAINFO_DEMUX
765 )
766 {
767 BookMark_Get();
768 }
769
770 //Demand to go elsewhere
771 if (File_GoTo!=(int64u)-1)
772 {
773 if (Config->File_IsSeekable_Get())
774 {
775 if (File_GoTo>=File_Size)
776 File_GoTo=File_Size;
777 Buffer_Clear();
778 }
779 else
780 File_Offset+=Buffer_Offset;
781
782 return;
783 }
784 #if MEDIAINFO_HASH
785 if (Hash_ParseUpTo)
786 {
787 Buffer_Clear();
788 return;
789 }
790 #endif //MEDIAINFO_HASH
791 if (Buffer_Offset>=Buffer_Size
792 #if MEDIAINFO_HASH
793 && Hash==NULL
794 #endif //MEDIAINFO_HASH
795 )
796 {
797 if (Buffer_Offset>Buffer_Size)
798 File_GoTo=File_Offset+Buffer_Offset;
799 Buffer_Clear();
800 return;
801 }
802
803 //Buffer handling
804 if (Buffer_Size && Buffer_Offset<=Buffer_Size) //all is not used
805 {
806 if (Buffer_Temp_Size==0) //If there was no copy
807 {
808 #if MEDIAINFO_DEMUX
809 if (!IsSub && Config->Demux_EventWasSent && Config->File_Buffer_Repeat_IsSupported && Buffer_Offset==0) //If there was no byte consumed
810 {
811 Config->File_Buffer_Repeat=true;
812 }
813 else
814 #endif //MEDIAINFO_DEMUX
815 {
816 if (Buffer_Temp!=NULL && Buffer_Temp_Size_Max<Buffer_Size-Buffer_Offset)
817 {
818 delete[] Buffer_Temp; Buffer_Temp=NULL; Buffer_Temp_Size=0; Buffer_Temp_Size_Max=0;
819 }
820 if (Buffer_Temp==NULL)
821 {
822 size_t Buffer_Temp_Size_Max_ToAdd=Buffer_Size-Buffer_Offset>32768?Buffer_Size-Buffer_Offset:32768;
823 if (Buffer_Temp_Size_Max_ToAdd<Buffer_Temp_Size_Max) Buffer_Temp_Size_Max_ToAdd=Buffer_Temp_Size_Max;
824 Buffer_Temp_Size_Max=Buffer_Temp_Size_Max_ToAdd;
825 Buffer_Temp=new int8u[Buffer_Temp_Size_Max];
826 }
827 Buffer_Temp_Size=Buffer_Size-Buffer_Offset;
828 memcpy_Unaligned_Unaligned(Buffer_Temp, Buffer+Buffer_Offset, Buffer_Temp_Size);
829 }
830 }
831 else if (Buffer_Offset) //Already a copy, just moving it
832 {
833 std::memmove(Buffer_Temp, Buffer_Temp+Buffer_Offset, Buffer_Size-Buffer_Offset);
834 Buffer_Temp_Size=Buffer_Size-Buffer_Offset;
835 }
836 }
837 else if (Buffer_Temp_Size)
838 Buffer_Temp_Size=0;
839
840 //Reserving unused data
841 if ((int64u)-1-Buffer_Offset<File_Offset) //In case of unknown filesize, File_Offset may be (int64u)-1
842 Buffer_Offset=(size_t)((int64u)-1-File_Offset);
843 if (Buffer_Offset)
844 {
845 if (Buffer_Offset>=FrameInfo.Buffer_Offset_End && FrameInfo_Next.DTS!=(int64u)-1)
846 {
847 FrameInfo=FrameInfo_Next;
848 FrameInfo_Next=frame_info();
849 }
850
851 float64 Ratio=1;
852 if (OriginalBuffer)
853 {
854 Ratio=((float64)OriginalBuffer_Size)/Buffer_Size;
855 size_t Temp_Size=(size_t)float64_int64s(((float64)Buffer_Offset)*Ratio);
856
857 OriginalBuffer_Size-=Temp_Size;
858 memmove(OriginalBuffer, OriginalBuffer+Buffer_Offset, OriginalBuffer_Size);
859 }
860
861 Buffer_Size-=Buffer_Offset;
862 File_Offset+=Buffer_Offset;
863 if (Buffer_Offset_Temp>=Buffer_Offset)
864 Buffer_Offset_Temp-=Buffer_Offset;
865 if (FrameInfo.Buffer_Offset_End!=(int64u)-1 && FrameInfo.Buffer_Offset_End>=Buffer_Offset)
866 FrameInfo.Buffer_Offset_End-=Buffer_Offset;
867 if (FrameInfo_Next.Buffer_Offset_End!=(int64u)-1 && FrameInfo_Next.Buffer_Offset_End>=Buffer_Offset)
868 FrameInfo_Next.Buffer_Offset_End-=Buffer_Offset;
869 if (!Offsets_Buffer.empty())
870 {
871 if (Offsets_Buffer.size()>=2 && Offsets_Buffer.size()%2==0 && Offsets_Buffer[0]==Offsets_Buffer[1])
872 {
873 size_t Pos=Offsets_Buffer.size()-2;
874 do
875 {
876 if (Offsets_Buffer[Pos]>Buffer_Offset)
877 {
878 Offsets_Buffer[Pos]-=Buffer_Offset;
879 Offsets_Buffer[Pos+1]-=Buffer_Offset;
880 }
881 else
882 {
883 Offsets_Stream[Pos]+=float64_int64s(Buffer_Offset*Ratio/2)-Offsets_Buffer[Pos];
884 Offsets_Stream[Pos+1]+=float64_int64s(Buffer_Offset*Ratio/2)-Offsets_Buffer[Pos+1];
885 Offsets_Buffer[Pos]=0;
886 Offsets_Buffer[Pos+1]=0;
887 Offsets_Buffer.erase(Offsets_Buffer.begin(), Offsets_Buffer.begin()+Pos);
888 Offsets_Stream.erase(Offsets_Stream.begin(), Offsets_Stream.begin()+Pos);
889 if (Offsets_Pos!=(size_t)-1 && Pos)
890 {
891 if (Pos<Offsets_Pos)
892 Offsets_Pos-=Pos;
893 else
894 Offsets_Pos=0;
895 }
896 break;
897 }
898 if (Pos==0)
899 break;
900 Pos-=2;
901 }
902 while (Pos);
903 }
904 else
905 {
906 size_t Pos=Offsets_Buffer.size()-1;
907 do
908 {
909 if (Offsets_Buffer[Pos]>Buffer_Offset*Ratio)
910 Offsets_Buffer[Pos]-=float64_int64s(Buffer_Offset*Ratio);
911 else
912 {
913 Offsets_Stream[Pos]+=float64_int64s(Buffer_Offset*Ratio)-Offsets_Buffer[Pos];
914 Offsets_Buffer[Pos]=0;
915 Offsets_Buffer.erase(Offsets_Buffer.begin(), Offsets_Buffer.begin()+Pos);
916 Offsets_Stream.erase(Offsets_Stream.begin(), Offsets_Stream.begin()+Pos);
917 if (Offsets_Pos!=(size_t)-1 && Pos)
918 {
919 if (Pos<Offsets_Pos)
920 Offsets_Pos-=Pos;
921 else
922 Offsets_Pos=0;
923 }
924 break;
925 }
926 if (Pos==0)
927 break;
928 Pos--;
929 }
930 while (Pos);
931 }
932 }
933
934 Buffer_Offset=0;
935 }
936
937 //Is it OK?
938 if (Buffer_Size>Buffer_MaximumSize)
939 {
940 #if MEDIAINFO_HASH
941 if (Config->File_Hash_Get().to_ulong() && Hash && Status[IsAccepted])
942 {
943 Buffer_Clear();
944 Hash_ParseUpTo=File_Size;
945 }
946 else
947 #endif //MEDIAINFO_HASH
948 ForceFinish();
949 return;
950 }
951 }
952
Open_Buffer_Continue(File__Analyze * Sub,const int8u * ToAdd,size_t ToAdd_Size,bool IsNewPacket,float64 Ratio)953 void File__Analyze::Open_Buffer_Continue (File__Analyze* Sub, const int8u* ToAdd, size_t ToAdd_Size, bool IsNewPacket, float64 Ratio)
954 {
955 if (Sub==NULL)
956 return;
957
958 //Sub
959 if (Sub->File_GoTo!=(int64u)-1)
960 Sub->File_GoTo=(int64u)-1;
961 Sub->File_Offset=File_Offset+Buffer_Offset+Element_Offset;
962 if (Sub->File_Size!=File_Size)
963 {
964 for (size_t Pos=0; Pos<=Sub->Element_Level; Pos++)
965 if (Sub->Element[Pos].Next==Sub->File_Size)
966 Sub->Element[Pos].Next=File_Size;
967 Sub->File_Size=File_Size;
968 }
969 Sub->Element[0].IsComplete=Element[Element_Level].IsComplete;
970 #if MEDIAINFO_TRACE
971 Sub->Element_Level_Base=Element_Level_Base+Element_Level;
972 #endif
973
974 //{File F; F.Open(Ztring(__T("d:\\direct"))+Ztring::ToZtring((size_t)this, 16), File::Access_Write_Append); F.Write(ToAdd, ToAdd_Size);}
975
976 //Adaptating File_Offset
977 if (Sub!=this && Sub->Buffer_Size<=Sub->File_Offset)
978 Sub->File_Offset-=Sub->Buffer_Size;
979
980 //Parsing
981 Sub->PES_FirstByte_IsAvailable=PES_FirstByte_IsAvailable;
982 Sub->PES_FirstByte_Value=PES_FirstByte_Value;
983 if (IsNewPacket && ToAdd_Size)
984 {
985 if (Offsets_Stream.empty())
986 {
987 Sub->Offsets_Stream.push_back(File_Offset+float64_int64s((Buffer_Offset+Element_Offset)*Ratio));
988 Sub->Offsets_Buffer.push_back(Sub->Buffer_Size);
989 }
990 else
991 {
992 if (Offsets_Buffer[0]>=Buffer_Offset-Header_Size && (Sub->Offsets_Stream.empty() || Sub->Offsets_Stream[Sub->Offsets_Stream.size()-1]+Sub->Buffer_Size-Sub->Offsets_Buffer[Sub->Offsets_Stream.size()-1]!=Offsets_Stream[0]))
993 {
994 if ((Buffer_Offset-Header_Size)*Ratio<Offsets_Buffer[0])
995 {
996 Sub->Offsets_Stream.push_back(Offsets_Stream[0]);
997 Sub->Offsets_Buffer.push_back((Sub->OriginalBuffer_Size?Sub->OriginalBuffer_Size:Sub->Buffer_Size)+Offsets_Buffer[0]-(Buffer_Offset+Element_Offset));
998 }
999 else
1000 {
1001 Sub->Offsets_Stream.push_back(Offsets_Stream[0]+Buffer_Offset+Element_Offset-Offsets_Buffer[0]);
1002 Sub->Offsets_Buffer.push_back(Sub->OriginalBuffer_Size?Sub->OriginalBuffer_Size:Sub->Buffer_Size);
1003 }
1004 }
1005 for (size_t Pos=1; Pos<Offsets_Stream.size(); Pos++)
1006 if (Offsets_Buffer[Pos]>=Buffer_Offset+Element_Offset && Offsets_Buffer[Pos]<Buffer_Offset+Element_Size)
1007 {
1008 if ((Buffer_Offset-Header_Size)*Ratio<Offsets_Buffer[Pos])
1009 {
1010 Sub->Offsets_Stream.push_back(Offsets_Stream[Pos]);
1011 Sub->Offsets_Buffer.push_back((Sub->OriginalBuffer_Size?Sub->OriginalBuffer_Size:Sub->Buffer_Size)+Offsets_Buffer[Pos]-(Buffer_Offset+Element_Offset));
1012 }
1013 else
1014 {
1015 Sub->Offsets_Stream.push_back(Offsets_Stream[Pos]+Buffer_Offset+Element_Offset-Offsets_Buffer[Pos]);
1016 Sub->Offsets_Buffer.push_back(Sub->OriginalBuffer_Size?Sub->OriginalBuffer_Size:Sub->Buffer_Size);
1017 }
1018 }
1019 }
1020 }
1021
1022 if (Ratio!=1)
1023 {
1024 if (Sub->OriginalBuffer_Size+Element_Size-Element_Offset>Sub->OriginalBuffer_Capacity)
1025 {
1026 int8u* Temp=Sub->OriginalBuffer;
1027 Sub->OriginalBuffer_Capacity=(size_t)(Sub->OriginalBuffer_Size+Element_Size-Element_Offset);
1028 Sub->OriginalBuffer=new int8u[Sub->OriginalBuffer_Capacity];
1029 memcpy_Unaligned_Unaligned(Sub->OriginalBuffer, Temp, Sub->OriginalBuffer_Size);
1030 delete[] Temp;
1031 }
1032 memcpy_Unaligned_Unaligned(Sub->OriginalBuffer+Sub->OriginalBuffer_Size, Buffer+Buffer_Offset+(size_t)Element_Offset, (size_t)(Element_Size-Element_Offset));
1033 Sub->OriginalBuffer_Size+=(size_t)(Element_Size-Element_Offset);
1034 }
1035
1036 #if MEDIAINFO_ADVANCED2
1037 if (Frequency_c)
1038 Sub->Frequency_c=Frequency_c;
1039 #endif //MEDIAINFO_ADVANCED2
1040 if (Sub->FrameInfo.DTS!=(int64u)-1 || Sub->FrameInfo.PTS!=(int64u)-1)
1041 Sub->FrameInfo.Buffer_Offset_End=Sub->Buffer_Offset+Sub->Buffer_Size+ToAdd_Size;
1042 else if (Sub->FrameInfo_Previous.DTS!=(int64u)-1 || Sub->FrameInfo_Previous.PTS!=(int64u)-1)
1043 Sub->FrameInfo_Previous.Buffer_Offset_End=Sub->Buffer_Offset+Sub->Buffer_Size+ToAdd_Size;
1044 if (Sub->FrameInfo_Previous.DTS!=(int64u)-1)
1045 {
1046 Sub->FrameInfo_Next=Sub->FrameInfo;
1047 Sub->FrameInfo=Sub->FrameInfo_Previous;
1048 Sub->FrameInfo_Previous=frame_info();
1049
1050 Sub->Frame_Count_Previous=Sub->Frame_Count;
1051 Sub->Field_Count_Previous=Sub->Field_Count;
1052 }
1053 if (Frame_Count_NotParsedIncluded!=(int64u)-1)
1054 Sub->Frame_Count_NotParsedIncluded=Frame_Count_NotParsedIncluded;
1055 #if MEDIAINFO_DEMUX
1056 bool Demux_EventWasSent_Save=Config->Demux_EventWasSent;
1057 Config->Demux_EventWasSent=false;
1058 #endif //MEDIAINFO_DEMUX
1059 Sub->Open_Buffer_Continue(ToAdd, ToAdd_Size);
1060 #if MEDIAINFO_DEMUX
1061 if (Demux_EventWasSent_Save)
1062 Config->Demux_EventWasSent=true;
1063 #endif //MEDIAINFO_DEMUX
1064 if (Sub->Buffer_Size)
1065 {
1066 Sub->FrameInfo_Previous=Sub->FrameInfo;
1067 Sub->FrameInfo=Sub->FrameInfo_Next;
1068 Sub->FrameInfo_Next=frame_info();
1069 }
1070
1071 #if MEDIAINFO_TRACE
1072 Trace_Details_Handling(Sub);
1073 #endif //MEDIAINFO_TRACE
1074 }
1075
1076 //---------------------------------------------------------------------------
Open_Buffer_Continue_Loop()1077 bool File__Analyze::Open_Buffer_Continue_Loop ()
1078 {
1079 //Header
1080 if (MustParseTheHeaderFile)
1081 {
1082 if (!FileHeader_Manage())
1083 return false; //Wait for more data
1084 if (Status[IsFinished] || File_GoTo!=(int64u)-1)
1085 return false; //Finish
1086 }
1087
1088 //Parsing specific
1089 Element_Offset=0;
1090 Element_Size=Buffer_Size;
1091 Element[Element_Level].WaitForMoreData=false;
1092 Read_Buffer_Continue();
1093 if (Element_IsWaitingForMoreData())
1094 {
1095 Buffer_TotalBytes+=Buffer_Offset;
1096 return false; //Wait for more data
1097 }
1098 if (sizeof(size_t)<sizeof(int64u) && Buffer_Offset+Element_Offset>=(int64u)(size_t)-1)
1099 GoTo(File_Offset+Buffer_Offset+Element_Offset);
1100 else
1101 Buffer_Offset+=(size_t)Element_Offset;
1102 if ((Status[IsFinished] && !ShouldContinueParsing) || Buffer_Offset>Buffer_Size || File_GoTo!=(int64u)-1)
1103 {
1104 Buffer_TotalBytes+=Buffer_Offset;
1105 return false; //Finish
1106 }
1107 #if MEDIAINFO_DEMUX
1108 if (Config->Demux_EventWasSent)
1109 {
1110 Buffer_TotalBytes+=Buffer_Offset;
1111 return false;
1112 }
1113 #endif //MEDIAINFO_DEMUX
1114
1115 //Parsing;
1116 while (Buffer_Offset<Buffer_Size)
1117 if (!Buffer_Parse())
1118 break;
1119 Buffer_TotalBytes+=Buffer_Offset;
1120
1121 //Handling of File_GoTo with already buffered data
1122 #if MEDIAINFO_HASH
1123 if (File_GoTo==(int64u)-1 && Hash_ParseUpTo && Hash_ParseUpTo>=File_Offset && Hash_ParseUpTo<File_Offset+Buffer_Size)
1124 {
1125 File_GoTo=Hash_ParseUpTo;
1126 Hash_ParseUpTo=0;
1127 }
1128 #endif //MEDIAINFO_HASH
1129 if (File_GoTo!=(int64u)-1 && File_GoTo>=File_Offset && File_GoTo<File_Offset+Buffer_Size)
1130 {
1131 if (Buffer_Temp_Size==0) //If there was no copy
1132 {
1133 Buffer_Temp_Size=(size_t)(File_Offset+Buffer_Size-File_GoTo);
1134 if (Buffer_Temp!=NULL && Buffer_Temp_Size_Max<Buffer_Temp_Size)
1135 {
1136 delete[] Buffer_Temp; Buffer_Temp=NULL; Buffer_Temp_Size=0; Buffer_Temp_Size_Max=0;
1137 }
1138 if (Buffer_Temp==NULL)
1139 {
1140 size_t Buffer_Temp_Size_Max_ToAdd=Buffer_Temp_Size>32768?Buffer_Temp_Size:32768;
1141 if (Buffer_Temp_Size_Max_ToAdd<Buffer_Temp_Size_Max) Buffer_Temp_Size_Max_ToAdd=Buffer_Temp_Size_Max;
1142 Buffer_Temp_Size_Max=Buffer_Temp_Size_Max_ToAdd;
1143 Buffer_Temp=new int8u[Buffer_Temp_Size_Max];
1144 }
1145 memcpy_Unaligned_Unaligned(Buffer_Temp, Buffer+Buffer_Size-Buffer_Temp_Size, Buffer_Temp_Size);
1146 }
1147 else //Already a copy, just moving it
1148 {
1149 Buffer_Temp_Size=(size_t)(File_Offset+Buffer_Size-File_GoTo);
1150 std::memmove(Buffer_Temp, Buffer+Buffer_Size-Buffer_Temp_Size, Buffer_Temp_Size);
1151 }
1152 File_Offset+=Buffer_Size-Buffer_Temp_Size;
1153 Buffer=Buffer_Temp;
1154 Buffer_Offset=0;
1155 Buffer_Size=Buffer_Temp_Size;
1156 File_GoTo=(int64u)-1;
1157
1158 #if MEDIAINFO_DEMUX
1159 if (Config->Demux_EventWasSent)
1160 return false;
1161 #endif //MEDIAINFO_DEMUX
1162
1163 return true;
1164 }
1165
1166 #if MEDIAINFO_DEMUX
1167 if (Config->Demux_EventWasSent)
1168 return false;
1169 #endif //MEDIAINFO_DEMUX
1170
1171 //Parsing specific
1172 Read_Buffer_AfterParsing();
1173
1174 //Jumping to the end of the file if needed
1175 if (!IsSub && !EOF_AlreadyDetected && Config->ParseSpeed<1 && Count_Get(Stream_General))
1176 {
1177 Element[Element_Level].WaitForMoreData=false;
1178 Detect_EOF();
1179 if ((File_GoTo!=(int64u)-1 && File_GoTo>File_Offset+Buffer_Offset) || (Status[IsFinished] && !ShouldContinueParsing))
1180 {
1181 EOF_AlreadyDetected=true;
1182 return false;
1183 }
1184 }
1185
1186 return false;
1187 }
1188
1189 //---------------------------------------------------------------------------
1190 #if MEDIAINFO_SEEK
Open_Buffer_Seek(size_t Method,int64u Value,int64u ID)1191 size_t File__Analyze::Open_Buffer_Seek (size_t Method, int64u Value, int64u ID)
1192 {
1193 #if MEDIAINFO_DEMUX
1194 Config->Demux_EventWasSent=false;
1195 #endif //MEDIAINFO_DEMUX
1196
1197 size_t ToReturn=Read_Buffer_Seek(Method, Value, ID);
1198
1199 if (File_GoTo!=(int64u)-1)
1200 Buffer_Clear();
1201
1202 return ToReturn;
1203 }
1204 #endif //MEDIAINFO_SEEK
1205
1206 //---------------------------------------------------------------------------
Open_Buffer_Position_Set(int64u File_Offset_)1207 void File__Analyze::Open_Buffer_Position_Set (int64u File_Offset_)
1208 {
1209 if (File_Offset_==(int64u)-1)
1210 return;
1211
1212 File_Offset=File_Offset_-Buffer_Temp_Size;
1213 File_GoTo=(int64u)-1;
1214 }
1215
1216 //---------------------------------------------------------------------------
Open_Buffer_CheckFileModifications()1217 void File__Analyze::Open_Buffer_CheckFileModifications()
1218 {
1219 Read_Buffer_CheckFileModifications();
1220 }
1221
1222 //---------------------------------------------------------------------------
1223 #if MEDIAINFO_ADVANCED2
Open_Buffer_SegmentChange()1224 void File__Analyze::Open_Buffer_SegmentChange ()
1225 {
1226 Read_Buffer_SegmentChange();
1227 }
1228 #endif //MEDIAINFO_ADVANCED2
1229
1230 //---------------------------------------------------------------------------
Open_Buffer_Unsynch()1231 void File__Analyze::Open_Buffer_Unsynch ()
1232 {
1233 Status[IsFinished]=false;
1234 Config->IsFinishing=false;
1235 FrameInfo=frame_info();
1236 FrameInfo_Previous=frame_info();
1237 FrameInfo_Next=frame_info();
1238 Frame_Count_NotParsedIncluded=Unsynch_Frame_Count;
1239 Unsynch_Frame_Count=(int64u)-1;
1240 PTS_End=0;
1241 DTS_End=0;
1242 #if MEDIAINFO_DEMUX
1243 Demux_IntermediateItemFound=true;
1244 Demux_Offset=0;
1245 Demux_TotalBytes=Buffer_TotalBytes;
1246 Config->Demux_EventWasSent=false;
1247 #endif //MEDIAINFO_DEMUX
1248
1249 //Clearing duration
1250 if (Synched)
1251 {
1252 for (size_t StreamKind=(size_t)Stream_General; StreamKind<(size_t)Stream_Menu; StreamKind++)
1253 {
1254 size_t StreamPos_Count=Count_Get((stream_t)StreamKind);
1255 for (size_t StreamPos=0; StreamPos<StreamPos_Count; StreamPos++)
1256 Clear((stream_t)StreamKind, StreamPos, Fill_Parameter((stream_t)StreamKind, Generic_Duration));
1257 }
1258 }
1259
1260 //if (Synched)
1261 if (!MustSynchronize || File_Offset_FirstSynched!=(int64u)-1) //Synched at least once
1262 {
1263 Synched=false;
1264 UnSynched_IsNotJunk=true;
1265 Read_Buffer_Unsynched();
1266 Ibi_Read_Buffer_Unsynched();
1267 }
1268 Buffer_Clear();
1269
1270 //Some default values
1271 if (StreamSource==IsStream && File_GoTo==0)
1272 {
1273 FrameInfo.DTS=0;
1274 Frame_Count_NotParsedIncluded=0;
1275 }
1276
1277 #if MEDIAINFO_ADVANCED2
1278 PTSb=NoTs;
1279 DTSb=NoTs;
1280 #endif //MEDIAINFO_ADVANCED2
1281 }
1282
1283 //---------------------------------------------------------------------------
Open_Buffer_Update()1284 void File__Analyze::Open_Buffer_Update ()
1285 {
1286 if (Status[IsAccepted])
1287 Streams_Update();
1288
1289 Status[File__Analyze::IsUpdated]=false;
1290 for (size_t Pos=File__Analyze::User_16; Pos<File__Analyze::User_16+16; Pos++)
1291 Status[Pos]=false;
1292 }
1293
1294 //---------------------------------------------------------------------------
Open_Buffer_Finalize(bool NoBufferModification)1295 void File__Analyze::Open_Buffer_Finalize (bool NoBufferModification)
1296 {
1297 //Indication to the parser that this is finishing
1298 if (!NoBufferModification && !Config->IsFinishing)
1299 {
1300 Config->IsFinishing=true;
1301 int64u FileSize_Real=File_Size;
1302 File_Size=File_Offset+Buffer_Size;
1303 Open_Buffer_Continue((const int8u*)NULL, 0);
1304 File_Size=FileSize_Real;
1305 #if MEDIAINFO_DEMUX
1306 if (Config->Demux_EventWasSent)
1307 {
1308 Config->IsFinishing=false; // Need to parse again
1309 return;
1310 }
1311 #endif //MEDIAINFO_DEMUX
1312 }
1313
1314 //Element must be Finish
1315 while (Element_Level>0)
1316 Element_End0();
1317
1318 //Buffer - Global
1319 Fill();
1320 if (!NoBufferModification)
1321 {
1322 ForceFinish();
1323 #if MEDIAINFO_DEMUX
1324 if (Config->Demux_EventWasSent)
1325 return;
1326 #endif //MEDIAINFO_DEMUX
1327 Buffer_Clear();
1328 }
1329
1330 #if MEDIAINFO_TRACE
1331 if (Details && Details->empty())
1332 Element[0].TraceNode.Print(Config_Trace_Format, *Details, Config_LineSeparator.To_UTF8(), File_Size);
1333 #endif //MEDIAINFO_TRACE
1334
1335 #if MEDIAINFO_EVENTS
1336 if (Status[IsAccepted])
1337 {
1338 EVENT_BEGIN (General, End, 0)
1339 if (Event.StreamIDs_Size>=1)
1340 Event.StreamIDs[Event.StreamIDs_Size-1]=(int64u)-1;
1341 Event.PCR=(int64u)-1;
1342 Event.DTS=(int64u)-1;
1343 Event.PTS=(int64u)-1;
1344 Event.DUR=(int64u)-1;
1345 Event.Stream_Bytes_Analyzed=Buffer_TotalBytes;
1346 Event.Stream_Size=File_Size;
1347 Event.Stream_Bytes_Padding=Buffer_PaddingBytes;
1348 Event.Stream_Bytes_Junk=Buffer_JunkBytes;
1349 if (!IsSub && MustSynchronize && !Synched && !UnSynched_IsNotJunk)
1350 Event.Stream_Bytes_Junk+=Buffer_TotalBytes+Buffer_Offset-Buffer_TotalBytes_LastSynched;
1351 EVENT_END ()
1352 }
1353 #endif //MEDIAINFO_EVENTS
1354 }
1355
Open_Buffer_Finalize(File__Analyze * Sub)1356 void File__Analyze::Open_Buffer_Finalize (File__Analyze* Sub)
1357 {
1358 if (Sub==NULL)
1359 return;
1360
1361 //Finalize
1362 Open_Buffer_Init(Sub);
1363 Sub->Open_Buffer_Finalize();
1364 }
1365
1366 //***************************************************************************
1367 // Buffer
1368 //***************************************************************************
1369
1370 //---------------------------------------------------------------------------
1371 #if MEDIAINFO_SEEK
Read_Buffer_Seek(size_t Method,int64u Value,int64u ID)1372 size_t File__Analyze::Read_Buffer_Seek (size_t Method, int64u Value, int64u ID)
1373 {
1374 #if MEDIAINFO_IBI
1375 if (!IsSub)
1376 {
1377 size_t ReturnValue=Ibi_Read_Buffer_Seek(Method, Value, ID);
1378 if (ReturnValue!=(size_t)-1) // If IBI file is supported
1379 return ReturnValue;
1380 }
1381 #endif //MEDIAINFO_IBI
1382
1383 //Parsing
1384 switch (Method)
1385 {
1386 case 0 : //Default stream seek (byte offset)
1387 GoTo(Value);
1388 Open_Buffer_Unsynch();
1389 return 1;
1390 case 1 : //Default stream seek (percentage)
1391 GoTo(File_Size*Value/10000);
1392 Open_Buffer_Unsynch();
1393 return 1;
1394 default :
1395 return (size_t)-1; //Not supported
1396 }
1397 }
1398 #endif //MEDIAINFO_SEEK
1399
1400 //---------------------------------------------------------------------------
1401 #if MEDIAINFO_SEEK
Read_Buffer_Seek_OneFramePerFile(size_t Method,int64u Value,int64u ID)1402 size_t File__Analyze::Read_Buffer_Seek_OneFramePerFile (size_t Method, int64u Value, int64u ID)
1403 {
1404 //Parsing
1405 switch (Method)
1406 {
1407 case 0 :
1408 {
1409 if (Value>=Config->File_Size)
1410 return 2; //Invalid value
1411 int64u Offset=0;
1412 for (size_t Pos=0; Pos<Config->File_Sizes.size(); Pos++)
1413 {
1414 Offset+=Config->File_Sizes[Pos];
1415 if (Offset>=Value)
1416 {
1417 Offset-=Config->File_Sizes[Pos];
1418 break;
1419 }
1420 }
1421 GoTo(Offset);
1422 Open_Buffer_Unsynch();
1423 return 1;
1424 }
1425 case 1 :
1426 {
1427 if (Value>=10000)
1428 return 2; //Invalid value
1429 size_t FilePos=(size_t)((((float32)Value)/10000)*Config->File_Sizes.size());
1430 int64u Offset=0;
1431 for (size_t Pos=0; Pos<FilePos; Pos++)
1432 Offset+=Config->File_Sizes[Pos];
1433 GoTo(Offset);
1434 Open_Buffer_Unsynch();
1435 return 1;
1436 }
1437 case 2 : //Timestamp
1438 #if MEDIAINFO_DEMUX
1439 if (Config->Demux_Rate_Get()==0)
1440 return (size_t)-1; //Not supported
1441 Value=float64_int64s(((float64)Value)/1000000000*Config->Demux_Rate_Get());
1442 #else //MEDIAINFO_DEMUX
1443 return (size_t)-1; //Not supported
1444 #endif //MEDIAINFO_DEMUX
1445 case 3 : //FrameNumber
1446 {
1447 if (Value>=Config->File_Names.size())
1448 return 2; //Invalid value
1449 int64u Offset=0;
1450 if (Config->File_Sizes.size()!=Config->File_Names.size())
1451 {
1452 Offset=Value; //File_GoTo is the frame offset in that case
1453 Config->File_GoTo_IsFrameOffset=true;
1454 }
1455 else
1456 for (size_t Pos=0; Pos<Value; Pos++)
1457 Offset+=Config->File_Sizes[Pos];
1458 GoTo(Offset);
1459 Open_Buffer_Unsynch();
1460 return 1;
1461 }
1462 default : return (size_t)-1; //Not supported
1463 }
1464 }
1465 #endif //MEDIAINFO_SEEK
1466
1467 //---------------------------------------------------------------------------
Read_Buffer_Unsynched_OneFramePerFile()1468 void File__Analyze::Read_Buffer_Unsynched_OneFramePerFile()
1469 {
1470 #if MEDIAINFO_ADVANCED
1471 if (Config->File_Sizes.size()!=Config->File_Names.size())
1472 {
1473 Frame_Count_NotParsedIncluded=File_GoTo;
1474 }
1475 else
1476 #endif //MEDIAINFO_ADVANCED
1477 {
1478 int64u GoTo=File_GoTo;
1479 for (Frame_Count_NotParsedIncluded=0; Frame_Count_NotParsedIncluded<Config->File_Sizes.size(); Frame_Count_NotParsedIncluded++)
1480 {
1481 if (GoTo>=Config->File_Sizes[(size_t)Frame_Count_NotParsedIncluded])
1482 GoTo-=Config->File_Sizes[(size_t)Frame_Count_NotParsedIncluded];
1483 else
1484 break;
1485 }
1486 }
1487
1488 #if MEDIAINFO_DEMUX
1489 if (!IsSub && Config->Demux_Rate_Get()) //TODO: remove !IsSub when time code delay is removed from PTS
1490 {
1491 FrameInfo.DTS=float64_int64s(Frame_Count_NotParsedIncluded*((float64)1000000000)/Config->Demux_Rate_Get());
1492 FrameInfo.PTS=FrameInfo.DTS;
1493 }
1494 else
1495 FrameInfo.PTS=FrameInfo.DTS=(int64u)-1;
1496 #endif //MEDIAINFO_DEMUX
1497 }
1498
1499 //---------------------------------------------------------------------------
Buffer_Parse()1500 bool File__Analyze::Buffer_Parse()
1501 {
1502 //End of this level?
1503 if (File_Offset+Buffer_Offset>=Element[Element_Level].Next)
1504 {
1505 //There is no loop handler, so we make the level down here
1506 while (Element_Level>0 && File_Offset+Buffer_Offset>=Element[Element_Level].Next)
1507 Element_End0(); //This is a buffer restart, must sync to Element level
1508 if (File_Offset+Buffer_Offset==File_Size)
1509 return false; //End of file
1510 MustUseAlternativeParser=false; //Reset it if we go out of an element
1511 }
1512
1513 //Synchro
1514 if (MustSynchronize)
1515 do
1516 {
1517 if (!Synchro_Manage())
1518 return false; //Wait for more data
1519 }
1520 while (!Synched);
1521 #if MEDIAINFO_DEMUX
1522 else if (Demux_TotalBytes<=Buffer_TotalBytes+Buffer_Offset)
1523 {
1524 if (Demux_UnpacketizeContainer && !Demux_UnpacketizeContainer_Test())
1525 {
1526 Demux_Offset-=Buffer_Offset;
1527 return false; //Wait for more data
1528 }
1529 if (Config->Demux_EventWasSent)
1530 return false;
1531 }
1532 #endif //MEDIAINFO_DEMUX
1533
1534 //Offsets
1535 if (Offsets_Pos==(size_t)-1 && !Offsets_Buffer.empty())
1536 Offsets_Pos=0;
1537 if (Offsets_Pos!=(size_t)-1)
1538 {
1539 while (Offsets_Pos<Offsets_Buffer.size() && Buffer_Offset>Offsets_Buffer[Offsets_Pos])
1540 Offsets_Pos++;
1541 if (Offsets_Pos>=Offsets_Buffer.size() || Buffer_Offset!=Offsets_Buffer[Offsets_Pos])
1542 Offsets_Pos--;
1543 }
1544
1545 //Header
1546 if (!Header_Manage())
1547 return false; //Wait for more data
1548
1549 //Data
1550 if (!Data_Manage())
1551 return false; //Wait for more data
1552
1553 Buffer_TotalBytes_LastSynched=Buffer_TotalBytes+Buffer_Offset;
1554
1555 return true;
1556 }
1557
1558 //---------------------------------------------------------------------------
Buffer_Clear()1559 void File__Analyze::Buffer_Clear()
1560 {
1561 //Buffer
1562 BS->Attach(NULL, 0);
1563 delete[] Buffer_Temp; Buffer_Temp=NULL;
1564 if (!Status[IsFinished])
1565 File_Offset+=Buffer_Size;
1566 else
1567 {
1568 File_Offset=File_Size;
1569 if (!IsSub && !Config->File_Names.empty())
1570 {
1571 if (Config->File_Sizes.size()>=Config->File_Names.size())
1572 Config->File_Current_Size=Config->File_Sizes[Config->File_Names.size()-1];
1573 Config->File_Current_Offset=Config->File_Current_Size;
1574 Config->File_Names_Pos=Config->File_Names.size()-1;
1575 }
1576 }
1577 Buffer_Size=0;
1578 Buffer_Temp_Size=0;
1579 Buffer_Offset=0;
1580 Buffer_Offset_Temp=0;
1581 Buffer_MinimumSize=0;
1582
1583 OriginalBuffer_Size=0;
1584 Offsets_Stream.clear();
1585 Offsets_Buffer.clear();
1586 Offsets_Pos=(size_t)-1;
1587
1588 //Details
1589 #if MEDIAINFO_TRACE
1590 Element[Element_Level].WaitForMoreData=false; //We must finalize the details
1591 Element[Element_Level].IsComplete=true; //We must finalize the details
1592 #endif //MEDIAINFO_TRACE
1593
1594 }
1595
1596 //***************************************************************************
1597 // Helpers
1598 //***************************************************************************
1599
1600 //---------------------------------------------------------------------------
Synchronize_0x000001()1601 bool File__Analyze::Synchronize_0x000001()
1602 {
1603 //Synchronizing
1604 while(Buffer_Offset+3<=Buffer_Size && (Buffer[Buffer_Offset ]!=0x00
1605 || Buffer[Buffer_Offset+1]!=0x00
1606 || Buffer[Buffer_Offset+2]!=0x01))
1607 {
1608 Buffer_Offset+=2;
1609 while(Buffer_Offset<Buffer_Size && Buffer[Buffer_Offset]!=0x00)
1610 Buffer_Offset+=2;
1611 if ((Buffer_Offset<Buffer_Size && Buffer[Buffer_Offset-1]==0x00) || Buffer_Offset>=Buffer_Size)
1612 Buffer_Offset--;
1613 }
1614
1615 //Parsing last bytes if needed
1616 if (Buffer_Offset+3==Buffer_Size && (Buffer[Buffer_Offset ]!=0x00
1617 || Buffer[Buffer_Offset+1]!=0x00
1618 || Buffer[Buffer_Offset+2]!=0x01))
1619 Buffer_Offset++;
1620 if (Buffer_Offset+2==Buffer_Size && (Buffer[Buffer_Offset ]!=0x00
1621 || Buffer[Buffer_Offset+1]!=0x00))
1622 Buffer_Offset++;
1623 if (Buffer_Offset+1==Buffer_Size && Buffer[Buffer_Offset ]!=0x00)
1624 Buffer_Offset++;
1625
1626 if (Buffer_Offset+3>Buffer_Size)
1627 return false;
1628
1629 //Synched is OK
1630 Synched=true;
1631 return true;
1632 }
1633
1634 //---------------------------------------------------------------------------
FileHeader_Begin_0x000001()1635 bool File__Analyze::FileHeader_Begin_0x000001()
1636 {
1637 // No need to check if inside a container
1638 if (IsSub)
1639 return true;
1640
1641 //Element_Size
1642 if (Buffer_Size<192*4)
1643 return false; //Not enough buffer for a test
1644
1645 //Detecting OldDirac/WAV/SWF/FLV/ELF/DPG/WM files
1646 int64u Magic8=CC8(Buffer);
1647 int32u Magic4=Magic8>>32;
1648 int32u Magic3=Magic4>> 8;
1649 int16u Magic2=Magic4>>16;
1650 if (Magic8==0x4B572D4449524143LL || Magic4==0x52494646 || Magic3==0x465753 || Magic3==0x464C56 || Magic4==0x7F454C46 || Magic4==0x44504730 || Magic4==0x3026B275 || Magic2==0x4D5A || Magic4==0x1A45DFA3)
1651 {
1652 Reject();
1653 return false;
1654 }
1655
1656 //GXF
1657 if (CC5(Buffer)==0x0000000001 && CC2(Buffer+14)==0xE1E2)
1658 {
1659 Reject();
1660 return false;
1661 }
1662
1663 //Detecting MPEG-4 files (ftyp/mdat/skip/free)
1664 Magic4=CC4(Buffer+4);
1665 switch (Magic4)
1666 {
1667 case 0x66747970 : //ftyp
1668 case 0x6D646174 : //mdat
1669 case 0x736B6970 : //skip
1670 case 0x66726565 : //free
1671 Reject();
1672 return false;
1673 default : break;
1674 }
1675
1676 //WTV
1677 if (Magic8==0xB7D800203749DA11LL && CC8(Buffer+8)==0xA64E0007E95EAD8DLL)
1678 {
1679 Reject();
1680 return false;
1681 }
1682
1683 //Detect TS files, and the parser is not enough precise to detect them later
1684 size_t Buffer_Offset=0;
1685 while (Buffer_Offset<188 && Buffer[Buffer_Offset]!=0x47) //Look for first Sync word
1686 Buffer_Offset++;
1687 if (Buffer_Offset<188 && Buffer[Buffer_Offset+188]==0x47 && Buffer[Buffer_Offset+188*2]==0x47 && Buffer[Buffer_Offset+188*3]==0x47)
1688 {
1689 Status[IsFinished]=true;
1690 return false;
1691 }
1692 Buffer_Offset=0;
1693
1694 //Detect BDAV files, and the parser is not enough precise to detect them later
1695 while (Buffer_Offset<192 && CC1(Buffer+Buffer_Offset+4)!=0x47) //Look for first Sync word
1696 Buffer_Offset++;
1697 if (Buffer_Offset<192 && CC1(Buffer+Buffer_Offset+192+4)==0x47 && CC1(Buffer+Buffer_Offset+192*2+4)==0x47 && CC1(Buffer+Buffer_Offset+192*3+4)==0x47)
1698 {
1699 Status[IsFinished]=true;
1700 return false;
1701 }
1702 Buffer_Offset=0;
1703
1704 //All should be OK...
1705 return true;
1706 }
1707
1708 //---------------------------------------------------------------------------
FileHeader_Begin_XML(XMLDocument & Document)1709 bool File__Analyze::FileHeader_Begin_XML(XMLDocument &Document)
1710 {
1711 //Element_Size
1712 if (Buffer_Size<32 || (!IsSub && File_Size>16*1024*1024))
1713 {
1714 Reject();
1715 return false; //XML files are not expected to be so big
1716 }
1717
1718 //Element_Size
1719 if (!IsSub && Buffer_Size<File_Size)
1720 {
1721 Element_WaitForMoreData();
1722 return false; //Must wait for more data
1723 }
1724
1725 //XML header
1726 Ztring Data;
1727 if ((Buffer[0]=='<'
1728 && Buffer[1]==0x00)
1729 || (Buffer[0]==0xFF
1730 && Buffer[1]==0xFE
1731 && Buffer[2]=='<'
1732 && Buffer[3]==0x00))
1733 Data.From_UTF16LE((const char*)Buffer, Buffer_Size);
1734 else if ((Buffer[0]==0x00
1735 && Buffer[1]=='<')
1736 || (Buffer[0]==0xFE
1737 && Buffer[1]==0xFF
1738 && Buffer[2]==0x00
1739 && Buffer[3]=='<'))
1740 Data.From_UTF16BE((const char*)Buffer, Buffer_Size);
1741 else if ((Buffer[0]=='<')
1742 || (Buffer[0]==0xEF
1743 && Buffer[1]==0xBB
1744 && Buffer[2]==0xBF
1745 && Buffer[3]=='<'))
1746 Data.From_UTF8((const char*)Buffer, Buffer_Size);
1747 else
1748 {
1749 Reject();
1750 return false;
1751 }
1752
1753 string DataUTF8=Data.To_UTF8();
1754 if (Document.Parse(DataUTF8.c_str()))
1755 {
1756 Reject();
1757 return false;
1758 }
1759
1760 return true;
1761 }
1762
1763 //***************************************************************************
1764 // Timestamps
1765 //***************************************************************************
1766
1767 //---------------------------------------------------------------------------
TS_Clear(ts_type Type)1768 void File__Analyze::TS_Clear(ts_type Type)
1769 {
1770 if (Type&TS_PTS)
1771 FrameInfo.PTS=(int64u)-1;
1772 if (Type&TS_DTS)
1773 FrameInfo.DTS=(int64u)-1;
1774
1775 #if MEDIAINFO_ADVANCED2
1776 if (Type&TS_PTS)
1777 FrameInfo.PTSc=NoTs;
1778 if (Type&TS_DTS)
1779 FrameInfo.DTSc=NoTs;
1780 #endif //MEDIAINFO_ADVANCED2
1781 }
1782
gcd(int64s a,int64s b)1783 int64s gcd(int64s a, int64s b)
1784 {
1785 return b ? gcd(b, a%b) : a;
1786 }
1787
1788 //---------------------------------------------------------------------------
TS_Set(int64s Ticks,ts_type Type)1789 void File__Analyze::TS_Set(int64s Ticks, ts_type Type)
1790 {
1791 if (StreamSource==IsStream)
1792 {
1793 if (!Frequency_b)
1794 return;
1795
1796 int64s divisor = gcd(1000000000, Frequency_b);
1797 if (Type&TS_PTS)
1798 FrameInfo.PTS=float64_int64s((float64)Ticks*(1000000000/divisor)/(Frequency_b/divisor));
1799 if (Type&TS_DTS)
1800 FrameInfo.DTS=float64_int64s((float64)Ticks*(1000000000/divisor)/(Frequency_b/divisor));
1801 }
1802 else
1803 {
1804 if (!Frequency_c)
1805 return;
1806
1807 int64s divisor = gcd(1000000000, Frequency_c);
1808 if (Type&TS_PTS)
1809 FrameInfo.PTS=float64_int64s((float64)Ticks*(1000000000/divisor)/(Frequency_c/divisor));
1810 if (Type&TS_DTS)
1811 FrameInfo.DTS=float64_int64s((float64)Ticks*(1000000000/divisor)/(Frequency_c/divisor));
1812 }
1813
1814 #if MEDIAINFO_ADVANCED2
1815 if (StreamSource==IsStream)
1816 {
1817 if (!Frequency_b)
1818 return;
1819
1820 if (Type&TS_PTS)
1821 PTSb=Ticks;
1822 if (Type&TS_DTS)
1823 DTSb=Ticks;
1824 if (Frequency_c)
1825 {
1826 if (Type&TS_PTS)
1827 PTSb*=Frequency_c;
1828 if (Type&TS_DTS)
1829 DTSb*=Frequency_c;
1830 }
1831 }
1832 else
1833 {
1834 if (!Frequency_c)
1835 return;
1836
1837 if (Type&TS_PTS)
1838 FrameInfo.PTSc=Ticks;
1839 if (Type&TS_DTS)
1840 FrameInfo.DTSc=Ticks;
1841 }
1842
1843 FrameInfo.Frame_Count_AfterLastTimeStamp=0;
1844 #endif //MEDIAINFO_ADVANCED2
1845 }
1846
1847 //---------------------------------------------------------------------------
TS_Set(File__Analyze * Parser,ts_type Type)1848 void File__Analyze::TS_Set(File__Analyze* Parser, ts_type Type)
1849 {
1850 if (Type&TS_PTS && FrameInfo.PTS!=(int64u)-1)
1851 Parser->FrameInfo.PTS=FrameInfo.PTS;
1852 if (Type&TS_DTS && FrameInfo.DTS!=(int64u)-1)
1853 Parser->FrameInfo.DTS=FrameInfo.DTS;
1854
1855 #if MEDIAINFO_ADVANCED2
1856 if (Type&TS_PTS && FrameInfo.PTSc!=NoTs)
1857 Parser->FrameInfo.PTSc=FrameInfo.PTSc;
1858 if (Type&TS_DTS && FrameInfo.DTSc!=NoTs)
1859 Parser->FrameInfo.DTSc=FrameInfo.DTSc;
1860
1861 if (!FrameInfo.Frame_Count_AfterLastTimeStamp)
1862 Parser->FrameInfo.Frame_Count_AfterLastTimeStamp=0;
1863 #endif //MEDIAINFO_ADVANCED2
1864 }
1865
1866 //---------------------------------------------------------------------------
TS_Ajust(int64s Ticks)1867 void File__Analyze::TS_Ajust(int64s Ticks)
1868 {
1869 #if MEDIAINFO_ADVANCED2
1870 if (StreamSource==IsStream)
1871 {
1872 if (PTSb==NoTs)
1873 {
1874 if (FrameInfo.DTSc!=NoTs)
1875 PTSb=FrameInfo.DTSc*Frequency_b+Ticks*FrameInfo.Frame_Count_AfterLastTimeStamp*(Frequency_c?Frequency_c:1); // Relying on DTS only, ajustment is done by the function itself
1876 else
1877 PTSb=-Ticks*FrameInfo.Frame_Count_AfterLastTimeStamp*(Frequency_c?Frequency_c:1);
1878 }
1879
1880 if (PTSb!=NoTs)
1881 PTSb+=Ticks*(Frequency_c?Frequency_c:1);
1882 }
1883 else
1884 {
1885 if (PTSb!=NoTs)
1886 PTSb+=Ticks;
1887 }
1888 #endif //MEDIAINFO_ADVANCED2
1889 }
1890
1891 //---------------------------------------------------------------------------
TS_Add(int64s Ticks,ts_type Type)1892 void File__Analyze::TS_Add(int64s Ticks, ts_type Type)
1893 {
1894 if (StreamSource==IsStream)
1895 {
1896 //Coherency test
1897 if (!Frequency_b)
1898 {
1899 #if MEDIAINFO_ADVANCED2
1900 FrameInfo.Frame_Count_AfterLastTimeStamp++;
1901 #endif //MEDIAINFO_ADVANCED2
1902 return;
1903 }
1904
1905 #if MEDIAINFO_ADVANCED2
1906 //Filling first TS if not set somewhere else
1907 if (Type&TS_PTS && PTSb==NoTs)
1908 {
1909 if (FrameInfo.PTSc!=NoTs)
1910 PTSb=FrameInfo.PTSc*Frequency_b+Ticks*FrameInfo.Frame_Count_AfterLastTimeStamp*(Frequency_c?Frequency_c:1);
1911 else
1912 PTSb=-Ticks*FrameInfo.Frame_Count_AfterLastTimeStamp*(Frequency_c?Frequency_c:1);
1913 }
1914 if (Type&TS_DTS && DTSb==NoTs)
1915 {
1916 if (FrameInfo.DTSc!=NoTs)
1917 DTSb=FrameInfo.DTSc*Frequency_b+Ticks*FrameInfo.Frame_Count_AfterLastTimeStamp*(Frequency_c?Frequency_c:1);
1918 else
1919 DTSb=-Ticks*FrameInfo.Frame_Count_AfterLastTimeStamp*(Frequency_c?Frequency_c:1);
1920 }
1921
1922 //Coherency test
1923 if (Type&TS_PTS && PTSb!=NoTs && FrameInfo.PTSc!=NoTs)
1924 {
1925 if (!FrameInfo.Frame_Count_AfterLastTimeStamp && PTSb != FrameInfo.PTSc*Frequency_b && (FrameInfo.PTSc*Frequency_b-PTSb<=-Frequency_b || FrameInfo.PTSc*Frequency_b-PTSb>=Frequency_b))
1926 {
1927 PTSb=FrameInfo.PTSc*Frequency_b;
1928 }
1929 }
1930 if (Type&TS_DTS && DTSb!=NoTs && FrameInfo.DTSc!=NoTs)
1931 {
1932 if (!FrameInfo.Frame_Count_AfterLastTimeStamp && DTSb != FrameInfo.DTSc*Frequency_b && (FrameInfo.DTSc*Frequency_b-DTSb<=-Frequency_b || FrameInfo.DTSc*Frequency_b-DTSb>=Frequency_b))
1933 {
1934 DTSb=FrameInfo.DTSc*Frequency_b;
1935 }
1936 }
1937 #endif //MEDIAINFO_ADVANCED2
1938 }
1939
1940 //Trace
1941 #if MEDIAINFO_ADVANCED2
1942 Element_Info1(Ztring::ToZtring(Frame_Count));
1943 Element_Info1C((DTSb!=NoTs && DTSb!=PTSb), __T("DTS ")+Ztring().Duration_From_Milliseconds(float64_int64s(((float64)DTSb)*1000/(Frequency_c?Frequency_c:1)/Frequency_b)));
1944 Element_Info1C((PTSb!=NoTs), __T("PTS ")+Ztring().Duration_From_Milliseconds(float64_int64s(((float64)PTSb)*1000/(Frequency_c?Frequency_c:1)/Frequency_b)));
1945 #else //MEDIAINFO_ADVANCED2
1946 Element_Info1C((FrameInfo.DTS!=(int64u)-1 && FrameInfo.PTS!=(int64u)-1), __T("DTS ")+Ztring().Duration_From_Milliseconds(float64_int64s(((float64)FrameInfo.DTS)/1000000)));
1947 Element_Info1C((FrameInfo.PTS!=(int64u)-1), __T("PTS ")+Ztring().Duration_From_Milliseconds(float64_int64s(((float64)FrameInfo.PTS)/1000000)));
1948 Element_Info1(Frame_Count);
1949 #endif //MEDIAINFO_ADVANCED2
1950
1951 //Adding timestamp
1952 FrameInfo.DUR=Ticks*1000000000/Frequency_b;
1953 if (Type&TS_PTS && FrameInfo.PTS!=(int64u)-1 && Frequency_b)
1954 FrameInfo.PTS+=FrameInfo.DUR;
1955 if (Type&TS_DTS && FrameInfo.DTS!=(int64u)-1 && Frequency_b)
1956 FrameInfo.DTS+=FrameInfo.DUR;
1957 #if MEDIAINFO_ADVANCED2
1958 if (StreamSource==IsStream)
1959 {
1960 if (Type&TS_PTS && PTSb!=NoTs)
1961 PTSb+=Ticks*(Frequency_c?Frequency_c:1);
1962 if (Type&TS_DTS && DTSb!=NoTs)
1963 DTSb+=Ticks*(Frequency_c?Frequency_c:1);
1964 }
1965 else
1966 {
1967 if (Type&TS_PTS && PTSb!=NoTs)
1968 PTSb+=Ticks;
1969 if (Type&TS_DTS && DTSb!=NoTs)
1970 DTSb+=Ticks;
1971 }
1972 FrameInfo.Frame_Count_AfterLastTimeStamp++;
1973 #endif //MEDIAINFO_ADVANCED2
1974 Frame_Count++;
1975 Frame_Count_InThisBlock++;
1976 if (Frame_Count_NotParsedIncluded!=(int64u)-1)
1977 Frame_Count_NotParsedIncluded++;
1978 }
1979
1980 //***************************************************************************
1981 // Synchro
1982 //***************************************************************************
1983
1984 //---------------------------------------------------------------------------
Synchro_Manage()1985 bool File__Analyze::Synchro_Manage()
1986 {
1987 //Testing if synchro is OK
1988 if (Synched)
1989 {
1990 if (!IsSub)
1991 Buffer_TotalBytes_LastSynched=Buffer_TotalBytes+Buffer_Offset;
1992
1993 if (!Synchro_Manage_Test())
1994 return false;
1995 }
1996
1997 //Trying to synchronize
1998 if (!Synched)
1999 {
2000 //Buffer_TotalBytes_Fill_Max
2001 if (!Status[IsFilled] && Buffer_TotalBytes>=Buffer_TotalBytes_Fill_Max)
2002 {
2003 Open_Buffer_Unsynch();
2004 GoToFromEnd(0);
2005 return false;
2006 }
2007 if (!Synchronize())
2008 {
2009 if (Status[IsFinished])
2010 Finish(); //Finish
2011 if (!IsSub && File_Offset_FirstSynched==(int64u)-1 && Buffer_TotalBytes+Buffer_Offset>=Buffer_TotalBytes_FirstSynched_Max)
2012 {
2013 Open_Buffer_Unsynch();
2014 GoToFromEnd(0);
2015 }
2016 return false; //Wait for more data
2017 }
2018 Synched=true;
2019 if (!IsSub)
2020 {
2021 if (!UnSynched_IsNotJunk)
2022 Buffer_JunkBytes+=Buffer_TotalBytes+Buffer_Offset-Buffer_TotalBytes_LastSynched;
2023 Buffer_TotalBytes_LastSynched=Buffer_TotalBytes+Buffer_Offset;
2024 UnSynched_IsNotJunk=false;
2025 }
2026 if (File_Offset_FirstSynched==(int64u)-1)
2027 {
2028 Synched_Init();
2029 Buffer_TotalBytes_FirstSynched+=Buffer_TotalBytes+Buffer_Offset;
2030 File_Offset_FirstSynched=File_Offset+Buffer_Offset;
2031 }
2032 #if MEDIAINFO_DEMUX
2033 if (Config->Demux_EventWasSent)
2034 return false;
2035 #endif //MEDIAINFO_DEMUX
2036 if (!Synchro_Manage_Test())
2037 return false;
2038 }
2039
2040 return true;
2041 }
2042
2043 //---------------------------------------------------------------------------
Synchro_Manage_Test()2044 bool File__Analyze::Synchro_Manage_Test()
2045 {
2046 //Testing if synchro is OK
2047 if (Synched)
2048 {
2049 if (!Synched_Test())
2050 return false;
2051 #if MEDIAINFO_DEMUX
2052 if (Synched && Demux_TotalBytes<=Buffer_TotalBytes+Buffer_Offset)
2053 {
2054 if (Demux_UnpacketizeContainer && !Demux_UnpacketizeContainer_Test())
2055 {
2056 Demux_Offset-=Buffer_Offset;
2057 return false; //Wait for more data
2058 }
2059 if (Config->Demux_EventWasSent)
2060 return false;
2061 }
2062 #endif //MEDIAINFO_DEMUX
2063 if (Buffer_Offset>=FrameInfo.Buffer_Offset_End && FrameInfo_Next.DTS!=(int64u)-1)
2064 {
2065 FrameInfo=FrameInfo_Next;
2066 FrameInfo_Next=frame_info();
2067 }
2068 if (Synched)
2069 {
2070 if (!IsSub)
2071 Buffer_TotalBytes_LastSynched=Buffer_TotalBytes+Buffer_Offset;
2072 }
2073 else
2074 {
2075 Element[Element_Level].IsComplete=true; //Else the trusting algo will think it
2076 Trusted_IsNot("Synchronisation lost");
2077 while (Element_Level)
2078 Element_End();
2079 }
2080 }
2081
2082 //Trying to synchronize
2083 if (!Synched)
2084 {
2085 if (!Synchronize())
2086 {
2087 if (Status[IsFinished])
2088 Finish(); //Finish
2089 if (!IsSub && File_Offset_FirstSynched==(int64u)-1 && Buffer_TotalBytes+Buffer_Offset>=Buffer_TotalBytes_FirstSynched_Max)
2090 Reject();
2091 return false; //Wait for more data
2092 }
2093 Synched=true;
2094 if (!IsSub)
2095 {
2096 if (!UnSynched_IsNotJunk)
2097 Buffer_JunkBytes+=Buffer_TotalBytes+Buffer_Offset-Buffer_TotalBytes_LastSynched;
2098 Buffer_TotalBytes_LastSynched=Buffer_TotalBytes+Buffer_Offset;
2099 UnSynched_IsNotJunk=false;
2100 }
2101 if (File_Offset_FirstSynched==(int64u)-1)
2102 {
2103 Synched_Init();
2104 Buffer_TotalBytes_FirstSynched+=Buffer_TotalBytes+Buffer_Offset;
2105 File_Offset_FirstSynched=File_Offset+Buffer_Offset;
2106 }
2107 if (!Synched_Test())
2108 return false;
2109 #if MEDIAINFO_DEMUX
2110 if (Synched && Demux_TotalBytes<=Buffer_TotalBytes+Buffer_Offset)
2111 {
2112 if (Demux_UnpacketizeContainer && !Demux_UnpacketizeContainer_Test())
2113 {
2114 Demux_Offset-=Buffer_Offset;
2115 return false; //Wait for more data
2116 }
2117 if (Config->Demux_EventWasSent)
2118 return false;
2119 }
2120 #endif //MEDIAINFO_DEMUX
2121 }
2122
2123 return true;
2124 }
2125
2126 //***************************************************************************
2127 // File Header
2128 //***************************************************************************
2129
2130 //---------------------------------------------------------------------------
FileHeader_Manage()2131 bool File__Analyze::FileHeader_Manage()
2132 {
2133 //From the parser
2134 if (!Status[IsAccepted] && !FileHeader_Begin())
2135 {
2136 if (Status[IsFinished]) //Newest parsers set this bool if there is an error
2137 Reject();
2138 if (File_Offset+Buffer_Size>=File_Size)
2139 Reject();
2140 return false; //Wait for more data
2141 }
2142
2143 //Positionning
2144 if ((Buffer_Size && Buffer_Offset+Element_Offset>Buffer_Size) || (sizeof(size_t)<sizeof(int64u) && Buffer_Offset+Element_Offset>=(int64u)(size_t)-1))
2145 {
2146 GoTo(File_Offset+Buffer_Offset+Element_Offset);
2147 return false;
2148 }
2149 else
2150 {
2151 Buffer_Offset+=(size_t)Element_Offset;
2152 if (Buffer_Offset>Buffer_Size)
2153 Buffer_Size=Buffer_Offset;
2154 Element_Offset=0;
2155 }
2156
2157 #if MEDIAINFO_DEMUX
2158 if (Config->Demux_EventWasSent)
2159 return false;
2160 #endif //MEDIAINFO_DEMUX
2161
2162 //From the parser
2163 Element_Size=Buffer_Size-Buffer_Offset;
2164 Element_Begin1("File Header");
2165 FileHeader_Parse();
2166 if (Element_Offset==0 && !Status[IsFinished])
2167 Element_DoNotShow();
2168 Element_End0();
2169 if (Status[IsFinished]) //Newest parsers set this bool if there is an error
2170 {
2171 Finish();
2172 return false;
2173 }
2174
2175 //Testing the parser result
2176 if (Element_IsWaitingForMoreData() || Element[Element_Level].UnTrusted) //Wait or problem
2177 {
2178 //The header is not complete, need more data
2179 #if MEDIAINFO_TRACE
2180 Element[Element_Level].TraceNode.Init();
2181 #endif //MEDIAINFO_TRACE
2182 return false;
2183 }
2184
2185 //Positionning
2186 if ((Buffer_Size && Buffer_Offset+Element_Offset>Buffer_Size) || (sizeof(size_t)<sizeof(int64u) && Buffer_Offset+Element_Offset>=(int64u)(size_t)-1))
2187 {
2188 GoTo(File_Offset+Buffer_Offset+Element_Offset);
2189 return false;
2190 }
2191 else
2192 {
2193 Buffer_Offset+=(size_t)Element_Offset;
2194 Element_Offset=0;
2195 }
2196
2197 MustParseTheHeaderFile=false;
2198 return true;
2199 }
2200
2201 //***************************************************************************
2202 // Header
2203 //***************************************************************************
2204
2205 //---------------------------------------------------------------------------
Header_Manage()2206 bool File__Analyze::Header_Manage()
2207 {
2208 //Test
2209 if (Buffer_Offset>=Buffer_Size)
2210 return false;
2211
2212 //Header begin
2213 Element_Size=Element[Element_Level].Next-(File_Offset+Buffer_Offset);
2214 Element_Offset=0;
2215 if (!Header_Begin())
2216 {
2217 //Jumping to the end of the file if needed
2218 if (!EOF_AlreadyDetected && Config->ParseSpeed<1 && File_GoTo==(int64u)-1)
2219 {
2220 Element[Element_Level].WaitForMoreData=false;
2221 Detect_EOF();
2222 if ((File_GoTo!=(int64u)-1 && File_GoTo>File_Offset+Buffer_Offset) || (Status[IsFinished] && !ShouldContinueParsing))
2223 EOF_AlreadyDetected=true;
2224 }
2225 return false; //Wait for more data
2226 }
2227
2228 //Going in a lower level
2229 Element_Size=Element[Element_Level].Next-(File_Offset+Buffer_Offset+Element_Offset);
2230 Element[Element_Level].UnTrusted=false;
2231 if (Buffer_Offset+Element_Size>Buffer_Size)
2232 {
2233 Element_Size=Buffer_Size-Buffer_Offset;
2234 Element[Element_Level].IsComplete=false;
2235 }
2236 else
2237 Element[Element_Level].IsComplete=true;
2238 if (Element_Size==0)
2239 return false;
2240 Element_Offset=0;
2241 Element_Begin0(); //Element
2242 #if MEDIAINFO_TRACE
2243 Data_Level=Element_Level;
2244 #endif //MEDIAINFO_TRACE
2245 Element_Begin1("Header"); //Header
2246
2247 //Header parsing
2248 Header_Parse();
2249
2250 //Testing the parser result
2251 if (Element[Element_Level].UnTrusted) //Problem
2252 {
2253 Element[Element_Level].UnTrusted=false;
2254 Header_Fill_Code(0, "Problem");
2255 if (MustSynchronize)
2256 {
2257 //Unsynchronizing to the next byte
2258 Element_Offset=1;
2259 Header_Fill_Size(1);
2260 Synched=false;
2261 }
2262 else
2263 {
2264 if(Element_Level<2)
2265 return false;
2266 //Can not synchronize anymore in this block
2267 Element_Offset=Element[Element_Level-2].Next-(File_Offset+Buffer_Offset);
2268 Header_Fill_Size(Element_Offset);
2269 }
2270 }
2271 if(Element_Level<1)
2272 return false;
2273 if (Element_IsWaitingForMoreData() || ((DataMustAlwaysBeComplete && Element[Element_Level-1].Next>File_Offset+Buffer_Size) || File_GoTo!=(int64u)-1) //Wait or want to have a comple data chunk
2274 #if MEDIAINFO_DEMUX
2275 || (Config->Demux_EventWasSent)
2276 #endif //MEDIAINFO_DEMUX
2277 )
2278 {
2279 //The header is not complete, need more data
2280 Element[Element_Level].WaitForMoreData=true;
2281 Element_End0(); //Header
2282 Element_End0(); //Element
2283 return false;
2284 }
2285
2286 //Filling
2287 Element[Element_Level].WaitForMoreData=false;
2288 Element[Element_Level].IsComplete=true;
2289
2290 //TraceNode
2291 #if MEDIAINFO_TRACE
2292 if (Trace_Activated)
2293 {
2294 if (Element[Element_Level-1].TraceNode.Name_Is_Empty())
2295 Element[Element_Level-1].TraceNode.Set_Name("Unknown");
2296 Element[Element_Level].TraceNode.Size=Element_Offset;
2297 if (Element_Offset==0)
2298 Element_DoNotShow();
2299 }
2300 #endif //MEDIAINFO_TRACE
2301
2302 //Integrity
2303 if (Element[Element_Level-1].Next<(File_Offset+Buffer_Offset+Element_Offset))
2304 Element[Element_Level-1].Next=File_Offset+Buffer_Offset+Element_Offset; //Size is not good
2305
2306 //Positionning
2307 Element_Size=Element[Element_Level-1].Next-(File_Offset+Buffer_Offset+Element_Offset);
2308 Header_Size=Element_Offset;
2309 Buffer_Offset+=(size_t)Header_Size;
2310 Element_Offset=0;
2311 if (Buffer_Offset+Element_Size>Buffer_Size)
2312 {
2313 if (Buffer_Size>Buffer_Offset)
2314 Element_Size=Buffer_Size-Buffer_Offset;
2315 else
2316 Element_Size=0; //There is an error in the parsing
2317 Element[Element_Level-1].IsComplete=false;
2318 }
2319
2320 Element_End0(); //Header
2321 return true;
2322 }
2323
2324 //---------------------------------------------------------------------------
Header_Parse()2325 void File__Analyze::Header_Parse()
2326 {
2327 //Filling
2328 Header_Fill_Code(0);
2329 Header_Fill_Size(Element_Size);
2330 }
2331
2332 //---------------------------------------------------------------------------
2333 #if MEDIAINFO_TRACE
Header_Fill_Code(int64u Code,const Ztring & Name)2334 void File__Analyze::Header_Fill_Code(int64u Code, const Ztring &Name)
2335 {
2336 //Filling
2337 Element[Element_Level-1].Code=Code;
2338
2339 //TraceNode
2340 if (Config_Trace_Level!=0)
2341 {
2342 Element_Level--;
2343 Element_Name(Name);
2344 Element_Level++;
2345 }
2346 }
2347 #endif //MEDIAINFO_TRACE
2348
Header_Fill_Code(int64u Code)2349 void File__Analyze::Header_Fill_Code(int64u Code)
2350 {
2351 //Filling
2352 Element[Element_Level-1].Code=Code;
2353 }
2354
2355 //---------------------------------------------------------------------------
Header_Fill_Size(int64u Size)2356 void File__Analyze::Header_Fill_Size(int64u Size)
2357 {
2358 if (Size==0)
2359 Trusted_IsNot("Block can't have a size of 0");
2360 if (DataMustAlwaysBeComplete && Size>Buffer_MaximumSize)
2361 {
2362 Element[Element_Level].IsComplete=true;
2363 Element[Element_Level-1].IsComplete=true;
2364 Trusted_IsNot("Block is too big");
2365 }
2366
2367 if (Element[Element_Level].UnTrusted)
2368 return;
2369
2370 //Integrity
2371 if (Size<Element_Offset)
2372 Size=Element_Offset; //At least what we read before!!!
2373
2374 //Filling
2375 if (Element_Level==1)
2376 Element[0].Next=File_Offset+Buffer_Offset+Size;
2377 else if (File_Offset+Buffer_Offset+Size>Element[Element_Level-2].Next)
2378 Element[Element_Level-1].Next=Element[Element_Level-2].Next;
2379 else
2380 Element[Element_Level-1].Next=File_Offset+Buffer_Offset+Size;
2381 Element[Element_Level-1].IsComplete=true;
2382
2383 //TraceNode
2384 #if MEDIAINFO_TRACE
2385 if (Trace_Activated)
2386 {
2387 Element[Element_Level-1].TraceNode.Pos=File_Offset+Buffer_Offset;
2388 Element[Element_Level-1].TraceNode.Size=Element[Element_Level-1].Next-(File_Offset+Buffer_Offset);
2389 }
2390 #endif //MEDIAINFO_TRACE
2391 }
2392
2393 //***************************************************************************
2394 // Data
2395 //***************************************************************************
2396
2397 //---------------------------------------------------------------------------
Data_Manage()2398 bool File__Analyze::Data_Manage()
2399 {
2400 Element_WantNextLevel=false;
2401 if (!Element[Element_Level].UnTrusted)
2402 {
2403 Element_Code=Element[Element_Level].Code;
2404 //size_t Element_Level_Save=Element_Level;
2405 Data_Parse();
2406 BS->Attach(NULL, 0); //Clear it
2407 //Element_Level=Element_Level_Save;
2408
2409 if (Buffer_Offset+(Element_WantNextLevel?Element_Offset:Element_Size)>=FrameInfo.Buffer_Offset_End)
2410 {
2411 if (Frame_Count_Previous<Frame_Count)
2412 Frame_Count_Previous=Frame_Count;
2413 if (Field_Count_Previous<Field_Count)
2414 Field_Count_Previous=Field_Count;
2415 }
2416
2417 if (Buffer_Offset+(Element_WantNextLevel?Element_Offset:Element_Size)>=FrameInfo.Buffer_Offset_End && FrameInfo_Next.DTS!=(int64u)-1)
2418 {
2419 FrameInfo=FrameInfo_Next;
2420 FrameInfo_Next=frame_info();
2421 }
2422
2423 //Testing the parser result
2424 if (Element_IsWaitingForMoreData())
2425 {
2426 //The data is not complete, need more data
2427 Element_End0(); //Element
2428 Buffer_Offset-=(size_t)Header_Size;
2429 return false;
2430 }
2431
2432 Element[Element_Level].IsComplete=true;
2433
2434 if (!Element_WantNextLevel && DataMustAlwaysBeComplete && Element_Offset<Element_Size)
2435 Element_Offset=Element_Size; //In case the element is not fully parsed, an element with size from the header is assumed
2436 }
2437
2438 //If no need of more
2439 if (File_GoTo!=(int64u)-1 || (Status[IsFinished] && !ShouldContinueParsing)
2440 #if MEDIAINFO_HASH
2441 || Hash_ParseUpTo
2442 #endif //MEDIAINFO_HASH
2443 )
2444 {
2445 if (!Element_WantNextLevel)
2446 Element_End0(); //Element
2447 if (!Element_WantNextLevel && Element_Offset<Element_Size)
2448 Buffer_Offset+=(size_t)Element_Size;
2449 else
2450 {
2451 if (sizeof(size_t)<sizeof(int64u) && Buffer_Offset+Element_Offset>=(int64u)(size_t)-1)
2452 GoTo(File_Offset+Buffer_Offset+Element_Offset);
2453 else
2454 Buffer_Offset+=(size_t)Element_Offset;
2455 }
2456 Header_Size=0;
2457 Element_Size=0;
2458 Element_Offset=0;
2459 return false;
2460 }
2461
2462 //Next element
2463 if (!Element_WantNextLevel
2464 #if MEDIAINFO_HASH
2465 && Hash==NULL
2466 #endif //MEDIAINFO_HASH
2467 )
2468 {
2469 if (Element[Element_Level].Next<=File_Offset+Buffer_Size)
2470 {
2471 if (Element_Offset<(size_t)(Element[Element_Level].Next-File_Offset-Buffer_Offset))
2472 Element_Offset=(size_t)(Element[Element_Level].Next-File_Offset-Buffer_Offset);
2473 }
2474 else if (!Status[IsFinished])
2475 {
2476 GoTo(Element[Element_Level].Next);
2477 if (!Element_WantNextLevel)
2478 Element_End0(); //Element
2479 return false;
2480 }
2481 }
2482
2483 if (!Element_WantNextLevel && Element_Offset<Element_Size)
2484 Buffer_Offset+=(size_t)Element_Size;
2485 else
2486 {
2487 if (sizeof(size_t)<sizeof(int64u) && Buffer_Offset+Element_Offset>=(int64u)(size_t)-1)
2488 GoTo(File_Offset+Buffer_Offset+Element_Offset);
2489 else
2490 Buffer_Offset+=(size_t)Element_Offset;
2491 }
2492 Header_Size=0;
2493 Element_Size=0;
2494 Element_Offset=0;
2495
2496 #if MEDIAINFO_DEMUX
2497 if (Config->Demux_EventWasSent)
2498 {
2499 if (!Element_WantNextLevel)
2500 Element_End0();
2501 return false;
2502 }
2503 #endif //MEDIAINFO_DEMUX
2504
2505 #if MEDIAINFO_TRACE
2506 if (Element_Level>0)
2507 Element[Element_Level-1].TraceNode.NoShow=Element[Element_Level].TraceNode.NoShow; //If data must not be shown, we hide the header too
2508 else
2509 Element[0].TraceNode.NoShow=false; //This should never happen, but in case of
2510 #endif //MEDIAINFO_TRACE
2511 if (!Element_WantNextLevel)
2512 Element_End0(); //Element
2513 Element[Element_Level].UnTrusted=false;
2514
2515 //Jumping to the end of the file if needed
2516 if (!EOF_AlreadyDetected && Config->ParseSpeed<1 && File_GoTo==(int64u)-1)
2517 {
2518 Element[Element_Level].WaitForMoreData=false;
2519 Detect_EOF();
2520 if ((File_GoTo!=(int64u)-1 && File_GoTo>File_Offset+Buffer_Offset) || (Status[IsFinished] && !ShouldContinueParsing))
2521 {
2522 EOF_AlreadyDetected=true;
2523 return false;
2524 }
2525 }
2526
2527 return true;
2528 }
2529
2530 //---------------------------------------------------------------------------
2531 #if MEDIAINFO_TRACE
Data_Info(const Ztring & Parameter)2532 void File__Analyze::Data_Info (const Ztring &Parameter)
2533 {
2534 size_t Element_Level_Temp=Element_Level;
2535 Element_Level=Data_Level;
2536 Element_Info(Parameter);
2537 Element_Level=Element_Level_Temp;
2538 }
2539 #endif //MEDIAINFO_TRACE
2540
2541 //---------------------------------------------------------------------------
2542 #if MEDIAINFO_TRACE
Data_Accept(const char * ParserName)2543 void File__Analyze::Data_Accept (const char* ParserName)
2544 {
2545 if (Status[IsAccepted] || Status[IsFinished])
2546 return;
2547
2548 if (ParserName)
2549 Info(std::string(ParserName)+", accepted");
2550
2551 Accept(ParserName);
2552 }
2553 #endif //MEDIAINFO_TRACE
2554
2555 //---------------------------------------------------------------------------
2556 #if MEDIAINFO_TRACE
Data_Finish(const char * ParserName)2557 void File__Analyze::Data_Finish (const char* ParserName)
2558 {
2559 if (ShouldContinueParsing)
2560 {
2561 if (ParserName)
2562 Info(std::string(ParserName)+", wants to finish, but should continue parsing");
2563 return;
2564 }
2565
2566 if (ParserName)
2567 Info(std::string(ParserName)+", finished");
2568
2569 Finish();
2570 }
2571 #endif //MEDIAINFO_TRACE
2572
2573 //---------------------------------------------------------------------------
2574 #if MEDIAINFO_TRACE
Data_Reject(const char * ParserName)2575 void File__Analyze::Data_Reject (const char* ParserName)
2576 {
2577 Status[IsAccepted]=false;
2578 Status[IsFinished]=true;
2579 Clear();
2580
2581 if (ParserName)// && File_Offset+Buffer_Offset+Element_Size<File_Size)
2582 Info(std::string(ParserName)+", rejected");
2583 }
2584 #endif //MEDIAINFO_TRACE
2585
2586 //---------------------------------------------------------------------------
2587 #if MEDIAINFO_TRACE
Data_GoTo(int64u GoTo_,const char * ParserName)2588 void File__Analyze::Data_GoTo (int64u GoTo_, const char* ParserName)
2589 {
2590 Element_Show();
2591
2592 if (ShouldContinueParsing)
2593 {
2594 if (ParserName)
2595 Info(std::string(ParserName)+", wants to go to somewhere, but should continue parsing");
2596 return;
2597 }
2598
2599 if (IsSub)
2600 {
2601 if (ParserName)
2602 Info(std::string(ParserName)+", wants to go to somewhere, but is sub, waiting data");
2603 return;
2604 }
2605
2606 if (ParserName)
2607 Info(std::string(ParserName)+", jumping to offset "+Ztring::ToZtring(GoTo_, 16).To_UTF8());
2608 GoTo(GoTo_);
2609 }
2610 #endif //MEDIAINFO_TRACE
2611
2612 //---------------------------------------------------------------------------
2613 #if MEDIAINFO_TRACE
Data_GoToFromEnd(int64u GoToFromEnd,const char * ParserName)2614 void File__Analyze::Data_GoToFromEnd (int64u GoToFromEnd, const char* ParserName)
2615 {
2616 if (IsSub && Config->ParseSpeed>=1)
2617 return;
2618
2619 if (GoToFromEnd>File_Size)
2620 {
2621 if (ParserName)
2622 Info(std::string(ParserName)+", wants to go to somewhere, but not valid");
2623 return;
2624 }
2625
2626 Data_GoTo(File_Size-GoToFromEnd, ParserName);
2627 }
2628 #endif //MEDIAINFO_TRACE
2629
2630
2631 //***************************************************************************
2632 // Element
2633 //***************************************************************************
2634
2635 //---------------------------------------------------------------------------
Element_Begin()2636 void File__Analyze::Element_Begin()
2637 {
2638 //Level
2639 Element_Level++;
2640
2641 //Element
2642 Element[Element_Level].Code=0;
2643 Element[Element_Level].Next=Element[Element_Level-1].Next;
2644 Element[Element_Level].WaitForMoreData=Element[Element_Level-1].WaitForMoreData;
2645 Element[Element_Level].UnTrusted=Element[Element_Level-1].UnTrusted;
2646 Element[Element_Level].IsComplete=Element[Element_Level-1].IsComplete;
2647
2648 //TraceNode
2649 #if MEDIAINFO_TRACE
2650 Element[Element_Level].TraceNode.Init();
2651 Element[Element_Level].TraceNode.Pos=File_Offset+Buffer_Offset+Element_Offset+BS->OffsetBeforeLastCall_Get(); //TODO: change this, used in Element_End0()
2652 if (Trace_Activated)
2653 Element[Element_Level].TraceNode.Size=Element[Element_Level].Next-(File_Offset+Buffer_Offset+Element_Offset+BS->OffsetBeforeLastCall_Get());
2654 #endif //MEDIAINFO_TRACE
2655 }
2656
2657 //---------------------------------------------------------------------------
2658 #if MEDIAINFO_TRACE
Element_Begin(const Ztring & Name)2659 void File__Analyze::Element_Begin(const Ztring &Name)
2660 {
2661 //Level
2662 Element_Level++;
2663
2664 //Element
2665 Element[Element_Level].Code=0;
2666 Element[Element_Level].Next=Element[Element_Level-1].Next;
2667 Element[Element_Level].WaitForMoreData=false;
2668 Element[Element_Level].UnTrusted=Element[Element_Level-1].UnTrusted;
2669 Element[Element_Level].IsComplete=Element[Element_Level-1].IsComplete;
2670
2671 //TraceNode
2672 Element[Element_Level].TraceNode.Init();
2673 Element[Element_Level].TraceNode.Pos=File_Offset+Buffer_Offset+Element_Offset+BS->OffsetBeforeLastCall_Get(); //TODO: change this, used in Element_End0()
2674 if (Trace_Activated)
2675 {
2676 Element[Element_Level].TraceNode.Size=Element[Element_Level].Next-(File_Offset+Buffer_Offset+Element_Offset+BS->OffsetBeforeLastCall_Get());
2677 Element_Name(Name);
2678 }
2679 }
2680 #endif //MEDIAINFO_TRACE
2681
2682 //---------------------------------------------------------------------------
2683 #if MEDIAINFO_TRACE
Element_Begin(const char * Name)2684 void File__Analyze::Element_Begin(const char* Name)
2685 {
2686 //Level
2687 Element_Level++;
2688
2689 //Element
2690 Element[Element_Level].Code=0;
2691 Element[Element_Level].Next=Element[Element_Level-1].Next;
2692 Element[Element_Level].WaitForMoreData=false;
2693 Element[Element_Level].UnTrusted=Element[Element_Level-1].UnTrusted;
2694 Element[Element_Level].IsComplete=Element[Element_Level-1].IsComplete;
2695
2696 //TraceNode
2697 Element[Element_Level].TraceNode.Init();
2698 if (Trace_Activated)
2699 {
2700 Element[Element_Level].TraceNode.Pos=File_Offset+Buffer_Offset+Element_Offset; //TODO: change this, used in Element_End0()
2701 if (BS_Size)
2702 {
2703 int64u BS_BitOffset=BS_Size-BS->Remain();
2704 Element[Element_Level].TraceNode.Pos+=BS_BitOffset>>3; //Including Bits to Bytes
2705 }
2706 Element[Element_Level].TraceNode.Size=Element[Element_Level].Next-(File_Offset+Buffer_Offset+Element_Offset+BS->OffsetBeforeLastCall_Get());
2707 Element_Name(Name);
2708 }
2709 }
2710 #endif //MEDIAINFO_TRACE
2711
2712 //---------------------------------------------------------------------------
2713 #if MEDIAINFO_TRACE
Element_Name(const Ztring & Name)2714 void File__Analyze::Element_Name(const Ztring &Name)
2715 {
2716 //TraceNode
2717 if (Trace_Activated)
2718 {
2719 if (!Name.empty())
2720 {
2721 Ztring Name2=Name;
2722 Name2.FindAndReplace(__T("\r\n"), __T("__"), 0, Ztring_Recursive);
2723 Name2.FindAndReplace(__T("\r"), __T("_"), 0, Ztring_Recursive);
2724 Name2.FindAndReplace(__T("\n"), __T("_"), 0, Ztring_Recursive);
2725 if (Name2[0]==__T(' '))
2726 Name2[0]=__T('_');
2727 Element[Element_Level].TraceNode.Set_Name(Name2.To_UTF8());
2728 }
2729 else
2730 Element[Element_Level].TraceNode.Set_Name("(Empty)");
2731 }
2732 }
2733 #endif //MEDIAINFO_TRACE
2734
2735 //---------------------------------------------------------------------------
2736 #if MEDIAINFO_TRACE
Element_Parser(const char * Parser)2737 void File__Analyze::Element_Parser(const char* Parser)
2738 {
2739 //Needed?
2740 if (Config_Trace_Level<=0.7)
2741 return;
2742
2743 Element[Element_Level].TraceNode.Infos.push_back(new element_details::Element_Node_Info(Parser, "Parser"));
2744 }
2745 #endif //MEDIAINFO_TRACE
2746
2747 //---------------------------------------------------------------------------
2748 #if MEDIAINFO_TRACE
Element_Error(const char * Message)2749 void File__Analyze::Element_Error(const char* Message)
2750 {
2751 //Needed?
2752 if (Config_Trace_Level<=0.7)
2753 return;
2754
2755 Element[Element_Level].TraceNode.Infos.push_back(new element_details::Element_Node_Info(Message, "Error"));
2756 }
2757 #endif //MEDIAINFO_TRACE
2758
2759 //---------------------------------------------------------------------------
2760 #if MEDIAINFO_TRACE
Param_Error(const char * Message)2761 void File__Analyze::Param_Error(const char* Message)
2762 {
2763 Param_Info(Message, "Error");
2764 }
2765 #endif //MEDIAINFO_TRACE
2766
2767 //---------------------------------------------------------------------------
2768 #if MEDIAINFO_TRACE
Get_Trace_Node(size_t level)2769 element_details::Element_Node *File__Analyze::Get_Trace_Node(size_t level)
2770 {
2771 if (level > Element_Level)
2772 return NULL;
2773
2774 return &Element[level].TraceNode;
2775 }
2776 #endif //MEDIAINFO_TRACE
2777
2778 //---------------------------------------------------------------------------
2779 #if MEDIAINFO_TRACE
Element_End(const Ztring & Name)2780 void File__Analyze::Element_End(const Ztring &Name)
2781 {
2782 //TraceNode
2783 if (Trace_Activated)
2784 {
2785 Element[Element_Level].TraceNode.Size=Element[Element_Level].Next-Element[Element_Level].TraceNode.Pos;
2786 if (!Name.empty())
2787 Element[Element_Level].TraceNode.Set_Name(Name.To_UTF8());
2788 }
2789
2790 Element_End_Common_Flush();
2791 }
2792 #endif //MEDIAINFO_TRACE
2793
2794 //***************************************************************************
2795 // Element - Common
2796 //***************************************************************************
2797
2798 //---------------------------------------------------------------------------
Element_End_Common_Flush()2799 void File__Analyze::Element_End_Common_Flush()
2800 {
2801 #if MEDIAINFO_TRACE
2802 //Size if not filled
2803 if (File_Offset+Buffer_Offset+Element_Offset+BS->Offset_Get()<Element[Element_Level].Next)
2804 Element[Element_Level].TraceNode.Size=File_Offset+Buffer_Offset+Element_Offset+BS->Offset_Get()-Element[Element_Level].TraceNode.Pos;
2805 #endif //MEDIAINFO_TRACE
2806
2807 //Level
2808 if (Element_Level==0)
2809 return;
2810
2811 //Element level
2812 Element_Level--;
2813
2814 //Element
2815 Element[Element_Level].UnTrusted=Element[Element_Level+1].UnTrusted;
2816 Element[Element_Level].WaitForMoreData=Element[Element_Level+1].WaitForMoreData;
2817
2818 #if MEDIAINFO_TRACE
2819 Element_End_Common_Flush_Details();
2820 #endif //MEDIAINFO_TRACE
2821 }
2822
2823 #if MEDIAINFO_TRACE
2824 //---------------------------------------------------------------------------
Element_End_Common_Flush_Details()2825 void File__Analyze::Element_End_Common_Flush_Details()
2826 {
2827 if (Trace_Activated)// && Config_Trace_Level!=0)
2828 {
2829 if (!Element[Element_Level+1].WaitForMoreData && (Element[Element_Level+1].IsComplete || !Element[Element_Level+1].UnTrusted) && !Element[Element_Level+1].TraceNode.NoShow)
2830 {
2831 //Element
2832 Element[Element_Level].TraceNode.Add_Child(&Element[Element_Level+1].TraceNode);
2833
2834 //Info
2835 if (!Element[Element_Level+1].TraceNode.Value.empty())
2836 Element[Element_Level].TraceNode.Value=Element[Element_Level+1].TraceNode.Value;
2837 Element[Element_Level+1].TraceNode.Init();
2838 }
2839 }
2840 }
2841 #endif //MEDIAINFO_TRACE
2842
2843 //---------------------------------------------------------------------------
Element_Prepare(int64u Size)2844 void File__Analyze::Element_Prepare (int64u Size)
2845 {
2846 Element_Offset=0;
2847 Element_Size=Size;
2848 #if MEDIAINFO_TRACE
2849 Element[Element_Level].TraceNode.Size=Size;
2850 #endif //MEDIAINFO_TRACE
2851 }
2852
2853 //***************************************************************************
2854 // Information
2855 //***************************************************************************
2856
2857 //---------------------------------------------------------------------------
2858 #if MEDIAINFO_TRACE
Info(const std::string & Value,size_t Element_Level_Minus)2859 void File__Analyze::Info(const std::string& Value, size_t Element_Level_Minus)
2860 {
2861 if (Config_Trace_Format==MediaInfo_Config::Trace_Format_CSV)
2862 return; //Do not display info
2863
2864 //Handling a different level (only Element_Level_Minus to 1 is currently well supported)
2865
2866 if (Config_Trace_Level==0 || !(Trace_Layers.to_ulong()&Config_Trace_Layers.to_ulong()))
2867 return;
2868
2869 element_details::Element_Node node;
2870 node.Init();
2871 node.Set_Name(Value);
2872 node.IsCat = true;
2873 node.Pos = File_Offset+Buffer_Offset+Element_Offset+BS->Offset_Get();
2874 Element[Element_Level].TraceNode.Add_Child(&node);
2875 }
2876 #endif //MEDIAINFO_TRACE
2877
2878 //***************************************************************************
2879 // Next code planning
2880 //***************************************************************************
2881
2882 //---------------------------------------------------------------------------
NextCode_Add(int64u Code)2883 void File__Analyze::NextCode_Add (int64u Code)
2884 {
2885 NextCode[Code]=true;
2886 }
2887
2888 //---------------------------------------------------------------------------
NextCode_Clear()2889 void File__Analyze::NextCode_Clear ()
2890 {
2891 NextCode.clear();
2892 }
2893
2894 //---------------------------------------------------------------------------
NextCode_Test()2895 bool File__Analyze::NextCode_Test ()
2896 {
2897 if (NextCode.find(Element_Code)==NextCode.end())
2898 {
2899 Trusted_IsNot("Frames are not in the right order");
2900 return false;
2901 }
2902
2903 return true;
2904 }
2905
2906 //***************************************************************************
2907 // Element trusting
2908 //***************************************************************************
2909
2910 //---------------------------------------------------------------------------
2911 #if MEDIAINFO_TRACE
Trusted_IsNot(const char * Reason)2912 void File__Analyze::Trusted_IsNot (const char* Reason)
2913 #else //MEDIAINFO_TRACE
2914 void File__Analyze::Trusted_IsNot ()
2915 #endif //MEDIAINFO_TRACE
2916 {
2917 Element_Offset=Element_Size;
2918 BS->Attach(NULL, 0);
2919
2920 if (!Element[Element_Level].UnTrusted)
2921 {
2922 #if MEDIAINFO_TRACE
2923 Param(Reason, 0);
2924 #endif //MEDIAINFO_TRACE
2925
2926 //Enough data?
2927 if (!Element[Element_Level].IsComplete)
2928 {
2929 Element_WaitForMoreData();
2930 return;
2931 }
2932
2933 Element[Element_Level].UnTrusted=true;
2934 Synched=false;
2935 if (!Status[IsFilled] && Trusted>0)
2936 Trusted--;
2937 }
2938
2939 if (Trusted==0 && !Status[IsAccepted])
2940 Reject();
2941 }
2942
2943 //***************************************************************************
2944 // Actions
2945 //***************************************************************************
2946
2947 //---------------------------------------------------------------------------
2948 #if MEDIAINFO_TRACE
Accept(const char * ParserName_Char)2949 void File__Analyze::Accept (const char* ParserName_Char)
2950 #else //MEDIAINFO_TRACE
2951 void File__Analyze::Accept ()
2952 #endif //MEDIAINFO_TRACE
2953 {
2954 if (Status[IsAccepted] || Status[IsFinished])
2955 return;
2956
2957 //In case of buffer interface without filename
2958 if (!IsSub && !Config->File_FileName_Get().empty())
2959 File_Name=Config->File_FileName_Get();
2960
2961 #if MEDIAINFO_TRACE
2962 if (ParserName.empty() && ParserName_Char)
2963 ParserName = ParserName_Char;
2964
2965 if (!ParserName.empty())
2966 {
2967 bool MustElementBegin=Element_Level?true:false;
2968 if (Element_Level>0)
2969 Element_End0(); //Element
2970 Info(ParserName+", accepted");
2971 if (MustElementBegin)
2972 Element_Level++;
2973 }
2974 #endif //MEDIAINFO_TRACE
2975
2976 Status[IsAccepted]=true;
2977 if (Count_Get(Stream_General)==0)
2978 {
2979 Stream_Prepare(Stream_General);
2980 Streams_Accept();
2981 }
2982
2983 #if MEDIAINFO_EVENTS
2984 if (!IsSub)
2985 {
2986 EVENT_BEGIN (General, Parser_Selected, 0)
2987 std::memset(Event.Name, 0, 16);
2988 if (!ParserName.empty())
2989 strncpy(Event.Name, Ztring().From_UTF8(ParserName).To_Local().c_str(), 15);
2990 EVENT_END ()
2991
2992 #if MEDIAINFO_DEMUX && MEDIAINFO_NEXTPACKET
2993 if (!Demux_EventWasSent_Accept_Specific && Config->NextPacket_Get())
2994 Config->Demux_EventWasSent=true;
2995 #endif //MEDIAINFO_DEMUX && MEDIAINFO_NEXTPACKET
2996 }
2997
2998 Config->Event_Accepted(this);
2999 #endif //MEDIAINFO_EVENTS
3000 }
3001
Accept(File__Analyze * Parser)3002 void File__Analyze::Accept (File__Analyze* Parser)
3003 {
3004 if (Parser==NULL)
3005 return;
3006
3007 Parser->Accept();
3008 }
3009
3010 //---------------------------------------------------------------------------
3011 #if MEDIAINFO_TRACE
Update(const char * ParserName_Char)3012 void File__Analyze::Update (const char* ParserName_Char)
3013 #else //MEDIAINFO_TRACE
3014 void File__Analyze::Update ()
3015 #endif //MEDIAINFO_TRACE
3016 {
3017 if (!Status[IsAccepted])
3018 return;
3019
3020 Open_Buffer_Update();
3021 }
3022
Update(File__Analyze * Parser)3023 void File__Analyze::Update (File__Analyze* Parser)
3024 {
3025 if (Parser==NULL)
3026 return;
3027
3028 Parser->Update();
3029 }
3030
3031 //---------------------------------------------------------------------------
3032 #if MEDIAINFO_TRACE
Fill(const char * ParserName_Char)3033 void File__Analyze::Fill (const char* ParserName_Char)
3034 #else //MEDIAINFO_TRACE
3035 void File__Analyze::Fill ()
3036 #endif //MEDIAINFO_TRACE
3037 {
3038 if (!Status[IsAccepted] || Status[IsFilled] || Status[IsFinished])
3039 return;
3040
3041 #if MEDIAINFO_TRACE
3042 if (ParserName.empty() && ParserName_Char)
3043 ParserName = ParserName_Char;
3044
3045 if (!ParserName.empty())
3046 {
3047 bool MustElementBegin=Element_Level?true:false;
3048 if (Element_Level>0)
3049 Element_End0(); //Element
3050 Info(ParserName+", filling");
3051 if (MustElementBegin)
3052 Element_Level++;
3053 }
3054 #endif //MEDIAINFO_TRACE
3055
3056 Streams_Fill();
3057 Status[IsFilled]=true;
3058 Status[IsUpdated]=true;
3059
3060 //Instantaneous bitrate at the "fill" level
3061 if (File_Size==(int64u)-1 && FrameInfo.PTS!=(int64u)-1 && PTS_Begin!=(int64u)-1 && FrameInfo.PTS-PTS_Begin && StreamKind_Last!=Stream_General && StreamKind_Last!=Stream_Max)
3062 {
3063 Fill(StreamKind_Last, 0, "BitRate_Instantaneous", Buffer_TotalBytes*8*1000000000/(FrameInfo.PTS-PTS_Begin));
3064 Fill_SetOptions(StreamKind_Last, 0, "BitRate_Instantaneous", "N NI");
3065 }
3066 }
3067
Fill(File__Analyze * Parser)3068 void File__Analyze::Fill (File__Analyze* Parser)
3069 {
3070 if (Parser==NULL)
3071 return;
3072
3073 Parser->Fill();
3074 }
3075
3076 //---------------------------------------------------------------------------
3077 #if MEDIAINFO_TRACE
Finish(const char * ParserName_Char)3078 void File__Analyze::Finish (const char* ParserName_Char)
3079 #else //MEDIAINFO_TRACE
3080 void File__Analyze::Finish ()
3081 #endif //MEDIAINFO_TRACE
3082 {
3083 if (Status[IsFinished])
3084 return;
3085
3086 if (!ShouldContinueParsing && !Status[IsFilled])
3087 Fill();
3088
3089 if (ShouldContinueParsing || Config->ParseSpeed>=1)
3090 {
3091 #if MEDIAINFO_TRACE
3092 if (!ParserName.empty())
3093 {
3094 bool MustElementBegin=Element_Level?true:false;
3095 if (Element_Level>0)
3096 Element_End0(); //Element
3097 Info(std::string(ParserName)+", wants to finish, but should continue parsing");
3098 if (MustElementBegin)
3099 Element_Level++;
3100 }
3101 #endif //MEDIAINFO_TRACE
3102
3103 return;
3104 }
3105
3106 ForceFinish();
3107 }
3108
Finish(File__Analyze * Parser)3109 void File__Analyze::Finish (File__Analyze* Parser)
3110 {
3111 ForceFinish(Parser); //The base parser wants, and is prepared to it, so nothing can be cancelled --> ForceFinish() instead of Finish()
3112 }
3113
3114 //---------------------------------------------------------------------------
3115 #if MEDIAINFO_TRACE
ForceFinish(const char * ParserName_Char)3116 void File__Analyze::ForceFinish (const char* ParserName_Char)
3117 #else //MEDIAINFO_TRACE
3118 void File__Analyze::ForceFinish ()
3119 #endif //MEDIAINFO_TRACE
3120 {
3121 if (Status[IsFinished])
3122 return;
3123
3124 #if MEDIAINFO_TRACE
3125 Element_Show(); //If Element_Level is >0, we must show what is in the details buffer
3126 while (Element_Level>0)
3127 Element_End0(); //This is Finish, must flush
3128
3129 if (ParserName.empty() && ParserName_Char)
3130 ParserName = ParserName_Char;
3131
3132 if (!ParserName.empty())
3133 {
3134 bool MustElementBegin=Element_Level?true:false;
3135 if (Element_Level>0)
3136 Element_End0(); //Element
3137 Info(ParserName+", finished");
3138 if (MustElementBegin)
3139 Element_Level++;
3140 }
3141 #endif //MEDIAINFO_TRACE
3142
3143 if (Status[IsAccepted])
3144 {
3145 //Total file size
3146 #if MEDIAINFO_ADVANCED
3147 if (!IsSub && !(!Config->File_IgnoreSequenceFileSize_Get() || Config->File_Names.size()<=1) && Config->ParseSpeed>=1.0 && Config->File_Names.size()>1 && Config->File_Names_Pos+1>=Config->File_Names.size())
3148 {
3149 Fill (Stream_General, 0, General_FileSize, Config->File_Current_Size, 10, true);
3150 }
3151 #endif //MEDIAINFO_ADVANCED
3152
3153 Fill();
3154 #if MEDIAINFO_DEMUX
3155 if (Config->Demux_EventWasSent)
3156 return;
3157 #endif //MEDIAINFO_DEMUX
3158 if (FrameInfo.DTS==(int64u)-1 && FrameInfo_Previous.DTS!=(int64u)-1)
3159 FrameInfo=FrameInfo_Previous;
3160 Streams_Finish();
3161 #if MEDIAINFO_DEMUX
3162 if (Config->Demux_EventWasSent)
3163 return;
3164 #endif //MEDIAINFO_DEMUX
3165 if (Status[IsUpdated])
3166 {
3167 Open_Buffer_Update();
3168 if (IsSub)
3169 Status[IsUpdated]=true; //We want that container merges the result
3170 #if MEDIAINFO_DEMUX
3171 if (Config->Demux_EventWasSent)
3172 return;
3173 #endif //MEDIAINFO_DEMUX
3174 }
3175 Streams_Finish_Global();
3176 #if MEDIAINFO_DEMUX
3177 if (Config->Demux_EventWasSent)
3178 return;
3179 #endif //MEDIAINFO_DEMUX
3180 Ibi_Stream_Finish();
3181 }
3182
3183 Status[IsFinished]=true;
3184
3185 //Real stream size
3186 if (Config->ParseSpeed>=1 && StreamSource==IsStream && Buffer_TotalBytes)
3187 {
3188 //Exception with text streams embedded in video
3189 if (StreamKind_Last==Stream_Text)
3190 StreamKind_Last=Stream_Video;
3191
3192 Fill(StreamKind_Last, 0, "StreamSize", Buffer_TotalBytes, 10, true);
3193 }
3194
3195 //Frame count
3196 if (Config->ParseSpeed>=1 && StreamSource==IsStream && Frame_Count && Frame_Count!=(int64u)-1 && Retrieve(StreamKind_Last, 0, Fill_Parameter(StreamKind_Last, Generic_FrameCount)).empty())
3197 Fill(StreamKind_Last, 0, Fill_Parameter(StreamKind_Last, Generic_FrameCount), Frame_Count);
3198 }
3199
ForceFinish(File__Analyze * Parser)3200 void File__Analyze::ForceFinish (File__Analyze* Parser)
3201 {
3202 if (Parser==NULL)
3203 return;
3204
3205 if (File_Offset+Buffer_Offset+Element_Size>=File_Size)
3206 {
3207 Element_Size=0;
3208 Parser->Buffer_Offset=(size_t)(Parser->File_Size-Parser->File_Offset);
3209 }
3210
3211 Parser->ForceFinish();
3212 }
3213
3214 //---------------------------------------------------------------------------
3215 #if MEDIAINFO_TRACE
Reject(const char * ParserName)3216 void File__Analyze::Reject (const char* ParserName)
3217 #else //MEDIAINFO_TRACE
3218 void File__Analyze::Reject ()
3219 #endif //MEDIAINFO_TRACE
3220 {
3221 Status[IsAccepted]=false;
3222 Status[IsFinished]=true;
3223 Clear();
3224
3225 #if MEDIAINFO_TRACE
3226 if (ParserName)// && File_Offset+Buffer_Offset+Element_Size<File_Size)
3227 {
3228 bool MustElementBegin=Element_Level?true:false;
3229 if (Element_Level>0)
3230 Element_End0(); //Element
3231 Info(std::string(ParserName)+", rejected");
3232 if (MustElementBegin)
3233 Element_Level++;
3234 }
3235 #endif //MEDIAINFO_TRACE
3236 }
3237
Reject(File__Analyze * Parser)3238 void File__Analyze::Reject (File__Analyze* Parser)
3239 {
3240 if (Parser==NULL)
3241 return;
3242
3243 Parser->Reject();
3244 }
3245
3246 //---------------------------------------------------------------------------
3247 #if MEDIAINFO_TRACE
GoTo(int64u GoTo,const char * ParserName)3248 void File__Analyze::GoTo (int64u GoTo, const char* ParserName)
3249 {
3250 if (!Status[IsAccepted])
3251 {
3252 Reject();
3253 return;
3254 }
3255
3256 Element_Show();
3257
3258 if (IsSub && Config->ParseSpeed>=1)
3259 return;
3260
3261 if (GoTo==File_Size)
3262 {
3263 BookMark_Get();
3264 if (File_GoTo==(int64u)-1)
3265 Finish();
3266 return;
3267 }
3268
3269 if (ShouldContinueParsing)
3270 {
3271 if (ParserName)
3272 {
3273 bool MustElementBegin=Element_Level?true:false;
3274 if (Element_Level>0)
3275 Element_End0(); //Element
3276 Info(std::string(ParserName)+", wants to go to somewhere, but should continue parsing");
3277 if (MustElementBegin)
3278 Element_Level++;
3279 }
3280 return;
3281 }
3282
3283 if (IsSub)
3284 {
3285 if (ParserName)
3286 {
3287 bool MustElementBegin=Element_Level?true:false;
3288 if (Element_Level>0)
3289 Element_End0(); //Element
3290 Info(std::string(ParserName)+", wants to go to somewhere, but is sub, waiting data");
3291 if (MustElementBegin)
3292 Element_Level++;
3293 }
3294 return;
3295 }
3296
3297 if (ParserName)
3298 {
3299 bool MustElementBegin=Element_Level?true:false;
3300 switch (Config_Trace_Format)
3301 {
3302 case MediaInfo_Config::Trace_Format_XML : break;
3303 case MediaInfo_Config::Trace_Format_MICRO_XML : break;
3304 default : //TODO: find a better way to display jumps, both XML and Text
3305 if (Element_Level>0)
3306 Element_End0(); //Element
3307 Info(std::string(ParserName)+", jumping to offset "+Ztring::ToZtring(GoTo, 16).To_UTF8());
3308 if (MustElementBegin)
3309 Element_Level++; //Element
3310 }
3311 }
3312
3313 File_GoTo=GoTo;
3314
3315 #if MEDIAINFO_EVENTS
3316 EVENT_BEGIN (General, Move_Request, 0)
3317 Event.StreamOffset=File_GoTo;
3318 EVENT_END ()
3319 #endif //MEDIAINFO_EVENTS
3320 }
3321 #else //MEDIAINFO_TRACE
GoTo(int64u GoTo)3322 void File__Analyze::GoTo (int64u GoTo)
3323 {
3324 if (!Status[IsAccepted])
3325 {
3326 Reject();
3327 return;
3328 }
3329
3330 if (IsSub && Config->ParseSpeed>=1)
3331 return;
3332
3333 if (GoTo==File_Size)
3334 {
3335 BookMark_Get();
3336 if (File_GoTo==(int64u)-1)
3337 ForceFinish();
3338 return;
3339 }
3340
3341 if (ShouldContinueParsing)
3342 {
3343 return;
3344 }
3345
3346 if (IsSub)
3347 {
3348 return;
3349 }
3350
3351 File_GoTo=GoTo;
3352 }
3353 #endif //MEDIAINFO_TRACE
3354
3355 //---------------------------------------------------------------------------
3356 #if MEDIAINFO_TRACE
GoToFromEnd(int64u GoToFromEnd,const char * ParserName)3357 void File__Analyze::GoToFromEnd (int64u GoToFromEnd, const char* ParserName)
3358 {
3359 if (GoToFromEnd>File_Size)
3360 {
3361 if (ParserName)
3362 {
3363 bool MustElementBegin=Element_Level?true:false;
3364 if (Element_Level>0)
3365 Element_End0(); //Element
3366 Info(std::string(ParserName)+", wants to go to somewhere, but not valid");
3367 if (MustElementBegin)
3368 Element_Level++;
3369 }
3370 return;
3371 }
3372
3373 if (File_Size==(int64u)-1)
3374 {
3375 #if MEDIAINFO_SEEK
3376 if (
3377 #if MEDIAINFO_ADVANCED
3378 Config->File_IgnoreSequenceFileSize_Get() &&
3379 #endif //MEDIAINFO_ADVANCED
3380 GoToFromEnd)
3381 {
3382 File_GoTo=Config->File_Names.size()-1;
3383 File_Offset=(int64u)-1;
3384 Config->File_Current_Offset=(int64u)-1;
3385 Config->File_GoTo_IsFrameOffset=true;
3386 }
3387 else
3388 #endif //MEDIAINFO_SEEK
3389 ForceFinish(); //We can not jump
3390 return;
3391 }
3392
3393 GoTo(File_Size-GoToFromEnd, ParserName);
3394 }
3395 #else //MEDIAINFO_TRACE
GoToFromEnd(int64u GoToFromEnd)3396 void File__Analyze::GoToFromEnd (int64u GoToFromEnd)
3397 {
3398 if (GoToFromEnd>File_Size)
3399 return;
3400
3401 if (File_Size==(int64u)-1)
3402 {
3403 #if MEDIAINFO_SEEK
3404 if (
3405 #if MEDIAINFO_ADVANCED
3406 Config->File_IgnoreSequenceFileSize_Get() &&
3407 #endif //MEDIAINFO_ADVANCED
3408 GoToFromEnd)
3409 {
3410 File_GoTo=Config->File_Names.size()-1;
3411 File_Offset=(int64u)-1;
3412 Config->File_Current_Offset=(int64u)-1;
3413 Config->File_GoTo_IsFrameOffset=true;
3414 }
3415 else
3416 #endif //MEDIAINFO_SEEK
3417 ForceFinish(); //We can not jump
3418 return;
3419 }
3420
3421 GoTo(File_Size-GoToFromEnd);
3422 }
3423 #endif //MEDIAINFO_TRACE
3424
3425 //---------------------------------------------------------------------------
Element_Code_Get(size_t Level)3426 int64u File__Analyze::Element_Code_Get (size_t Level)
3427 {
3428 return Element[Level].Code;
3429 }
3430
3431 //---------------------------------------------------------------------------
Element_TotalSize_Get(size_t LevelLess)3432 int64u File__Analyze::Element_TotalSize_Get (size_t LevelLess)
3433 {
3434 return Element[Element_Level-LevelLess].Next-(File_Offset+Buffer_Offset);
3435 }
3436
3437 //---------------------------------------------------------------------------
Element_IsComplete_Get()3438 bool File__Analyze::Element_IsComplete_Get ()
3439 {
3440 return Element[Element_Level].IsComplete;
3441 }
3442
3443 //---------------------------------------------------------------------------
Element_ThisIsAList()3444 void File__Analyze::Element_ThisIsAList ()
3445 {
3446 Element_WantNextLevel=true;
3447 }
3448
3449 //---------------------------------------------------------------------------
Element_WaitForMoreData()3450 void File__Analyze::Element_WaitForMoreData ()
3451 {
3452 //if (File_Offset+Buffer_Size<File_Size)
3453 Element[Element_Level].WaitForMoreData=true;
3454 }
3455
3456 //---------------------------------------------------------------------------
3457 #if MEDIAINFO_TRACE
Element_DoNotTrust(const char * Reason)3458 void File__Analyze::Element_DoNotTrust (const char* Reason)
3459 #else //MEDIAINFO_TRACE
3460 void File__Analyze::Element_DoNotTrust ()
3461 #endif //MEDIAINFO_TRACE
3462 {
3463 Element[Element_Level].WaitForMoreData=false;
3464 Element[Element_Level].IsComplete=true;
3465 #if MEDIAINFO_TRACE
3466 Trusted_IsNot(Reason);
3467 #else //MEDIAINFO_TRACE
3468 Trusted_IsNot();
3469 #endif //MEDIAINFO_TRACE
3470 }
3471
3472 //---------------------------------------------------------------------------
3473 #if MEDIAINFO_TRACE
Element_DoNotShow()3474 void File__Analyze::Element_DoNotShow ()
3475 {
3476 Element[Element_Level].TraceNode.NoShow=true;
3477 }
3478 #endif //MEDIAINFO_TRACE
3479
3480 //---------------------------------------------------------------------------
3481 #if MEDIAINFO_TRACE
Element_DoNotShow_Children()3482 void File__Analyze::Element_DoNotShow_Children ()
3483 {
3484 for (size_t i = 0; i < Element[Element_Level].TraceNode.Children.size(); ++i)
3485 {
3486 if (!Element[Element_Level].TraceNode.Children[i])
3487 continue;
3488 Element[Element_Level].TraceNode.Children[i]->NoShow=true;
3489 }
3490 }
3491 #endif //MEDIAINFO_TRACE
3492
3493 //---------------------------------------------------------------------------
3494 #if MEDIAINFO_TRACE
Element_Remove_Children_IfNoErrors()3495 void File__Analyze::Element_Remove_Children_IfNoErrors ()
3496 {
3497 for (size_t i = 0; i < Element[Element_Level].TraceNode.Children.size(); ++i)
3498 {
3499 if (!Element[Element_Level].TraceNode.Children[i])
3500 continue;
3501 delete Element[Element_Level].TraceNode.Children[i];
3502 Element[Element_Level].TraceNode.Children[i] = NULL;
3503 }
3504
3505 Element[Element_Level].TraceNode.Children.clear();
3506 }
3507 #endif //MEDIAINFO_TRACE
3508
3509 //---------------------------------------------------------------------------
3510 #if MEDIAINFO_TRACE
Element_Children_IfNoErrors()3511 void File__Analyze::Element_Children_IfNoErrors ()
3512 {
3513 if (Element[Element_Level].TraceNode.HasError)
3514 return;
3515
3516 //TODO: option to keep the nodes
3517 // Element_DoNotShow_Children();
3518 Element_Remove_Children_IfNoErrors();
3519 }
3520 #endif //MEDIAINFO_TRACE
3521
3522 //---------------------------------------------------------------------------
3523 #if MEDIAINFO_TRACE
Element_Set_Remove_Children_IfNoErrors()3524 void File__Analyze::Element_Set_Remove_Children_IfNoErrors ()
3525 {
3526 Element[Element_Level].TraceNode.RemoveIfNoErrors = true;
3527 }
3528 #endif //MEDIAINFO_TRACE
3529
3530 //---------------------------------------------------------------------------
3531 #if MEDIAINFO_TRACE
Element_Show()3532 void File__Analyze::Element_Show ()
3533 {
3534 Element[Element_Level].TraceNode.NoShow=false;
3535 }
3536 #endif //MEDIAINFO_TRACE
3537
3538 //---------------------------------------------------------------------------
3539 #if MEDIAINFO_TRACE
Element_Show_Children()3540 void File__Analyze::Element_Show_Children ()
3541 {
3542 for (size_t i = 0; i < Element[Element_Level].TraceNode.Children.size(); ++i)
3543 {
3544 if (!Element[Element_Level].TraceNode.Children[i])
3545 continue;
3546 Element[Element_Level].TraceNode.Children[i]->NoShow=false;
3547 }
3548 }
3549 #endif //MEDIAINFO_TRACE
3550
3551 //---------------------------------------------------------------------------
3552 #if MEDIAINFO_TRACE
Element_Show_Get()3553 bool File__Analyze::Element_Show_Get ()
3554 {
3555 return !Element[Element_Level].TraceNode.NoShow;
3556 }
3557 #endif //MEDIAINFO_TRACE
3558
3559 //---------------------------------------------------------------------------
3560 #if MEDIAINFO_TRACE
Element_Show_Add(File__Analyze * node)3561 void File__Analyze::Element_Show_Add (File__Analyze* node)
3562 {
3563 if (!node)
3564 return;
3565
3566 //From Sub
3567 Element[Element_Level].TraceNode.Add_Child(&node->Element[0].TraceNode);
3568 node->Element[0].TraceNode.Init();
3569 }
3570 #endif //MEDIAINFO_TRACE
3571
3572 #if MEDIAINFO_TRACE
Trace_Layers_Update(size_t Layer)3573 void File__Analyze::Trace_Layers_Update(size_t Layer)
3574 {
3575 if (Layer!=(size_t)-1)
3576 {
3577 Trace_Layers.reset();
3578 Trace_Layers.set(Layer);
3579 }
3580 Trace_Activated=(Config_Trace_Level!=0 && (Trace_Layers&Config_Trace_Layers)!=0);
3581 }
3582 #endif //MEDIAINFO_TRACE
3583
3584 //***************************************************************************
3585 // Status
3586 //***************************************************************************
3587
3588 //---------------------------------------------------------------------------
Element_IsOK()3589 bool File__Analyze::Element_IsOK ()
3590 {
3591 #if !MEDIAINFO_TRACE
3592 if (BS && BS->BufferUnderRun)
3593 Trusted_IsNot();
3594 #endif //MEDIAINFO_TRACE
3595
3596 return !Element[Element_Level].WaitForMoreData && !Element[Element_Level].UnTrusted;
3597 }
3598
3599 //---------------------------------------------------------------------------
Element_IsNotFinished()3600 bool File__Analyze::Element_IsNotFinished ()
3601 {
3602 if (BS->Remain()>0 || Element_Offset+BS->Offset_Get()<Element_Size)
3603 return true;
3604 else
3605 return false;
3606 }
3607
3608 //---------------------------------------------------------------------------
Element_IsWaitingForMoreData()3609 bool File__Analyze::Element_IsWaitingForMoreData ()
3610 {
3611 return Element[Element_Level].WaitForMoreData;
3612 }
3613
3614 //***************************************************************************
3615 // BookMarks
3616 //***************************************************************************
3617
3618 //---------------------------------------------------------------------------
BookMark_Set(size_t Element_Level_ToSet)3619 void File__Analyze::BookMark_Set (size_t Element_Level_ToSet)
3620 {
3621 Element_Level_ToSet=Element_Level;
3622 BookMark_Element_Level=Element_Level_ToSet;
3623 BookMark_Code.resize(BookMark_Element_Level+1);
3624 BookMark_Next.resize(BookMark_Element_Level+1);
3625 for (size_t Pos=0; Pos<=BookMark_Element_Level; Pos++)
3626 {
3627 BookMark_Code[Pos]=Element[Pos].Code;
3628 BookMark_Next[Pos]=Element[Pos].Next;
3629 }
3630 BookMark_GoTo=File_Offset+Buffer_Offset+Element_Offset;
3631 }
3632
3633 //---------------------------------------------------------------------------
BookMark_Get()3634 void File__Analyze::BookMark_Get ()
3635 {
3636 if (!BookMark_Needed())
3637 return;
3638
3639 Element_Show();
3640 while (Element_Level>0)
3641 Element_End0();
3642 while (Element_Level<BookMark_Element_Level)
3643 {
3644 Element_Begin1("Restarting parsing...");
3645 Element_WantNextLevel=true;
3646 }
3647
3648 if (!BookMark_Code.empty())
3649 {
3650 for (size_t Pos=0; Pos<=BookMark_Element_Level; Pos++)
3651 {
3652 Element[Pos].Code=BookMark_Code[Pos];
3653 Element[Pos].Next=BookMark_Next[Pos];
3654 }
3655 BookMark_Code.clear();
3656 BookMark_Next.clear();
3657 BookMark_Element_Level=0;
3658 }
3659 if (File_GoTo==(int64u)-1)
3660 {
3661 File_GoTo=BookMark_GoTo;
3662 }
3663 }
3664
3665 //---------------------------------------------------------------------------
3666 #if MEDIAINFO_TRACE
Details_Clear()3667 void File__Analyze::Details_Clear()
3668 {
3669 Details->clear();
3670 Element[0].TraceNode.Init();
3671 }
3672 #endif //MEDIAINFO_TRACE
3673
3674 #if MEDIAINFO_EVENTS
Event_Prepare(struct MediaInfo_Event_Generic * Event,int32u Event_Code,size_t Event_Size)3675 void File__Analyze::Event_Prepare(struct MediaInfo_Event_Generic* Event, int32u Event_Code, size_t Event_Size)
3676 {
3677 memset(Event, 0x00, Event_Size);
3678 Event->EventCode=Event_Code;
3679 Event->EventSize=Event_Size;
3680 Event->StreamIDs_Size=StreamIDs_Size;
3681 memcpy_Unaligned_Unaligned_Once1024(Event->StreamIDs, StreamIDs, 128);
3682 memcpy(Event->StreamIDs_Width, StreamIDs_Width, sizeof(StreamIDs_Width));
3683 memcpy(Event->ParserIDs, ParserIDs, sizeof(ParserIDs));
3684 Event->StreamOffset=File_Offset+Buffer_Offset+Element_Offset;
3685 Event->FrameNumber=Frame_Count_NotParsedIncluded;
3686 Event->PCR=FrameInfo.PCR;
3687 Event->DTS=(FrameInfo.DTS==(int64u)-1?FrameInfo.PTS:FrameInfo.DTS);
3688 Event->PTS=FrameInfo.PTS;
3689 Event->DUR=FrameInfo.DUR;
3690 //Event->FrameNumber_PresentationOrder=FrameNumber_PresentationOrder;
3691 }
3692 #endif //MEDIAINFO_EVENTS
3693
3694 //***************************************************************************
3695 // Demux
3696 //***************************************************************************
3697 #if MEDIAINFO_DEMUX
Demux(const int8u * Buffer,size_t Buffer_Size,contenttype Content_Type,const int8u * xx,size_t xxx)3698 void File__Analyze::Demux (const int8u* Buffer, size_t Buffer_Size, contenttype Content_Type, const int8u* xx, size_t xxx)
3699 {
3700 if (!(Config_Demux&Demux_Level))
3701 return;
3702
3703 if (!Buffer_Size)
3704 return;
3705
3706 #if MEDIAINFO_DEMUX && MEDIAINFO_SEEK
3707 if (Config->Demux_IsSeeking)
3708 return;
3709 #endif //MEDIAINFO_SEEK
3710
3711 #if MEDIAINFO_EVENTS
3712 //Demux
3713 if (StreamIDs_Size)
3714 StreamIDs[StreamIDs_Size-1]=Element_Code;
3715
3716 EVENT_BEGIN(Global, Demux, 4)
3717 if (StreamIDs_Size)
3718 Event.EventCode|=((int32u)ParserIDs[StreamIDs_Size-1]<<24);
3719 Event.Content_Type=(int8u)Content_Type;
3720 Event.Content_Size=Buffer_Size;
3721 Event.Content=Buffer;
3722 Event.Flags=0;
3723 if (Demux_random_access)
3724 Event.Flags|=0x1; //Bit 0
3725 Event.Offsets_Size=Offsets_Buffer.size();
3726 std::vector<int64u> Offsets_Stream_Temp;
3727 std::vector<int64u> Offsets_Buffer_Temp;
3728 float64 Ratio=1;
3729 if (OriginalBuffer_Size)
3730 Ratio=((float64)File__Analyze::OriginalBuffer_Size)/File__Analyze::Buffer_Size;
3731 if (Offsets_Buffer.empty())
3732 {
3733 Event.Offsets_Stream=NULL;
3734 Event.Offsets_Content=NULL;
3735 }
3736 else if (Buffer_Offset+Element_Offset)
3737 {
3738 Offsets_Stream_Temp=Offsets_Stream;
3739 Offsets_Buffer_Temp=Offsets_Buffer;
3740 size_t Pos=0;
3741 if (Offsets_Buffer.size()>=2 && Offsets_Buffer.size()%2==0 && Offsets_Buffer[0]==Offsets_Buffer[1])
3742 {
3743 while (Pos+2<Offsets_Buffer_Temp.size() && Offsets_Buffer_Temp[Pos+2]<Buffer_Offset+Element_Offset)
3744 Pos+=2;
3745 if (Pos)
3746 {
3747 Offsets_Buffer_Temp.erase(Offsets_Buffer_Temp.begin(), Offsets_Buffer_Temp.begin()+Pos);
3748 Offsets_Stream_Temp.erase(Offsets_Stream_Temp.begin(), Offsets_Stream_Temp.begin()+Pos);
3749 Event.Offsets_Size-=Pos;
3750 }
3751 Offsets_Stream_Temp[0]+=(Buffer_Offset+Element_Offset)/2-Offsets_Buffer_Temp[0];
3752 Offsets_Stream_Temp[1]+=(Buffer_Offset+Element_Offset)/2-Offsets_Buffer_Temp[1];
3753 Offsets_Buffer_Temp[0]=0;
3754 Offsets_Buffer_Temp[1]=0;
3755 for (size_t Pos=2; Pos<Offsets_Buffer_Temp.size(); Pos+=2)
3756 {
3757 Offsets_Buffer_Temp[Pos]-=(Buffer_Offset+Element_Offset)/2;
3758 Offsets_Buffer_Temp[Pos+1]-=(Buffer_Offset+Element_Offset)/2;
3759 }
3760 }
3761 else
3762 {
3763 while (Pos+1<Offsets_Buffer_Temp.size() && Offsets_Buffer_Temp[Pos+1]<(Buffer_Offset+Element_Offset)*Ratio)
3764 Pos++;
3765 if (Pos)
3766 {
3767 Offsets_Buffer_Temp.erase(Offsets_Buffer_Temp.begin(), Offsets_Buffer_Temp.begin()+Pos);
3768 Offsets_Stream_Temp.erase(Offsets_Stream_Temp.begin(), Offsets_Stream_Temp.begin()+Pos);
3769 Event.Offsets_Size-=Pos;
3770 }
3771 Offsets_Stream_Temp[0]+=float64_int64s((Buffer_Offset+Element_Offset)*Ratio)-Offsets_Buffer_Temp[0];
3772 Offsets_Buffer_Temp[0]=0;
3773 for (size_t Pos=1; Pos<Offsets_Buffer_Temp.size(); Pos++)
3774 Offsets_Buffer_Temp[Pos]-=float64_int64s((Buffer_Offset+Element_Offset)*Ratio);
3775 }
3776 Event.Offsets_Stream=&Offsets_Stream_Temp.front();
3777 Event.Offsets_Content=&Offsets_Buffer_Temp.front();
3778 }
3779 else
3780 {
3781 Event.Offsets_Stream=&Offsets_Stream.front();
3782 Event.Offsets_Content=&Offsets_Buffer.front();
3783 }
3784 Event.OriginalContent_Size=OriginalBuffer_Size?((size_t)float64_int64s(((float64)(Element_Size-Element_Offset))*Ratio)):0;
3785 Event.OriginalContent=OriginalBuffer_Size?(OriginalBuffer+(size_t)float64_int64s(((float64)(Buffer_Offset+Element_Offset))*Ratio)):NULL;
3786 EVENT_END()
3787
3788 if (StreamIDs_Size)
3789 StreamIDs[StreamIDs_Size-1]=(int64u)-1;
3790 #if MEDIAINFO_DEMUX && MEDIAINFO_NEXTPACKET
3791 if (Status[IsAccepted] && Config->NextPacket_Get())
3792 Config->Demux_EventWasSent=true;
3793 #endif //MEDIAINFO_DEMUX && MEDIAINFO_NEXTPACKET
3794 if (StreamIDs_Size)
3795 StreamIDs[StreamIDs_Size-1]=(int64u)-1;
3796 #endif //MEDIAINFO_EVENTS
3797 }
3798 #endif //MEDIAINFO_DEMUX
3799
3800 #if MEDIAINFO_DEMUX
Demux_UnpacketizeContainer_Demux(bool random_access)3801 void File__Analyze::Demux_UnpacketizeContainer_Demux (bool random_access)
3802 {
3803 Demux_random_access=random_access;
3804
3805 if (StreamIDs_Size>=2)
3806 Element_Code=StreamIDs[StreamIDs_Size-2];
3807 StreamIDs_Size--;
3808 Demux(Buffer+Buffer_Offset, Demux_Offset-Buffer_Offset, ContentType_MainStream);
3809 StreamIDs_Size++;
3810 if (StreamIDs_Size>=2)
3811 StreamIDs[StreamIDs_Size-2]=Element_Code;
3812 Demux_UnpacketizeContainer_Demux_Clear();
3813 }
3814
Demux_UnpacketizeContainer_Test_OneFramePerFile()3815 bool File__Analyze::Demux_UnpacketizeContainer_Test_OneFramePerFile ()
3816 {
3817 if (!IsSub && Buffer_Size<Config->File_Current_Size-Config->File_Current_Offset)
3818 {
3819 size_t* File_Buffer_Size_Hint_Pointer=Config->File_Buffer_Size_Hint_Pointer_Get();
3820 if (File_Buffer_Size_Hint_Pointer)
3821 (*File_Buffer_Size_Hint_Pointer) = (size_t)(Config->File_Current_Size - Config->File_Current_Offset - Buffer_Size);
3822 return false;
3823 }
3824
3825 float64 Demux_Rate=Config->Demux_Rate_Get();
3826 if (!Demux_Rate)
3827 Demux_Rate=24;
3828 if (Frame_Count_NotParsedIncluded!=(int64u)-1)
3829 FrameInfo.DTS=float64_int64s(Frame_Count_NotParsedIncluded*1000000000/Demux_Rate);
3830 else
3831 FrameInfo.DTS=(int64u)-1;
3832 FrameInfo.PTS=FrameInfo.DTS;
3833 FrameInfo.DUR=float64_int64s(1000000000/Demux_Rate);
3834 Demux_Offset=Buffer_Size;
3835 Demux_UnpacketizeContainer_Demux();
3836
3837 return true;
3838 }
3839
Demux_UnpacketizeContainer_Demux_Clear()3840 void File__Analyze::Demux_UnpacketizeContainer_Demux_Clear ()
3841 {
3842 Demux_TotalBytes=Buffer_TotalBytes+Demux_Offset;
3843 Demux_Offset=0;
3844 //if (Frame_Count || Field_Count)
3845 // Element_End0();
3846 //Element_Begin1("Frame or Field");
3847 }
3848 #endif //MEDIAINFO_DEMUX
3849
3850 //***************************************************************************
3851 // Decode
3852 //***************************************************************************
3853
3854 #if MEDIAINFO_DECODE
3855
3856 //---------------------------------------------------------------------------
Decoded(const int8u * Buffer,size_t Buffer_Size)3857 void File__Analyze::Decoded (const int8u* Buffer, size_t Buffer_Size)
3858 {
3859 if (!Buffer_Size)
3860 return;
3861
3862 #if MEDIAINFO_EVENTS
3863 //Demux
3864 if (StreamIDs_Size)
3865 StreamIDs[StreamIDs_Size-1]=Element_Code;
3866
3867 EVENT_BEGIN(Global, Decoded, 0)
3868 if (StreamIDs_Size)
3869 Event.EventCode|=((int32u)ParserIDs[StreamIDs_Size-1]<<24);
3870 Event.Content_Size=Buffer_Size;
3871 Event.Content=Buffer;
3872 Event.Flags=0;
3873 EVENT_END()
3874 #endif //MEDIAINFO_EVENTS
3875 }
3876
3877 #endif //MEDIAINFO_DECODE
3878
3879 //***************************************************************************
3880 // IBI
3881 //***************************************************************************
3882 #if MEDIAINFO_IBIUSAGE
Ibi_Read_Buffer_Unsynched()3883 void File__Analyze::Ibi_Read_Buffer_Unsynched ()
3884 {
3885 Ibi_SynchronizationOffset_Current=(int64u)-1;
3886
3887 if (IbiStream==NULL)
3888 return;
3889
3890 IbiStream->Unsynch();
3891 for (size_t Pos=0; Pos<IbiStream->Infos.size(); Pos++)
3892 {
3893 if (File_GoTo==IbiStream->Infos[Pos].StreamOffset)
3894 {
3895 FrameInfo.DTS=(IbiStream->Infos[Pos].Dts!=(int64u)-1)?float64_int64s((((float64)IbiStream->Infos[Pos].Dts)*1000000000*IbiStream->DtsFrequencyDenominator/IbiStream->DtsFrequencyNumerator)):(int64u)-1;
3896 Frame_Count_NotParsedIncluded=IbiStream->Infos[Pos].FrameNumber;
3897 break;
3898 }
3899 }
3900 }
3901
3902 #if MEDIAINFO_SEEK
Ibi_Read_Buffer_Seek(size_t Method,int64u Value,int64u ID)3903 size_t File__Analyze::Ibi_Read_Buffer_Seek (size_t Method, int64u Value, int64u ID)
3904 {
3905 if (IbiStream==NULL)
3906 return (size_t)-1;
3907
3908 //Init
3909 if (!Seek_Duration_Detected)
3910 {
3911 if (!IsSub)
3912 {
3913 //External IBI
3914 std::string IbiFile=Config->Ibi_Get();
3915 if (!IbiFile.empty())
3916 {
3917 IbiStream->Infos.clear(); //TODO: support IBI data from different inputs
3918
3919 File_Ibi MI;
3920 Open_Buffer_Init(&MI, IbiFile.size());
3921 MI.Ibi=new ibi;
3922 MI.Open_Buffer_Continue((const int8u*)IbiFile.c_str(), IbiFile.size());
3923 (*IbiStream)=(*MI.Ibi->Streams.begin()->second);
3924 }
3925 }
3926
3927 Seek_Duration_Detected=true;
3928 }
3929
3930 //Parsing
3931 switch (Method)
3932 {
3933 case 0 :
3934 #if MEDIAINFO_IBI
3935 {
3936 for (size_t Pos=0; Pos<IbiStream->Infos.size(); Pos++)
3937 {
3938 if (Value<=IbiStream->Infos[Pos].StreamOffset)
3939 {
3940 if (Value<IbiStream->Infos[Pos].StreamOffset && Pos)
3941 Pos--;
3942
3943 //Checking continuity of Ibi
3944 if (!IbiStream->Infos[Pos].IsContinuous && Pos+1<IbiStream->Infos.size())
3945 {
3946 Config->Demux_IsSeeking=true;
3947 GoTo((IbiStream->Infos[Pos].StreamOffset+IbiStream->Infos[Pos+1].StreamOffset)/2);
3948 Open_Buffer_Unsynch();
3949
3950 return 1;
3951 }
3952
3953 Config->Demux_IsSeeking=false;
3954
3955 GoTo(IbiStream->Infos[Pos].StreamOffset);
3956 Open_Buffer_Unsynch();
3957
3958 return 1;
3959 }
3960 }
3961
3962 if (IbiStream->Infos.empty())
3963 {
3964 GoTo(0);
3965 Open_Buffer_Unsynch();
3966 }
3967 else if (!IbiStream->Infos[IbiStream->Infos.size()-1].IsContinuous)
3968 {
3969 GoTo(IbiStream->Infos[IbiStream->Infos.size()-1].StreamOffset);
3970 Open_Buffer_Unsynch();
3971 }
3972 else
3973 return 2; //Invalid value
3974 return 1;
3975 }
3976 #else //MEDIAINFO_IBI
3977 return (size_t)-2; //Not supported / IBI disabled
3978 #endif //MEDIAINFO_IBI
3979 case 1 :
3980 return Ibi_Read_Buffer_Seek(0, File_Size*Value/10000, ID);
3981 case 2 : //Timestamp
3982 #if MEDIAINFO_IBI
3983 {
3984 if (!(IbiStream->DtsFrequencyNumerator==1000000000 && IbiStream->DtsFrequencyDenominator==1))
3985 {
3986 float64 ValueF=(float64)Value;
3987 ValueF/=1000000000; //Value is in ns
3988 ValueF/=IbiStream->DtsFrequencyDenominator;
3989 ValueF*=IbiStream->DtsFrequencyNumerator;
3990 Value=float64_int64s(ValueF);
3991 }
3992
3993 for (size_t Pos=0; Pos<IbiStream->Infos.size(); Pos++)
3994 {
3995 if (Value<=IbiStream->Infos[Pos].Dts)
3996 {
3997 if (Value<IbiStream->Infos[Pos].Dts && Pos)
3998 Pos--;
3999
4000 //Checking continuity of Ibi
4001 if (!IbiStream->Infos[Pos].IsContinuous && Pos+1<IbiStream->Infos.size())
4002 {
4003 Config->Demux_IsSeeking=true;
4004 GoTo((IbiStream->Infos[Pos].StreamOffset+IbiStream->Infos[Pos+1].StreamOffset)/2);
4005 Open_Buffer_Unsynch();
4006
4007 return 1;
4008 }
4009
4010 Config->Demux_IsSeeking=false;
4011
4012 GoTo(IbiStream->Infos[Pos].StreamOffset);
4013 Open_Buffer_Unsynch();
4014
4015 return 1;
4016 }
4017 }
4018
4019 if (IbiStream->Infos.empty())
4020 {
4021 GoTo(0);
4022 Open_Buffer_Unsynch();
4023 }
4024 else if (!IbiStream->Infos[IbiStream->Infos.size()-1].IsContinuous)
4025 {
4026 GoTo(IbiStream->Infos[IbiStream->Infos.size()-1].StreamOffset);
4027 Open_Buffer_Unsynch();
4028 }
4029 else
4030 return 2; //Invalid value
4031 return 1;
4032 }
4033 #else //MEDIAINFO_IBI
4034 return (size_t)-2; //Not supported / IBI disabled
4035 #endif //MEDIAINFO_IBI
4036 case 3 : //FrameNumber
4037 #if MEDIAINFO_IBI
4038 {
4039 for (size_t Pos=0; Pos<IbiStream->Infos.size(); Pos++)
4040 {
4041 if (Value<=IbiStream->Infos[Pos].FrameNumber)
4042 {
4043 if (Value<IbiStream->Infos[Pos].FrameNumber && Pos)
4044 Pos--;
4045
4046 //Checking continuity of Ibi
4047 if (!IbiStream->Infos[Pos].IsContinuous && Pos+1<IbiStream->Infos.size())
4048 {
4049 Config->Demux_IsSeeking=true;
4050 GoTo((IbiStream->Infos[Pos].StreamOffset+IbiStream->Infos[Pos+1].StreamOffset)/2);
4051 Open_Buffer_Unsynch();
4052
4053 return 1;
4054 }
4055
4056 Config->Demux_IsSeeking=false;
4057
4058 GoTo(IbiStream->Infos[Pos].StreamOffset);
4059 Open_Buffer_Unsynch();
4060
4061 return 1;
4062 }
4063 }
4064
4065 if (IbiStream->Infos.empty())
4066 {
4067 GoTo(0);
4068 Open_Buffer_Unsynch();
4069 }
4070 else if (!IbiStream->Infos[IbiStream->Infos.size()-1].IsContinuous)
4071 {
4072 GoTo(IbiStream->Infos[IbiStream->Infos.size()-1].StreamOffset);
4073 Open_Buffer_Unsynch();
4074 }
4075 else
4076 return 2; //Invalid value
4077 return 1;
4078 }
4079 #else //MEDIAINFO_IBI
4080 return (size_t)-2; //Not supported / IBI disabled
4081 #endif //MEDIAINFO_IBI
4082 default : return (size_t)-1; //Not supported
4083 }
4084 }
4085 #endif //MEDIAINFO_SEEK
4086 #endif //MEDIAINFO_IBIUSAGE
4087
4088 #if MEDIAINFO_IBIUSAGE
Ibi_Stream_Finish()4089 void File__Analyze::Ibi_Stream_Finish ()
4090 {
4091 if (IsSub)
4092 return;
4093
4094 if (!(IbiStream==NULL || IbiStream->Infos.empty()) && File_Offset+Buffer_Size==File_Size)
4095 {
4096 ibi::stream::info IbiInfo;
4097 IbiInfo.StreamOffset=File_Offset+Buffer_Size;
4098 IbiInfo.FrameNumber=Frame_Count_NotParsedIncluded;
4099 IbiInfo.Dts=(FrameInfo.DTS!=(int64u)-1)?float64_int64s(((float64)FrameInfo.DTS)/1000000000*IbiStream->DtsFrequencyNumerator/IbiStream->DtsFrequencyDenominator):(int64u)-1;
4100 IbiInfo.IsContinuous=true;
4101 IbiStream->Add(IbiInfo);
4102 }
4103
4104 if (Config_Ibi_Create)
4105 {
4106 if (!(IbiStream==NULL || IbiStream->Infos.empty()))
4107 Ibi.Streams[(int64u)-1]=new ibi::stream(*IbiStream);
4108
4109 //Inform_Data
4110 ZtringListList Content;
4111 for (size_t StreamKind=Stream_General; StreamKind<Stream_Max; ++StreamKind)
4112 {
4113 ZtringListList Source=MediaInfoLib::Config.Info_Get((stream_t)StreamKind);
4114
4115 for (size_t StreamPos=0; StreamPos<Count_Get((stream_t)StreamKind); ++StreamPos)
4116 {
4117 ZtringList KindAndPos;
4118 KindAndPos.push_back(Get((stream_t)StreamKind, StreamPos, __T("StreamKind")));
4119 Content.push_back(KindAndPos);
4120
4121 //Standard
4122 for (size_t Pos=0; Pos<Source.size(); ++Pos)
4123 {
4124 Ztring &Options=Source[Pos](Info_Options);
4125 if (InfoOption_ShowInSupported<Options.size() && Options[InfoOption_ShowInSupported]==__T('Y') && Pos<(*Stream)[StreamKind][StreamPos].size() && !(*Stream)[StreamKind][StreamPos][Pos].empty())
4126 {
4127 ZtringList Line;
4128 Line.push_back(Source[Pos][Info_Name]);
4129 Line.push_back((*Stream)[StreamKind][StreamPos][Pos]);
4130 Content.push_back(Line);
4131 }
4132 }
4133
4134 //Additional
4135 for (size_t Pos=0; Pos<(*Stream_More)[StreamKind][StreamPos].size(); ++Pos)
4136 {
4137 ZtringList Line=(*Stream_More)[StreamKind][StreamPos][Pos];
4138 Line.resize(Info_Options+1);
4139 Content.push_back(Line);
4140 }
4141
4142 //Separator
4143 Content.push_back(Ztring());
4144 }
4145 }
4146 if (!Content.empty())
4147 Content.resize(Content.size()-1);
4148 Ibi.Inform_Data=Content.Read();
4149
4150 //IBI Creation
4151 File_Ibi_Creation IbiCreation(Ibi);
4152 Ztring IbiText=IbiCreation.Finish();
4153 if (!IbiText.empty())
4154 {
4155 Fill(Stream_General, 0, "IBI", IbiText);
4156 Fill_SetOptions(Stream_General, 0, "IBI", "N NT");
4157 }
4158 }
4159 }
4160
Ibi_Stream_Finish(int64u Numerator,int64u Denominator)4161 void File__Analyze::Ibi_Stream_Finish (int64u Numerator, int64u Denominator)
4162 {
4163 if (IsSub || IbiStream==NULL)
4164 return;
4165
4166 if (IbiStream->DtsFrequencyNumerator==1000000000 && IbiStream->DtsFrequencyDenominator==1 && !IbiStream->Infos.empty())
4167 {
4168 IbiStream->DtsFrequencyNumerator=Numerator;
4169 IbiStream->DtsFrequencyDenominator=Denominator;
4170 for (size_t Pos=0; Pos<IbiStream->Infos.size(); Pos++)
4171 if (IbiStream->Infos[Pos].Dts!=(int64u)-1)
4172 IbiStream->Infos[Pos].Dts=float64_int64s(((float64)IbiStream->Infos[Pos].Dts)/1000000000/Denominator*Numerator);
4173 }
4174 }
4175
Ibi_Add()4176 void File__Analyze::Ibi_Add ()
4177 {
4178 if (IbiStream==NULL)
4179 return;
4180
4181 ibi::stream::info IbiInfo;
4182 IbiInfo.StreamOffset=IsSub?Ibi_SynchronizationOffset_Current:(File_Offset+Buffer_Offset);
4183 IbiInfo.FrameNumber=Frame_Count_NotParsedIncluded;
4184 IbiInfo.Dts=FrameInfo.DTS;
4185 IbiStream->Add(IbiInfo);
4186
4187 if (Frame_Count_NotParsedIncluded==(int64u)-1)
4188 Frame_Count_NotParsedIncluded=IbiStream->Infos[IbiStream->Infos_Pos-1].FrameNumber;
4189 }
4190
4191 #endif //MEDIAINFO_IBCREATION
4192
4193 } //NameSpace
4194