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