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_Internal.h"
22 #include "MediaInfo/MediaInfo_Config.h"
23 #include "MediaInfo/TimeCode.h"
24 #if defined(MEDIAINFO_FILE_YES)
25 #include "ZenLib/File.h"
26 #endif //defined(MEDIAINFO_REFERENCES_YES)
27 #include "ZenLib/FileName.h"
28 #include "ZenLib/BitStream_LE.h"
29 #include <cmath>
30 #include <cfloat>
31 #include <cassert>
32 using namespace std;
33 //---------------------------------------------------------------------------
34 
35 namespace MediaInfoLib
36 {
37 
38 //---------------------------------------------------------------------------
39 extern MediaInfo_Config Config;
40 const char* Mpegv_colour_primaries(int8u colour_primaries);
41 //---------------------------------------------------------------------------
42 
43 //***************************************************************************
44 // Others, specialized, parsing
45 //***************************************************************************
46 
47 //---------------------------------------------------------------------------
48 #if defined(MEDIAINFO_HEVC_YES) || defined(MEDIAINFO_MPEG4_YES)
Get_MasteringDisplayColorVolume(Ztring & MasteringDisplay_ColorPrimaries,Ztring & MasteringDisplay_Luminance)49 void File__Analyze::Get_MasteringDisplayColorVolume(Ztring &MasteringDisplay_ColorPrimaries, Ztring &MasteringDisplay_Luminance)
50 {
51     //Parsing
52     mastering_metadata_2086 Meta;
53     for (size_t c = 0; c < 3; c++)
54     {
55         Get_B2(Meta.Primaries[c*2  ],                           "display_primaries_x");
56         Get_B2(Meta.Primaries[c*2+1],                           "display_primaries_y");
57     }
58     Get_B2(Meta.Primaries[3*2  ],                               "white_point_x");
59     Get_B2(Meta.Primaries[3*2+1],                               "white_point_y");
60     Get_B4(Meta.Luminance[1],                                   "max_display_mastering_luminance");
61     Get_B4(Meta.Luminance[0],                                   "min_display_mastering_luminance");
62 
63     FILLING_BEGIN();
64         if (MasteringDisplay_ColorPrimaries.empty())
65             Get_MasteringDisplayColorVolume(MasteringDisplay_ColorPrimaries, MasteringDisplay_Luminance, Meta);
66     FILLING_END();
67 }
68 #endif
69 
70 //---------------------------------------------------------------------------
71 #if defined(MEDIAINFO_HEVC_YES) || defined(MEDIAINFO_MPEG4_YES) || defined(MEDIAINFO_MATROSKA_YES)
72 struct masteringdisplaycolorvolume_values
73 {
74     int8u Code; //ISO code
75     int16u Values[8]; // G, B, R, W pairs (x values then y values)
76 };
77 static const int8u MasteringDisplayColorVolume_Values_Size=4;
78 static const masteringdisplaycolorvolume_values MasteringDisplayColorVolume_Values[] =
79 {
80     { 1, {15000, 30000,  7500,  3000, 32000, 16500, 15635, 16450}}, // BT.709
81     { 9, { 8500, 39850,  6550,  2300, 35400, 14600, 15635, 16450}}, // BT.2020
82     {11, {13250, 34500,  7500,  3000, 34000, 16000, 15700, 17550}}, // DCI P3
83     {12, {13250, 34500,  7500,  3000, 34000, 16000, 15635, 16450}}, // Display P3
84 };
MasteringDisplayColorVolume_Values_Compute(int16u Values[8])85 Ztring MasteringDisplayColorVolume_Values_Compute(int16u Values[8])
86 {
87     //Reordering to RGB
88     size_t G=4, B=4, R=4;
89     for (size_t c=0; c<3; c++)
90     {
91         if (Values[c*2]<17500 && Values[c*2+1]<17500) //x and y
92             B=c;
93         else if ((int32s)(Values[c*2+1])-(int32s)(Values[c*2])>=0) // y minus x
94             G=c;
95         else
96             R=c;
97     }
98     if ((R|B|G)>=4)
99     {
100         //Order not automaticly detected, betting on GBR order
101         G=0;
102         B=1;
103         R=2;
104     }
105 
106     int8u Code;
107     for (int8u i=0; i<MasteringDisplayColorVolume_Values_Size; i++)
108     {
109         Code=MasteringDisplayColorVolume_Values[i].Code;
110         for (int8u j=0; j<2; j++)
111         {
112             // +/- 0.0005 (3 digits after comma)
113             if (Values[G*2+j]<MasteringDisplayColorVolume_Values[i].Values[0*2+j]-25 || (Values[G*2+j]>=MasteringDisplayColorVolume_Values[i].Values[0*2+j]+25))
114                 Code=0;
115             if (Values[B*2+j]<MasteringDisplayColorVolume_Values[i].Values[1*2+j]-25 || (Values[B*2+j]>=MasteringDisplayColorVolume_Values[i].Values[1*2+j]+25))
116                 Code=0;
117             if (Values[R*2+j]<MasteringDisplayColorVolume_Values[i].Values[2*2+j]-25 || (Values[R*2+j]>=MasteringDisplayColorVolume_Values[i].Values[2*2+j]+25))
118                 Code=0;
119             // +/- 0.00005 (4 digits after comma)
120             if (Values[3*2+j]<MasteringDisplayColorVolume_Values[i].Values[3*2+j]-2 || (Values[3*2+j]>=MasteringDisplayColorVolume_Values[i].Values[3*2+j]+3))
121                 Code=0;
122         }
123 
124         if (Code)
125             return Mpegv_colour_primaries(Code);
126     }
127 
128     return       __T("R: x=")+Ztring::ToZtring(((float64)Values[R*2  ])/50000, 6)
129                 +__T(  " y=")+Ztring::ToZtring(((float64)Values[R*2+1])/50000, 6)
130               +__T(", G: x=")+Ztring::ToZtring(((float64)Values[G*2  ])/50000, 6)
131                 +__T(  " y=")+Ztring::ToZtring(((float64)Values[G*2+1])/50000, 6)
132               +__T(", B: x=")+Ztring::ToZtring(((float64)Values[B*2  ])/50000, 6)
133                 +__T(  " y=")+Ztring::ToZtring(((float64)Values[B*2+1])/50000, 6)
134     +__T(", White point: x=")+Ztring::ToZtring(((float64)Values[3*2  ])/50000, 6)
135                 +__T(  " y=")+Ztring::ToZtring(((float64)Values[3*2+1])/50000, 6);
136 }
Get_MasteringDisplayColorVolume(Ztring & MasteringDisplay_ColorPrimaries,Ztring & MasteringDisplay_Luminance,mastering_metadata_2086 & Meta)137 void File__Analyze::Get_MasteringDisplayColorVolume(Ztring &MasteringDisplay_ColorPrimaries, Ztring &MasteringDisplay_Luminance, mastering_metadata_2086 &Meta)
138 {
139     if (!MasteringDisplay_ColorPrimaries.empty())
140         return; // Use the first one
141 
142     bool IsNotValid=false;
143     for (int8u i=0; i<8; i++)
144         if (Meta.Primaries[i]==(int16u)-1)
145             IsNotValid=true;
146     if (!IsNotValid)
147         MasteringDisplay_ColorPrimaries=MasteringDisplayColorVolume_Values_Compute(Meta.Primaries);
148 
149     if (Meta.Luminance[0]!=(int32u)-1 && Meta.Luminance[1]!=(int32u)-1)
150         MasteringDisplay_Luminance=        __T("min: ")+Ztring::ToZtring(((float64)Meta.Luminance[0])/10000, 4)
151                                   +__T(" cd/m2, max: ")+Ztring::ToZtring(((float64)Meta.Luminance[1])/10000, ((float64)Meta.Luminance[1]/10000-Meta.Luminance[1]/10000==0)?0:4)
152                                   +__T(" cd/m2");
153 }
154 #endif
155 
156 //---------------------------------------------------------------------------
157 #if defined(MEDIAINFO_HEVC_YES) || defined(MEDIAINFO_MPEG4_YES) || defined(MEDIAINFO_MATROSKA_YES)
158 static const size_t DolbyVision_Profiles_Size=10;
159 static const char* DolbyVision_Profiles[DolbyVision_Profiles_Size] = // dv[BL_codec_type].[number_of_layers][bit_depth][cross-compatibility]
160 {
161     "dvav",
162     "dvav",
163     "dvhe",
164     "dvhe",
165     "dvhe",
166     "dvhe",
167     "dvhe",
168     "dvhe",
169     "dvhe",
170     "dvav",
171 };
172 
173 extern const size_t DolbyVision_Compatibility_Size = 7;
174 extern const char* DolbyVision_Compatibility[DolbyVision_Compatibility_Size] =
175 {
176     "",
177     "HDR10",
178     "SDR",
179     NULL,
180     "HLG",
181     NULL,
182     "Blu-ray",
183 };
dvcC(bool has_dependency_pid,std::map<std::string,Ztring> * Infos)184 void File__Analyze::dvcC(bool has_dependency_pid, std::map<std::string, Ztring>* Infos)
185 {
186     Element_Name("Dolby Vision Configuration");
187 
188     //Parsing
189     int8u  dv_version_major, dv_version_minor, dv_profile, dv_level, dv_bl_signal_compatibility_id;
190     bool rpu_present_flag, el_present_flag, bl_present_flag;
191     Get_B1 (dv_version_major,                                   "dv_version_major");
192     if (dv_version_major && dv_version_major<=2) //Spec says nothing, we hope that a minor version change means that the stream is backward compatible
193     {
194         Get_B1 (dv_version_minor,                               "dv_version_minor");
195         BS_Begin();
196         size_t End=Data_BS_Remain();
197         if (End>=176)
198             End-=176;
199         else
200             End=0; // Not enough place for reserved bits, but we currently ignore such case, just considered as unknown
201         Get_S1 (7, dv_profile,                                  "dv_profile");
202         Get_S1 (6, dv_level,                                    "dv_level");
203         Get_SB (   rpu_present_flag,                            "rpu_present_flag");
204         Get_SB (   el_present_flag,                             "el_present_flag");
205         Get_SB (   bl_present_flag,                             "bl_present_flag");
206         if (has_dependency_pid && !bl_present_flag)
207         {
208             Skip_S2(13,                                         "dependency_pid");
209             Skip_S1( 3,                                         "reserved");
210         }
211         if (Data_BS_Remain())
212         {
213             Get_S1 (4, dv_bl_signal_compatibility_id,           "dv_bl_signal_compatibility_id"); // in dv_version_major 2 only if based on specs but it was confirmed to be seen in dv_version_major 1 too and it does not hurt (value 0 means no new display)
214             if (End<Data_BS_Remain())
215                 Skip_BS(Data_BS_Remain()-End,                   "reserved");
216         }
217         else
218             dv_bl_signal_compatibility_id=0;
219         BS_End();
220     }
221     Skip_XX(Element_Size-Element_Offset,                        "Unknown");
222 
223     FILLING_BEGIN();
224         if (Infos)
225             (*Infos)["HDR_Format"].From_UTF8("Dolby Vision");
226         else
227             Fill(Stream_Video, StreamPos_Last, Video_HDR_Format, "Dolby Vision");
228         if (dv_version_major && dv_version_major<=2)
229         {
230             Ztring Summary=Ztring::ToZtring(dv_version_major)+__T('.')+Ztring::ToZtring(dv_version_minor);
231             if (Infos)
232                 (*Infos)["HDR_Format_Version"]=Summary;
233             else
234                 Fill(Stream_Video, StreamPos_Last, Video_HDR_Format_Version, Summary);
235             string Profile, Level;
236             if (dv_profile<DolbyVision_Profiles_Size)
237                 Profile+=DolbyVision_Profiles[dv_profile];
238             else
239                 Profile+=Ztring().From_CC1(dv_profile).To_UTF8();
240             Profile+=__T('.');
241             Profile+=Ztring().From_CC1(dv_profile).To_UTF8();
242             Level+=Ztring().From_CC1(dv_level).To_UTF8();
243             if (Infos)
244             {
245                 (*Infos)["HDR_Format_Profile"].From_UTF8(Profile);
246                 (*Infos)["HDR_Format_Level"].From_UTF8(Level);
247             }
248             else
249             {
250                 Fill(Stream_Video, StreamPos_Last, Video_HDR_Format_Profile, Profile);
251                 Fill(Stream_Video, StreamPos_Last, Video_HDR_Format_Level, Level);
252             }
253             Summary += __T(',');
254             Summary+=__T(' ');
255             Summary+=Ztring().From_UTF8(Profile);
256             Summary+=__T('.');
257             Summary+=Ztring().From_UTF8(Level);
258 
259             string Layers;
260             if (rpu_present_flag|el_present_flag|bl_present_flag)
261             {
262                 Summary+=',';
263                 Summary+=' ';
264                 if (bl_present_flag)
265                     Layers +="BL+";
266                 if (el_present_flag)
267                     Layers +="EL+";
268                 if (rpu_present_flag)
269                     Layers +="RPU+";
270                 Layers.resize(Layers.size()-1);
271                 Summary+=Ztring().From_UTF8(Layers);
272             }
273             if (Infos)
274                 (*Infos)["HDR_Format_Settings"].From_UTF8(Layers);
275             else
276                 Fill(Stream_Video, StreamPos_Last, Video_HDR_Format_Settings, Layers);
277             if (dv_bl_signal_compatibility_id)
278             {
279                 string Compatibility;
280                 if (dv_bl_signal_compatibility_id<DolbyVision_Compatibility_Size && DolbyVision_Compatibility[dv_bl_signal_compatibility_id])
281                     Compatibility=DolbyVision_Compatibility[dv_bl_signal_compatibility_id];
282                 else
283                     Compatibility=Ztring().From_Number(dv_bl_signal_compatibility_id).To_UTF8();
284                 if (Infos)
285                     (*Infos)["HDR_Format_Compatibility"].From_UTF8(Compatibility);
286                 else
287                     Fill(Stream_Video, StreamPos_Last, Video_HDR_Format_Compatibility, Compatibility);
288             }
289         }
290         else
291             if (Infos)
292                 (*Infos)["HDR_Format_Version"]=Ztring::ToZtring(dv_version_major);
293             else
294                 Fill(Stream_Video, StreamPos_Last, Video_HDR_Format_Version, dv_version_major);
295     FILLING_END();
296 }
297 #endif
298 
299 //***************************************************************************
300 // Preparation des streams
301 //***************************************************************************
302 
303 //---------------------------------------------------------------------------
Stream_Prepare(stream_t KindOfStream,size_t StreamPos)304 size_t File__Analyze::Stream_Prepare (stream_t KindOfStream, size_t StreamPos)
305 {
306     //Integrity
307     if (KindOfStream>Stream_Max)
308         return Error;
309 
310     //Clear
311     if (KindOfStream==Stream_Max)
312     {
313         StreamKind_Last=Stream_Max;
314         StreamPos_Last=(size_t)-1;
315         return 0;
316     }
317 
318     if (StreamPos>=Count_Get(KindOfStream))
319     {
320         //Add a stream
321         (*Stream)[KindOfStream].resize((*Stream)[KindOfStream].size()+1);
322         (*Stream_More)[KindOfStream].resize((*Stream_More)[KindOfStream].size()+1);
323         StreamKind_Last=KindOfStream;
324         StreamPos_Last=(*Stream)[KindOfStream].size()-1;
325     }
326     else
327     {
328         //Insert a stream
329         (*Stream)[KindOfStream].insert((*Stream)[KindOfStream].begin()+StreamPos, ZtringList());
330         (*Stream_More)[KindOfStream].insert((*Stream_More)[KindOfStream].begin()+StreamPos, ZtringListList());
331         StreamKind_Last=KindOfStream;
332         StreamPos_Last=StreamPos;
333     }
334 
335     //Filling basic info
336     Fill(StreamKind_Last, StreamPos_Last, (size_t)General_Count, Count_Get(StreamKind_Last, StreamPos_Last));
337     Fill(StreamKind_Last, StreamPos_Last, General_StreamKind, MediaInfoLib::Config.Info_Get(StreamKind_Last).Read(General_StreamKind, Info_Text));
338     Fill(StreamKind_Last, StreamPos_Last, General_StreamKind_String, MediaInfoLib::Config.Language_Get(MediaInfoLib::Config.Info_Get(StreamKind_Last).Read(General_StreamKind, Info_Text)), true);
339     for (size_t Pos=0; Pos<Count_Get(KindOfStream); Pos++)
340     {
341         Fill(StreamKind_Last, Pos, General_StreamCount, Count_Get(StreamKind_Last), 10, true);
342         Fill(StreamKind_Last, Pos, General_StreamKindID, Pos, 10, true);
343         if (Count_Get(StreamKind_Last)>1)
344             Fill(StreamKind_Last, Pos, General_StreamKindPos, Pos+1, 10, true);
345         else
346             Clear(StreamKind_Last, Pos, General_StreamKindPos);
347     }
348 
349     //Filling Lists & Counts
350     if (!IsSub && KindOfStream!=Stream_General)
351     {
352         const Ztring& StreamKind_Text=Get(KindOfStream, 0, General_StreamKind, Info_Text);
353         Fill(Stream_General, 0, Ztring(StreamKind_Text+__T("Count")).To_Local().c_str(), Count_Get(KindOfStream), 10, true);
354     }
355 
356     //File name and dates
357     if (!IsSub && KindOfStream==Stream_General && File_Name.size()>0)
358     {
359         //File name
360         if (File_Name.find(__T("://"))==string::npos)
361         {
362             Fill (Stream_General, 0, General_CompleteName, File_Name);
363             Fill (Stream_General, 0, General_FolderName, FileName::Path_Get(File_Name));
364             Fill (Stream_General, 0, General_FileName, FileName::Name_Get(File_Name));
365             Fill (Stream_General, 0, General_FileExtension, FileName::Extension_Get(File_Name));
366         }
367         else
368         {
369             Ztring FileName_Modified=File_Name;
370             size_t Begin=FileName_Modified.find(__T(':'), 6);
371             size_t End=FileName_Modified.find(__T('@'));
372             if (Begin!=string::npos && End!=string::npos && Begin<End)
373                 FileName_Modified.erase(Begin, End-Begin);
374             Fill (Stream_General, 0, General_CompleteName, FileName_Modified);
375             size_t FileName_Modified_PathSeparatorOffset=FileName_Modified.find_last_of(__T('/'));
376             if (FileName_Modified_PathSeparatorOffset!=string::npos)
377             {
378                 Fill (Stream_General, 0, General_FolderName, FileName_Modified.substr(0, FileName_Modified_PathSeparatorOffset));
379                 size_t FileName_Modified_ExtensionSeparatorOffset=FileName_Modified.find_last_of(__T('.'));
380                 if (FileName_Modified_ExtensionSeparatorOffset!=string::npos && FileName_Modified_ExtensionSeparatorOffset>FileName_Modified_PathSeparatorOffset)
381                 {
382                     Fill (Stream_General, 0, General_FileName, FileName_Modified.substr(FileName_Modified_PathSeparatorOffset+1, FileName_Modified_ExtensionSeparatorOffset-(FileName_Modified_PathSeparatorOffset+1)));
383                     Fill (Stream_General, 0, General_FileExtension, FileName_Modified.substr(FileName_Modified_ExtensionSeparatorOffset+1));
384                 }
385                 else
386                     Fill (Stream_General, 0, General_FileName, FileName_Modified.substr(FileName_Modified_PathSeparatorOffset+1));
387             }
388         }
389         if (Retrieve(Stream_General, 0, General_FileExtension).empty())
390             Fill(Stream_General, 0, General_FileNameExtension, Retrieve(Stream_General, 0, General_FileName));
391         else
392             Fill(Stream_General, 0, General_FileNameExtension, Retrieve(Stream_General, 0, General_FileName)+__T('.')+Retrieve(Stream_General, 0, General_FileExtension));
393 
394         //File dates
395         #if defined(MEDIAINFO_FILE_YES)
396         File F(File_Name);
397         Fill (Stream_General, 0, General_File_Created_Date, F.Created_Get());
398         Fill (Stream_General, 0, General_File_Created_Date_Local, F.Created_Local_Get());
399         Fill (Stream_General, 0, General_File_Modified_Date, F.Modified_Get());
400         Fill (Stream_General, 0, General_File_Modified_Date_Local, F.Modified_Local_Get());
401         #endif //defined(MEDIAINFO_FILE_YES)
402     }
403 
404     //File size
405     if (((!IsSub || !File_Name.empty()) && KindOfStream==Stream_General && File_Size!=(int64u)-1))
406         Fill (Stream_General, 0, General_FileSize, File_Size);
407 
408     //Fill with already ready data
409     stream_t Fill_Temp_StreamKind=(Fill_Temp[StreamKind_Last].empty()?Stream_Max:StreamKind_Last);
410     for (size_t Pos=0; Pos<Fill_Temp[Fill_Temp_StreamKind].size(); Pos++)
411         if (Fill_Temp[Fill_Temp_StreamKind][Pos].Parameter.IsNumber())
412             Fill(StreamKind_Last, StreamPos_Last, Fill_Temp[Fill_Temp_StreamKind][Pos].Parameter.To_int32u(), Fill_Temp[Fill_Temp_StreamKind][Pos].Value);
413         else
414         {
415             Fill(StreamKind_Last, StreamPos_Last, Fill_Temp[Fill_Temp_StreamKind][Pos].Parameter.To_UTF8().c_str(), Fill_Temp[Fill_Temp_StreamKind][Pos].Value);
416             #if MEDIAINFO_DEMUX
417                 if (!Retrieve(KindOfStream, StreamPos_Last, "Demux_InitBytes").empty())
418                     Fill_SetOptions(KindOfStream, StreamPos_Last, "Demux_InitBytes", "N NT");
419             #endif //MEDIAINFO_DEMUX
420             map<string, string>::iterator Fill_Temp_Option=Fill_Temp_Options[Fill_Temp_StreamKind].find(Fill_Temp[Fill_Temp_StreamKind][Pos].Parameter.To_UTF8());
421             if (Fill_Temp_Option!=Fill_Temp_Options[Fill_Temp_StreamKind].end())
422                 Fill_SetOptions(KindOfStream, StreamPos_Last, Fill_Temp_Option->first.c_str(), Fill_Temp_Option->second.c_str());
423         }
424     Fill_Temp[Fill_Temp_StreamKind].clear();
425     Fill_Temp_Options[Fill_Temp_StreamKind].clear();
426 
427     return StreamPos_Last; //The position in the stream count
428 }
429 
Stream_Erase(stream_t KindOfStream,size_t StreamPos)430 size_t File__Analyze::Stream_Erase (stream_t KindOfStream, size_t StreamPos)
431 {
432     //Integrity
433     if (KindOfStream>Stream_Max || StreamPos>=Count_Get(KindOfStream))
434         return Error;
435 
436     //Filling Lists & Counts
437     if (!IsSub && KindOfStream!=Stream_General)
438     {
439         const Ztring& StreamKind_Text=Get(KindOfStream, 0, General_StreamKind, Info_Text);
440         ZtringList Temp; Temp.Separator_Set(0, __T(" / "));
441         Temp.Write(Retrieve(Stream_General, 0, Ztring(StreamKind_Text+__T("_Codec_List")).To_Local().c_str()));
442         if (StreamPos<Temp.size())
443             Temp.erase(Temp.begin()+StreamPos);
444         Fill(Stream_General, 0, Ztring(StreamKind_Text+__T("_Codec_List")).To_Local().c_str(), Temp.Read(), true);
445         Temp.Write(Retrieve(Stream_General, 0, Ztring(StreamKind_Text+__T("_Language_List")).To_Local().c_str()));
446         if (StreamPos<Temp.size())
447             Temp.erase(Temp.begin()+StreamPos);
448         Fill(Stream_General, 0, Ztring(StreamKind_Text+__T("_Language_List")).To_Local().c_str(), Temp.Read(), true);
449         Temp.Write(Retrieve(Stream_General, 0, Ztring(StreamKind_Text+__T("_Format_List")).To_Local().c_str()));
450         if (StreamPos<Temp.size())
451             Temp.erase(Temp.begin()+StreamPos);
452         Fill(Stream_General, 0, Ztring(StreamKind_Text+__T("_Format_List")).To_Local().c_str(), Temp.Read(), true);
453         Temp.Write(Retrieve(Stream_General, 0, Ztring(StreamKind_Text+__T("_Format_WithHint_List")).To_Local().c_str()));
454         if (StreamPos<Temp.size())
455             Temp.erase(Temp.begin()+StreamPos);
456         Fill(Stream_General, 0, Ztring(StreamKind_Text+__T("_Format_WithHint_List")).To_Local().c_str(), Temp.Read(), true);
457 
458         Fill(Stream_General, 0, Ztring(StreamKind_Text+__T("Count")).To_Local().c_str(), Count_Get(KindOfStream)-1, 10, true);
459     }
460 
461     //Insert a stream
462     (*Stream)[KindOfStream].erase((*Stream)[KindOfStream].begin()+StreamPos);
463     (*Stream_More)[KindOfStream].erase((*Stream_More)[KindOfStream].begin()+StreamPos);
464 
465     //Filling basic info
466     for (size_t Pos=0; Pos<Count_Get(KindOfStream); Pos++)
467     {
468         Fill(KindOfStream, Pos, General_StreamCount, Count_Get(KindOfStream), 10, true);
469         Fill(KindOfStream, Pos, General_StreamKindID, Pos, 10, true);
470         if (Count_Get(KindOfStream)>1)
471             Fill(KindOfStream, Pos, General_StreamKindPos, Pos+1, 10, true);
472         else
473             Clear(KindOfStream, Pos, General_StreamKindPos);
474     }
475 
476     StreamKind_Last=Stream_Max;
477     StreamPos_Last=(size_t)-1;
478 
479     return (*Stream)[KindOfStream].size()-1; //The position in the stream count
480 }
481 
482 
483 //***************************************************************************
484 // Filling
485 //***************************************************************************
486 
487 //---------------------------------------------------------------------------
ShowSource_IsInList(video Value)488 bool ShowSource_IsInList(video Value)
489 {
490     switch (Value)
491     {
492         case Video_colour_description_present:
493         case Video_colour_range:
494         case Video_colour_primaries:
495         case Video_matrix_coefficients:
496         case Video_transfer_characteristics:
497         case Video_MasteringDisplay_ColorPrimaries:
498         case Video_MasteringDisplay_Luminance:
499         case Video_MaxCLL:
500         case Video_MaxFALL:
501             return true;
502         default:
503             return false;
504     }
505 }
506 
507 //---------------------------------------------------------------------------
Fill(stream_t StreamKind,size_t StreamPos,size_t Parameter,const Ztring & Value,bool Replace)508 void File__Analyze::Fill (stream_t StreamKind, size_t StreamPos, size_t Parameter, const Ztring &Value, bool Replace)
509 {
510     // Sanitize
511     if (!Value.empty())
512     {
513         size_t Value_NotBOM_Pos;
514         #if defined(UNICODE) || defined (_UNICODE)
515             //Check inverted bytes from UTF BOM
516             Value_NotBOM_Pos=Value.find_first_not_of(__T('\xFFFE')); // Avoid deep recursivity
517             if (Value_NotBOM_Pos)
518             {
519                 Ztring Value2;
520                 Value2.reserve(Value.size()-1);
521                 for (size_t i=0; i<Value.size(); i++)
522                 {
523                     //Swap
524                     Char ValueChar=Value[i];
525                     ValueChar=((ValueChar<<8 & 0xFFFF) | ((ValueChar>>8) & 0xFF)); // Swap
526                     Value2.append(1, ValueChar);
527                 }
528                 Value_NotBOM_Pos=Value2.find_first_not_of(__T('\xFEFF')); // Avoid deep recursivity
529                 if (Value_NotBOM_Pos)
530                     Value2=Value2.substr(Value_NotBOM_Pos);
531                 return Fill(StreamKind, StreamPos, Parameter, Value2, Replace);
532             }
533 
534             Value_NotBOM_Pos=Value.find_first_not_of(__T('\xFEFF')); // Avoid deep recursivity
535         #else
536             Value_NotBOM_Pos=0;
537             while (Value.size()-Value_NotBOM_Pos>=3 // Avoid deep recursivity
538              && Value[Value_NotBOM_Pos  ]==0xEF
539              && Value[Value_NotBOM_Pos+1]==0xBB
540              && Value[Value_NotBOM_Pos+2]==0xBF
541                 )
542                 Value_NotBOM_Pos+=3;
543         #endif //defined(UNICODE) || defined (_UNICODE)
544 
545         if (Value_NotBOM_Pos)
546             return Fill(StreamKind, StreamPos, Parameter, Value.substr(Value_NotBOM_Pos), Replace);
547     }
548 
549     //MergedStreams
550     if (FillAllMergedStreams)
551     {
552         FillAllMergedStreams=false;
553         size_t s = MergedStreams_Last.size();
554         for (size_t i=0; i<s; ++i)
555             Fill(MergedStreams_Last[i].StreamKind, MergedStreams_Last[i].StreamPos, Parameter, Value, Replace);
556         FillAllMergedStreams=true;
557         return;
558     }
559 
560     //Integrity
561     if (StreamKind>Stream_Max || Parameter==(size_t)-1)
562         return;
563 
564     //Remove deprecated fields
565     if (!MediaInfoLib::Config.Legacy_Get())
566     {
567         const Ztring& Info=MediaInfoLib::Config.Info_Get(StreamKind, Parameter, Info_Info);
568         if (Info.size()>9 && Info[0]==__T('D') && Info[1]==__T('e') && Info[2]==__T('p') && Info[3]==__T('r') && Info[4]==__T('e') && Info[5]==__T('c') && Info[6]==__T('a') && Info[7]==__T('t') && Info[8]==__T('e') && Info[9]==__T('d'))
569             return;
570     }
571 
572     // Handling sources
573     const char* SourceValue[StreamSource_Max] =
574     {
575         "Container",
576         "Stream",
577         "ContainerExtra",
578     };
579     assert(sizeof(SourceValue)==StreamSource_Max*sizeof(const char*));
580     if (StreamKind==Stream_Video && ShowSource_IsInList((video)Parameter) && StreamSource<StreamSource_Max && Retrieve_Const(Stream_Video, StreamPos, Parameter+1).empty())
581     {
582         Fill(Stream_Video, StreamPos, Parameter+1, SourceValue[StreamSource]);
583     }
584 
585     //Format_Profile split (see similar code in MediaInfo_Inform.cpp, dedicated to MIXML)
586     #if MEDIAINFO_ADVANCED
587         if (Parameter==Fill_Parameter(StreamKind, Generic_Format_Profile) && MediaInfoLib::Config.Format_Profile_Split_Get())
588         {
589             size_t SeparatorPos=Value.find(__T('@'));
590             if (SeparatorPos!=string::npos && Value.find(__T(" / "))==string::npos) //TODO: better support of compatibility modes (e.g. "Multiview") and sequences (e.g. different profiles in different files "BCS@L3 / BCS@L2 / BCS@L3")
591             {
592                 Ztring Value2(Value);
593                 Ztring Format_Profile_More=Value2.substr(SeparatorPos+1);
594                 Value2.erase(SeparatorPos);
595                 if (Format_Profile_More.size()>=2 && Format_Profile_More[0]==__T('L') && Format_Profile_More[1]>=__T('0') && Format_Profile_More[1]<=__T('9'))
596                     Format_Profile_More.erase(0, 1);
597                 size_t SeparatorPos=Format_Profile_More.find(__T('@'));
598                 Fill(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_Format_Profile), Value2, Replace);
599                 if (SeparatorPos!=string::npos)
600                 {
601                     Fill(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_Format_Level), Format_Profile_More.substr(0, SeparatorPos));
602                     Fill(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_Format_Tier), Format_Profile_More.substr(SeparatorPos+1));
603                 }
604                 else
605                 {
606                     Fill(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_Format_Level), Format_Profile_More);
607                 }
608                 return;
609             }
610         }
611     #endif //MEDIAINFO_ADVANCED
612 
613     //Handling values with \r\n inside
614     if (Value.find_first_of(__T("\r\n"))!=string::npos)
615     {
616         Ztring CarriageReturnReplace=MediaInfoLib::Config.CarriageReturnReplace_Get();
617         if (!CarriageReturnReplace.empty())
618         {
619             Ztring NewValue=Value;
620             NewValue.FindAndReplace(__T("\r\n"), CarriageReturnReplace, 0, Ztring_Recursive);
621             NewValue.FindAndReplace(__T("\r"), CarriageReturnReplace, 0, Ztring_Recursive);
622             NewValue.FindAndReplace(__T("\n"), CarriageReturnReplace, 0, Ztring_Recursive);
623             if (NewValue.size()>=CarriageReturnReplace.size() && NewValue.rfind(CarriageReturnReplace)==NewValue.size()-CarriageReturnReplace.size())
624                 NewValue.resize(NewValue.size()-CarriageReturnReplace.size());
625             Fill(StreamKind, StreamPos, Parameter, NewValue, Replace);
626             return;
627         }
628     }
629 
630     //Handle Value before StreamKind
631     if (StreamKind==Stream_Max || StreamPos>=(*Stream)[StreamKind].size())
632     {
633         size_t StreamKindS=(size_t)StreamKind;
634         if (StreamKind!=Stream_Max)
635         {
636             //Stream kind is found, moving content
637             for (size_t Pos=0; Pos<Fill_Temp[Stream_Max].size(); Pos++)
638                 Fill_Temp[StreamKind].push_back(Fill_Temp[Stream_Max][Pos]);
639             Fill_Temp[Stream_Max].clear();
640         }
641         else
642         {
643             //Stream kind is not found, checking if it was found previously
644             for (StreamKindS=(size_t)Stream_General+1; StreamKindS<(size_t)Stream_Max; StreamKindS++)
645                 if (!Fill_Temp[StreamKindS].empty())
646                     break;
647         }
648 
649         const Ztring Parameter_String = Ztring::ToZtring(Parameter);
650         if (Replace)
651         {
652             for (size_t Pos=0; Pos<Fill_Temp[StreamKindS].size(); Pos++)
653                 if (Fill_Temp[StreamKindS][Pos].Parameter==Parameter_String)
654                 {
655                     Fill_Temp[StreamKindS][Pos].Value=Value;
656                     return;
657                 }
658         }
659         fill_temp_item NewList;
660         NewList.Parameter=Parameter_String;
661         NewList.Value=Value;
662         Fill_Temp[StreamKindS].push_back(NewList);
663         return; //No streams
664     }
665 
666     //Some defaults
667     if (Parameter==Fill_Parameter(StreamKind, Generic_Format_Commercial))
668         Replace=true;
669     if (Parameter==Fill_Parameter(StreamKind, Generic_Format_Commercial_IfAny))
670         Replace=true;
671 
672     if (!Replace && Value.empty())
673         return;
674     if (Replace && Value.empty())
675     {
676         Clear(StreamKind, StreamPos, Parameter);
677         return;
678     }
679 
680     Ztring &Target=(*Stream)[StreamKind][StreamPos](Parameter);
681     if (Target.empty() || Replace)
682         Target=Value; //First value
683     else
684     {
685         Target+=MediaInfoLib::Config.TagSeparator_Get();
686         Target+=Value;
687     }
688     Status[IsUpdated]=true;
689 
690     //Deprecated
691     if (Parameter==Fill_Parameter(StreamKind, Generic_BitDepth))
692         Fill(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_Resolution), Retrieve(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_BitDepth)), true);
693     if (StreamKind==Stream_Video && Parameter==Video_ChromaSubsampling)
694         Fill(Stream_Video, StreamPos, Video_Colorimetry, Value, Replace);
695 
696     switch (StreamKind)
697     {
698         case Stream_Video:
699                             switch (Parameter)
700                             {
701                                 case Video_Width:   if (StreamSource==IsStream) Fill(Stream_Video, StreamPos, Video_Sampled_Width, Value); break;
702                                 case Video_Height:  if (StreamSource==IsStream) Fill(Stream_Video, StreamPos, Video_Sampled_Height, Value); break;
703                                 case Video_DisplayAspectRatio:  DisplayAspectRatio_Fill(Value, Stream_Video, StreamPos, Video_Width, Video_Height, Video_PixelAspectRatio, Video_DisplayAspectRatio); break;
704                                 case Video_PixelAspectRatio:    PixelAspectRatio_Fill(Value, Stream_Video, StreamPos, Video_Width, Video_Height, Video_PixelAspectRatio, Video_DisplayAspectRatio);   break;
705                                 case Video_DisplayAspectRatio_CleanAperture:  DisplayAspectRatio_Fill(Value, Stream_Video, StreamPos, Video_Width_CleanAperture, Video_Height_CleanAperture, Video_PixelAspectRatio_CleanAperture, Video_DisplayAspectRatio_CleanAperture); break;
706                                 case Video_PixelAspectRatio_CleanAperture:    PixelAspectRatio_Fill(Value, Stream_Video, StreamPos, Video_Width_CleanAperture, Video_Height_CleanAperture, Video_PixelAspectRatio_CleanAperture, Video_DisplayAspectRatio_CleanAperture);   break;
707                                 case Video_DisplayAspectRatio_Original:  DisplayAspectRatio_Fill(Value, Stream_Video, StreamPos, Video_Width_Original, Video_Height_Original, Video_PixelAspectRatio_Original, Video_DisplayAspectRatio_Original); break;
708                                 case Video_PixelAspectRatio_Original:    PixelAspectRatio_Fill(Value, Stream_Video, StreamPos, Video_Width_Original, Video_Height_Original, Video_PixelAspectRatio_Original, Video_DisplayAspectRatio_Original);   break;
709                             }
710                             break;
711         case Stream_Audio:
712                             switch (Parameter)
713                             {
714                                 case Audio_SamplesPerFrame:
715                                 case Audio_SamplingRate:
716                                     if (Retrieve(Stream_Audio, StreamPos, Audio_FrameRate).empty())
717                                     {
718                                         float64 SamplesPerFrame=Retrieve(Stream_Audio, StreamPos, Audio_SamplesPerFrame).To_float64();
719                                         float64 SamplingRate=DBL_MAX;
720                                         ZtringList SamplingRates;
721                                         SamplingRates.Separator_Set(0, " / ");
722                                         SamplingRates.Write(Retrieve(Stream_Audio, StreamPos, Audio_SamplingRate));
723                                         if (!SamplingRates.empty())
724                                         {
725                                             size_t i=SamplingRates.size();
726                                             do
727                                             {
728                                                 --i;
729                                                 float64 SamplingRateTemp = SamplingRates[i].To_float64();
730                                                 if (SamplingRateTemp && SamplingRateTemp<SamplingRate)
731                                                     SamplingRate=SamplingRateTemp; // Using the lowest valid one (e.g. AAC doubles sampling rate but the legacy sampling rate is the real frame)
732                                             }
733                                             while (i);
734                                         }
735                                         if (SamplesPerFrame && SamplingRate && SamplingRate!=DBL_MAX && SamplesPerFrame!=SamplingRate)
736                                         {
737                                             float64 FrameRate=SamplingRate/SamplesPerFrame;
738                                             Fill(Stream_Audio, StreamPos, Audio_FrameRate, FrameRate);
739                                         }
740                                     }
741                             }
742                             break;
743         case Stream_Image:
744                             switch (Parameter)
745                             {
746                                 case Image_DisplayAspectRatio:  DisplayAspectRatio_Fill(Value, Stream_Image, StreamPos, Image_Width, Image_Height, Image_PixelAspectRatio, Image_DisplayAspectRatio); break;
747                                 case Image_PixelAspectRatio:    PixelAspectRatio_Fill(Value, Stream_Image, StreamPos, Image_Width, Image_Height, Image_PixelAspectRatio, Image_DisplayAspectRatio);   break;
748                                 case Image_DisplayAspectRatio_Original:  DisplayAspectRatio_Fill(Value, Stream_Image, StreamPos, Image_Width_Original, Image_Height_Original, Image_PixelAspectRatio_Original, Image_DisplayAspectRatio_Original); break;
749                                 case Image_PixelAspectRatio_Original:    PixelAspectRatio_Fill(Value, Stream_Image, StreamPos, Image_Width_Original, Image_Height_Original, Image_PixelAspectRatio_Original, Image_DisplayAspectRatio_Original);   break;
750                             }
751                             break;
752         default:
753                             // TODO;
754                             break;
755     }
756 
757     //Commercial name
758     if (Parameter==Fill_Parameter(StreamKind, Generic_Format))
759         Fill(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_Format_Commercial), Value);
760     if (Parameter==Fill_Parameter(StreamKind, Generic_Format_Commercial_IfAny))
761         Fill(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_Format_Commercial), Value, true);
762 
763     if (!IsSub)
764     {
765         Ztring ParameterName=Retrieve(StreamKind, StreamPos, Parameter, Info_Name);
766 
767         //General Format
768         if (Parameter==Fill_Parameter(StreamKind, Generic_Format) && Retrieve(Stream_General, 0, General_Format).empty() && !Value.empty() && Count_Get(Stream_Video)+Count_Get(Stream_Audio)+Count_Get(Stream_Text)+Count_Get(Stream_Other)+Count_Get(Stream_Image)==1)
769             Fill(Stream_General, 0, General_Format, Value); //If not already filled, we are filling with the stream format
770 
771         //ID
772         if (Parameter==General_ID)
773             Fill(StreamKind, StreamPos, General_ID_String, Value, Replace);
774 
775         //Format
776         if (Parameter==Fill_Parameter(StreamKind, Generic_Format))
777         {
778             if ((Replace && !MediaInfoLib::Config.Format_Get(Retrieve(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_Format)), InfoFormat_Info).empty()) || Retrieve(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_Format_Info)).empty())
779                 Fill(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_Format_Info), MediaInfoLib::Config.Format_Get(Retrieve(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_Format)), InfoFormat_Info), true);
780             if ((Replace && !MediaInfoLib::Config.Format_Get(Retrieve(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_Format)), InfoFormat_Url).empty()) || Retrieve(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_Format_Url)).empty())
781                 Fill(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_Format_Url) , MediaInfoLib::Config.Format_Get(Retrieve(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_Format)), InfoFormat_Url), true);
782             if (StreamKind!=Stream_Menu)
783             {
784                 if ((Replace && !MediaInfoLib::Config.Format_Get(Retrieve(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_Format)), InfoFormat_InternetMediaType).empty()) || Retrieve(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_InternetMediaType)).empty())
785                     Fill(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_InternetMediaType), MediaInfoLib::Config.Format_Get(Retrieve(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_Format)), InfoFormat_InternetMediaType), true);
786                 if ((Replace && !MediaInfoLib::Config.Format_Get(Retrieve(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_Format)), InfoFormat_Compression_Mode).empty()) || Retrieve(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_Compression_Mode)).empty())
787                     Fill(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_Compression_Mode), MediaInfoLib::Config.Format_Get(Retrieve(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_Format)), InfoFormat_Compression_Mode), true);
788             }
789             if (StreamKind==Stream_General)
790             {
791                 Fill(Stream_General, 0, General_Format_Extensions, MediaInfoLib::Config.Format_Get(Value, InfoFormat_Extensions), true);
792                 Fill(Stream_General, 0, General_Format_String, Value, true);
793                 Fill(Stream_General, 0, General_Codec, Value, true);
794                 Fill(Stream_General, 0, General_Codec_String, Value, true);
795             }
796         }
797         if (MediaInfoLib::Config.Legacy_Get())
798         {
799         if (StreamKind==Stream_General && Parameter==General_Format_Info)
800             (*Stream)[Stream_General][0](General_Codec_Info)=Value;
801         if (StreamKind==Stream_General && Parameter==General_Format_Url)
802             (*Stream)[Stream_General][0](General_Codec_Url)=Value;
803         if (StreamKind==Stream_General && Parameter==General_Format_Extensions)
804             (*Stream)[Stream_General][0](General_Codec_Extensions)=Value;
805         if (StreamKind==Stream_General && Parameter==General_Format_Settings)
806             (*Stream)[Stream_General][0](General_Codec_Settings)=Value;
807 
808         //Codec
809         if (Parameter==Fill_Parameter(StreamKind, Generic_Codec))
810         {
811             const Ztring &C1=MediaInfoLib::Config.Codec_Get(Retrieve(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_Codec)), InfoCodec_Name, (stream_t)StreamKind);
812             if (C1.empty())
813                 Fill(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_Codec_String), Value, true);
814             else
815             {
816                 Ztring D=Retrieve(StreamKind, StreamPos, "Codec/Family");
817                 Fill(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_Codec_String), C1, true);
818                 Fill(StreamKind, StreamPos, "Codec/Family", MediaInfoLib::Config.Codec_Get(Retrieve(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_Codec)), InfoCodec_KindofCodec, StreamKind), true);
819                 Ztring B=Retrieve(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_Codec));
820                 Ztring C=MediaInfoLib::Config.Codec_Get(B, InfoCodec_KindofCodec, StreamKind);
821                 Fill(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_Codec_Info)  , MediaInfoLib::Config.Codec_Get(Retrieve(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_Codec)), InfoCodec_Description, StreamKind), true);
822                 Fill(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_Codec_Url)   , MediaInfoLib::Config.Codec_Get(Retrieve(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_Codec)), InfoCodec_Url,         StreamKind), true);
823             }
824         }
825         }
826 
827         //CodecID_Description
828         if (Parameter==Fill_Parameter(StreamKind, Generic_CodecID_Info) && Retrieve(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_CodecID_Description))==Value)
829             Clear(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_CodecID_Description));
830 
831         //BitRate from BitRate_Nominal
832         if ((Parameter==Fill_Parameter(StreamKind, Generic_BitRate)
833           || Parameter==Fill_Parameter(StreamKind, Generic_BitRate_Nominal))
834         #if MEDIAINFO_ADVANCED
835          && Config->File_MergeBitRateInfo_Get()
836         #endif //MEDIAINFO_ADVANCED
837          )
838         {
839             float32 BitRate=Retrieve(StreamKind, StreamPos, "BitRate").To_float32();
840             float32 BitRate_Nominal=Retrieve(StreamKind, StreamPos, "BitRate_Nominal").To_float32();
841             if (BitRate_Nominal>BitRate*0.95 && BitRate_Nominal<BitRate*1.05)
842             {
843                 Ztring Temp=Retrieve(StreamKind, StreamPos, "BitRate_Nominal");
844                 Clear(StreamKind, StreamPos, "BitRate_Nominal");
845                 Fill(StreamKind, StreamPos, "BitRate", Temp, true);
846             }
847         }
848 
849         //BitRate from BitRate_Maximum
850         if ((Parameter==Fill_Parameter(StreamKind, Generic_BitRate)
851           || Parameter==Fill_Parameter(StreamKind, Generic_BitRate_Maximum))
852         #if MEDIAINFO_ADVANCED
853          && Config->File_MergeBitRateInfo_Get()
854         #endif //MEDIAINFO_ADVANCED
855         )
856         {
857             float32 BitRate=Retrieve(StreamKind, StreamPos, "BitRate").To_float32();
858             float32 BitRate_Maximum=Retrieve(StreamKind, StreamPos, "BitRate_Maximum").To_float32();
859             if (BitRate>BitRate_Maximum*0.99 && BitRate<BitRate_Maximum*1.01)
860             {
861                 Ztring Temp=Retrieve(StreamKind, StreamPos, "BitRate_Maximum");
862                 Clear(StreamKind, StreamPos, "BitRate_Maximum");
863                 Fill(StreamKind, StreamPos, "BitRate", Temp, true);
864             }
865         }
866 
867         //File size
868         if (StreamKind==Stream_General && Parameter==General_FileSize)
869         {
870             int64u File_Size_Save=File_Size;
871             File_Size=Value.To_int64u();
872             for (size_t Kind=Stream_Video; Kind<Stream_Menu; Kind++)
873                 for (size_t Pos=0; Pos<Count_Get((stream_t)Kind); Pos++)
874                     FileSize_FileSize123((stream_t)Kind, Pos, Fill_Parameter((stream_t)Kind, Generic_StreamSize));
875             File_Size=File_Size_Save;
876         }
877 
878         //Delay/Video
879         if (StreamKind==Stream_Video && StreamPos==0 && Parameter==Video_Delay)
880         {
881             for (size_t Pos=0; Pos<Count_Get(Stream_Audio); Pos++)
882                 if (!Retrieve(Stream_Audio, Pos, Audio_Delay).empty())
883                 {
884                     Fill(Stream_Audio, Pos, Audio_Video_Delay, Retrieve(Stream_Audio, Pos, Audio_Delay).To_int64s()-Value.To_int64s(), 10, true);
885                     if (Retrieve(Stream_Audio, Pos, Audio_Video_Delay).To_int64u()==0)
886                         for (size_t Param_Pos=Audio_Video_Delay+1; Param_Pos<=Audio_Video_Delay+4; Param_Pos++)
887                             if (Param_Pos<(*Stream)[Stream_Audio][Pos].size())
888                                 (*Stream)[Stream_Audio][Pos][Param_Pos].clear();
889                 }
890             for (size_t Pos=0; Pos<Count_Get(Stream_Text); Pos++)
891                 if (!Retrieve(Stream_Text, Pos, Text_Delay).empty())
892                 {
893                     Fill(Stream_Text, Pos, Text_Video_Delay, Retrieve(Stream_Text, Pos, Text_Delay).To_int64s()-Value.To_int64s(), 10, true);
894                     if (Retrieve(Stream_Text, Pos, Text_Video_Delay).To_int64u()==0)
895                         for (size_t Param_Pos=Text_Video_Delay+1; Param_Pos<=Text_Video_Delay+4; Param_Pos++)
896                             if (Param_Pos<(*Stream)[Stream_Text][Pos].size())
897                                 (*Stream)[Stream_Text][Pos][Param_Pos].clear();
898                 }
899         }
900         if (StreamKind==Stream_Audio && Parameter==Audio_Delay && Count_Get(Stream_Video) && !Retrieve(Stream_Audio, StreamPos, Audio_Delay).empty() && !Retrieve(Stream_Video, 0, Video_Delay).empty())
901         {
902             if (Replace)
903                 Clear(Stream_Audio, StreamPos, Audio_Video_Delay);
904             ZtringList AudioDelay; AudioDelay.Separator_Set(0, __T(" / ")); AudioDelay.Write(Retrieve(Stream_Audio, StreamPos, Audio_Delay));
905             ZtringList VideoDelay; VideoDelay.Separator_Set(0, __T(" / ")); VideoDelay.Write(Retrieve(Stream_Video, 0, Video_Delay));
906             if (!AudioDelay.empty() && !VideoDelay.empty() && AudioDelay.size() <= VideoDelay.size())
907             {
908                 Fill(Stream_Audio, StreamPos, Audio_Video_Delay, AudioDelay(AudioDelay.size()-1).To_int64s()-VideoDelay(VideoDelay.size()-1).To_int64s(), 10);
909                 if (VideoDelay.size()==1 && Retrieve(Stream_Audio, StreamPos, Audio_Video_Delay).To_int64u()==0)
910                     for (size_t Pos=Audio_Video_Delay+1; Pos<=Audio_Video_Delay+4; Pos++)
911                         if (Pos<(*Stream)[Stream_Audio][StreamPos].size())
912                             (*Stream)[Stream_Audio][StreamPos][Pos].clear();
913             }
914         }
915         if (StreamKind==Stream_Text && Parameter==Text_Delay && Count_Get(Stream_Video) && !Retrieve(Stream_Text, StreamPos, Text_Delay).empty() && !Retrieve(Stream_Video, 0, Video_Delay).empty())
916         {
917             Ztring MuxingMode_MoreInfo=Get(Stream_Text, StreamPos, "MuxingMode_MoreInfo");
918             Ztring StreamID=MuxingMode_MoreInfo.SubString(__T("Muxed in Video #"), Ztring());
919             size_t StreamID_Int=(size_t)StreamID.To_int64u();
920             if (StreamID_Int)
921                 StreamID_Int--;
922             Fill(Stream_Text, StreamPos, Text_Video_Delay, Value.To_int64s()-Retrieve(Stream_Video, StreamID_Int, Video_Delay).To_int64s(), 10, true);
923             if (Retrieve(Stream_Text, StreamPos, Text_Video_Delay).To_int64u()==0)
924                 for (size_t Pos=Text_Video_Delay+1; Pos<=Text_Video_Delay+4; Pos++)
925                     if (Pos<(*Stream)[Stream_Text][StreamPos].size())
926                         (*Stream)[Stream_Text][StreamPos][Pos].clear();
927         }
928         if (StreamKind==Stream_Other && Parameter==Other_Delay && Count_Get(Stream_Video) && !Retrieve(Stream_Other, StreamPos, Other_Delay).empty() && !Retrieve(Stream_Video, 0, Video_Delay).empty())
929         {
930             if (Replace)
931                 Clear(Stream_Other, StreamPos, Other_Video_Delay);
932             ZtringList OtherDelay; OtherDelay.Separator_Set(0, __T(" / ")); OtherDelay.Write(Retrieve(Stream_Other, StreamPos, Other_Delay));
933             ZtringList VideoDelay; VideoDelay.Separator_Set(0, __T(" / ")); VideoDelay.Write(Retrieve(Stream_Video, 0, Video_Delay));
934             if (!OtherDelay.empty() && !VideoDelay.empty() && OtherDelay.size() <= VideoDelay.size())
935             {
936                 Fill(Stream_Other, StreamPos, Other_Video_Delay, OtherDelay(OtherDelay.size()-1).To_int64s()-VideoDelay(VideoDelay.size()-1).To_int64s(), 10);
937                 if (VideoDelay.size()==1 && Retrieve(Stream_Other, StreamPos, Other_Video_Delay).To_int64u()==0)
938                     for (size_t Pos=Other_Video_Delay+1; Pos<=Other_Video_Delay+4; Pos++)
939                         if (Pos<(*Stream)[Stream_Other][StreamPos].size())
940                             (*Stream)[Stream_Other][StreamPos][Pos].clear();
941             }
942         }
943 
944         //Delay/Video0
945         if (StreamKind==Stream_Video && StreamPos==0 && Parameter==Video_Delay)
946         {
947             for (size_t Pos=0; Pos<Count_Get(Stream_Audio); Pos++)
948                 if (!Retrieve(Stream_Audio, Pos, Audio_Delay).empty())
949                 {
950                     Fill(Stream_Audio, Pos, Audio_Video0_Delay, Retrieve(Stream_Audio, Pos, Audio_Delay).To_int64s()-Value.To_int64s(), 10, true);
951                     if (Retrieve(Stream_Audio, Pos, Audio_Video0_Delay).To_int64u()==0)
952                         for (size_t Param_Pos=Audio_Video0_Delay+1; Param_Pos<=Audio_Video0_Delay+4; Param_Pos++)
953                             if (Param_Pos<(*Stream)[Stream_Audio][Pos].size())
954                                 (*Stream)[Stream_Audio][Pos][Param_Pos].clear();
955                 }
956             for (size_t Pos=0; Pos<Count_Get(Stream_Text); Pos++)
957                 if (!Retrieve(Stream_Text, Pos, Text_Delay).empty())
958                 {
959                     Fill(Stream_Text, Pos, Text_Video0_Delay, Retrieve(Stream_Text, Pos, Text_Delay).To_int64s()-Value.To_int64s(), 10, true);
960                     if (Retrieve(Stream_Text, Pos, Text_Video0_Delay).To_int64u()==0)
961                         for (size_t Param_Pos=Text_Video0_Delay+1; Param_Pos<=Text_Video0_Delay+4; Param_Pos++)
962                             if (Param_Pos<(*Stream)[Stream_Text][Pos].size())
963                                 (*Stream)[Stream_Text][Pos][Param_Pos].clear();
964                 }
965         }
966         if (StreamKind==Stream_Audio && Parameter==Audio_Delay && Count_Get(Stream_Video) && !Retrieve(Stream_Audio, StreamPos, Audio_Delay).empty() && !Retrieve(Stream_Video, 0, Video_Delay).empty())
967         {
968             if (Replace)
969                 Clear(Stream_Audio, StreamPos, Audio_Video0_Delay);
970             ZtringList AudioDelay; AudioDelay.Separator_Set(0, __T(" / ")); AudioDelay.Write(Retrieve(Stream_Audio, StreamPos, Audio_Delay));
971             ZtringList VideoDelay; VideoDelay.Separator_Set(0, __T(" / ")); VideoDelay.Write(Retrieve(Stream_Video, 0, Video_Delay));
972             if (!AudioDelay.empty() && !VideoDelay.empty() && AudioDelay.size() <= VideoDelay.size())
973             {
974                 Fill(Stream_Audio, StreamPos, Audio_Video0_Delay, AudioDelay(AudioDelay.size() - 1).To_int64s() - VideoDelay(VideoDelay.size() - 1).To_int64s(), 10);
975                 if (VideoDelay.size()==1 && Retrieve(Stream_Audio, StreamPos, Audio_Video0_Delay).To_int64u()==0)
976                     for (size_t Pos=Audio_Video0_Delay+1; Pos<=Audio_Video0_Delay+4; Pos++)
977                         if (Pos<(*Stream)[Stream_Audio][StreamPos].size())
978                             (*Stream)[Stream_Audio][StreamPos][Pos].clear();
979             }
980         }
981         if (StreamKind==Stream_Text && Parameter==Text_Delay && Count_Get(Stream_Video) && !Retrieve(Stream_Text, StreamPos, Text_Delay).empty() && !Retrieve(Stream_Video, 0, Video_Delay).empty())
982         {
983             Ztring MuxingMode_MoreInfo=Get(Stream_Text, StreamPos, "MuxingMode_MoreInfo");
984             Ztring StreamID=MuxingMode_MoreInfo.SubString(__T("Muxed in Video #"), Ztring());
985             size_t StreamID_Int=(size_t)StreamID.To_int64u();
986             if (StreamID_Int)
987                 StreamID_Int--;
988             Fill(Stream_Text, StreamPos, Text_Video0_Delay, Value.To_int64s()-Retrieve(Stream_Video, StreamID_Int, Video_Delay).To_int64s(), 10, true);
989             if (Retrieve(Stream_Text, StreamPos, Text_Video0_Delay).To_int64u()==0)
990                 for (size_t Pos=Text_Video0_Delay+1; Pos<=Text_Video0_Delay+4; Pos++)
991                     if (Pos<(*Stream)[Stream_Text][StreamPos].size())
992                         (*Stream)[Stream_Text][StreamPos][Pos].clear();
993         }
994         if (StreamKind==Stream_Other && Parameter==Text_Delay && Count_Get(Stream_Video) && !Retrieve(Stream_Other, StreamPos, Text_Delay).empty() && !Retrieve(Stream_Video, 0, Video_Delay).empty())
995         {
996             Ztring MuxingMode_MoreInfo=Get(Stream_Other, StreamPos, "MuxingMode_MoreInfo");
997             Ztring StreamID=MuxingMode_MoreInfo.SubString(__T("Muxed in Video #"), Ztring());
998             size_t StreamID_Int=(size_t)StreamID.To_int64u();
999             if (StreamID_Int)
1000                 StreamID_Int--;
1001             Fill(Stream_Other, StreamPos, Text_Video0_Delay, Value.To_int64s()-Retrieve(Stream_Video, StreamID_Int, Video_Delay).To_int64s(), 10, true);
1002             if (Retrieve(Stream_Other, StreamPos, Text_Video0_Delay).To_int64u()==0)
1003                 for (size_t Pos=Text_Video0_Delay+1; Pos<=Text_Video0_Delay+4; Pos++)
1004                     if (Pos<(*Stream)[Stream_Other][StreamPos].size())
1005                         (*Stream)[Stream_Other][StreamPos][Pos].clear();
1006         }
1007 
1008         //Language
1009         //-Find 2-digit language
1010         if (Parameter==Fill_Parameter(StreamKind, Generic_Language))
1011         {
1012             //Removing old strings
1013             Clear(StreamKind, StreamPos, Parameter+1); //String
1014             Clear(StreamKind, StreamPos, Parameter+2); //String1
1015             Clear(StreamKind, StreamPos, Parameter+3); //String2
1016             Clear(StreamKind, StreamPos, Parameter+4); //String3
1017             Clear(StreamKind, StreamPos, Parameter+5); //String4
1018 
1019             ZtringListList Languages;
1020             Languages.Separator_Set(0, __T(" / "));
1021             Languages.Separator_Set(1, __T("-"));
1022             Languages.Write((*Stream)[StreamKind][StreamPos][Parameter]);
1023 
1024             //Canonizing
1025             for (size_t Pos=0; Pos<Languages.size(); Pos++)
1026             {
1027                 Ztring Language_Orig;
1028 
1029                 //Removing undefined languages
1030                 if (Languages[Pos].size()>=1)
1031                 {
1032                     Language_Orig=Languages[Pos][0];
1033                     Languages[Pos][0].MakeLowerCase();
1034                     if ((Languages[Pos][0].size()==3 && (Languages[Pos][0]==__T("mis")
1035                                                       || Languages[Pos][0]==__T("und")
1036                                                       || Languages[Pos][0]==__T("???")
1037                                                       || Languages[Pos][0]==__T("   ")))
1038                      || (Languages[Pos][0].size()==2 && Languages[Pos][0]==__T("  ")))
1039                         Languages[Pos].clear();
1040                 }
1041 
1042                 //Finding ISO-639-1 from ISO-639-2 or translated name
1043                 if (Languages[Pos].size()>=1)
1044                 {
1045                     if (Languages[Pos][0].size()==3 && !MediaInfoLib::Config.Iso639_1_Get(Languages[Pos][0]).empty())
1046                         Languages[Pos][0]=MediaInfoLib::Config.Iso639_1_Get(Languages[Pos][0]);
1047                     if (Languages[Pos][0].size()>3 && !MediaInfoLib::Config.Iso639_Find(Languages[Pos][0]).empty())
1048                         Languages[Pos][0]=MediaInfoLib::Config.Iso639_Find(Languages[Pos][0]);
1049                     if (Languages[Pos][0].size()>3)
1050                         Languages[Pos][0]=Language_Orig; //We failed to detect language, using the original version
1051                 }
1052             }
1053 
1054             if (Languages.Read()!=Retrieve(StreamKind, StreamPos, Parameter))
1055                 Fill(StreamKind, StreamPos, Parameter, Languages.Read(), true);
1056             else
1057             {
1058                 ZtringList Language1; Language1.Separator_Set(0, __T(" / "));
1059                 ZtringList Language2; Language2.Separator_Set(0, __T(" / "));
1060                 ZtringList Language3; Language3.Separator_Set(0, __T(" / "));
1061                 ZtringList Language4; Language4.Separator_Set(0, __T(" / "));
1062 
1063                 for (size_t Pos=0; Pos<Languages.size(); Pos++)
1064                 {
1065                     if (Languages[Pos].size()>=1)
1066                     {
1067                         Ztring Language_Translated;
1068                         if (Languages[Pos].size()==2)
1069                             Language_Translated=MediaInfoLib::Config.Language_Get(__T("Language_")+Languages[Pos].Read()); //Testing in case the langauge file has the complex form
1070                         if (Language_Translated.find(__T("Language_"))==0)
1071                             Language_Translated.clear(); //No translation found
1072                         if (Language_Translated.empty())
1073                         {
1074                         Language_Translated=MediaInfoLib::Config.Language_Get(__T("Language_")+Languages[Pos][0]);
1075                         if (Language_Translated.find(__T("Language_"))==0)
1076                             Language_Translated=Languages[Pos][0]; //No translation found
1077                         if (Languages[Pos].size()>=2)
1078                         {
1079                             if (Languages[Pos].size()==2 && Languages[Pos][1].size()>=2 && Languages[Pos][1].size()<=3 && (Languages[Pos][1][0]&0xDF)>=__T('A') && (Languages[Pos][1][0]&0xDF)<=__T('Z') && (Languages[Pos][1][1]&0xDF)>=__T('A') && (Languages[Pos][1][1]&0xDF)<=__T('Z'))
1080                             {
1081                                 Language_Translated+=__T(" (");
1082                                 Language_Translated+=Ztring(Languages[Pos][1]).MakeUpperCase();
1083                                 Language_Translated+=__T(")");
1084                             }
1085                             else
1086                                 for (size_t Pos2=1; Pos2<Languages[Pos].size(); Pos2++)
1087                                 {
1088                                     Language_Translated+=__T('-'); //As the original string
1089                                     Language_Translated+=Languages[Pos][Pos2];
1090                                 }
1091                         }
1092                         }
1093                         Language1.push_back(Language_Translated);
1094                         if (Languages[Pos][0].size()==2)
1095                         {
1096                             Language2.push_back(Languages[Pos][0]);
1097                             Language4.push_back(Languages[Pos].Read());
1098                         }
1099                         else
1100                         {
1101                             Language2.push_back(Ztring());
1102                             Language4.push_back(Ztring());
1103                         }
1104                         if (Languages[Pos][0].size()==3)
1105                             Language3.push_back(Languages[Pos][0]);
1106                         else if (!MediaInfoLib::Config.Iso639_2_Get(Languages[Pos][0]).empty())
1107                             Language3.push_back(MediaInfoLib::Config.Iso639_2_Get(Languages[Pos][0]));
1108                         else
1109                             Language3.push_back(Ztring());
1110                     }
1111                     else
1112                     {
1113                         Language1.push_back(Ztring());
1114                         Language2.push_back(Ztring());
1115                         Language3.push_back(Ztring());
1116                         Language4.push_back(Ztring());
1117                     }
1118                 }
1119 
1120                 Fill(StreamKind, StreamPos, Parameter+2, Language1.Read()); //String1
1121                 Fill(StreamKind, StreamPos, Parameter+3, Language2.Read()); //String2
1122                 Fill(StreamKind, StreamPos, Parameter+4, Language3.Read()); //String3
1123                 Fill(StreamKind, StreamPos, Parameter+5, Language4.Read()); //String4
1124                 Fill(StreamKind, StreamPos, Parameter+1, Retrieve(StreamKind, StreamPos, Parameter+2)); //String
1125             }
1126         }
1127 
1128         //ServiceName / ServiceProvider
1129         if (Parameter==Fill_Parameter(StreamKind, Generic_ServiceName)
1130          || Parameter==Fill_Parameter(StreamKind, Generic_ServiceProvider))
1131         {
1132             if (Retrieve(StreamKind, StreamPos, Parameter).find(__T(" - "))==string::npos && (Retrieve(StreamKind, StreamPos, Parameter).find(__T(':'))==2 || Retrieve(StreamKind, StreamPos, Parameter).find(__T(':'))==3))
1133             {
1134                 Ztring Temp=Retrieve(StreamKind, StreamPos, Parameter);
1135                 Temp.erase(0, Retrieve(StreamKind, StreamPos, Parameter).find(__T(':'))+1);
1136                 (*Stream)[StreamKind][StreamPos](Parameter)=Temp;
1137             }
1138         }
1139 
1140         //FrameRate Nominal
1141         if (StreamKind==Stream_Video && (Parameter==Video_FrameRate || Parameter==Video_FrameRate_Nominal))
1142         {
1143             float32 FrameRate=Retrieve(Stream_Video, StreamPos, Video_FrameRate).To_float32();
1144             float32 FrameRate_Nominal=Retrieve(Stream_Video, StreamPos, Video_FrameRate_Nominal).To_float32();
1145             if (FrameRate_Nominal>FrameRate*0.9995 && FrameRate_Nominal<FrameRate*1.0005)
1146             {
1147                 Ztring Temp=Retrieve(StreamKind, StreamPos, Video_FrameRate_Nominal);
1148                 Clear(StreamKind, StreamPos, Video_FrameRate_Nominal);
1149                 if (Parameter==Video_FrameRate)
1150                     Fill(StreamKind, StreamPos, Parameter, Temp, true);
1151             }
1152         }
1153 
1154         //Well known framerate values
1155         if (StreamKind==Stream_Video && (Parameter==Video_FrameRate || Parameter==Video_FrameRate_Nominal || Parameter==Video_FrameRate_Original)
1156          && Retrieve(Stream_Video, StreamPos, Video_FrameRate_Original_Num).empty()) // Ignoring when there is a num/den with discrepency between container and raw stream
1157         {
1158             Video_FrameRate_Rounding(StreamPos, (video)Parameter);
1159             if (Retrieve(Stream_Video, StreamPos, Video_FrameRate_Nominal)==Retrieve(Stream_Video, StreamPos, Video_FrameRate))
1160                 Clear(Stream_Video, StreamPos, Video_FrameRate_Nominal);
1161             if (Parameter!=Video_FrameRate_Original && Retrieve(Stream_Video, StreamPos, Video_FrameRate_Original)==Retrieve(Stream_Video, StreamPos, Video_FrameRate))
1162                 Clear(Stream_Video, StreamPos, Video_FrameRate_Original);
1163         }
1164 
1165         //Bits/(Pixel*Frame)
1166         if (StreamKind==Stream_Video && (Parameter==Video_BitRate || Parameter==Video_BitRate_Nominal || Parameter==Video_Width || Parameter==Video_Height || Parameter==Video_FrameRate))
1167         {
1168             float32 BitRate=Retrieve(Stream_Video, StreamPos, Video_BitRate).To_float32();
1169             if (BitRate==0)
1170                 BitRate=Retrieve(Stream_Video, StreamPos, Video_BitRate_Nominal).To_float32();
1171             float F1=(float)Retrieve(Stream_Video, StreamPos, Video_Width).To_int32s()*(float)Retrieve(Stream_Video, StreamPos, Video_Height).To_int32s()*Retrieve(Stream_Video, StreamPos, Video_FrameRate).To_float32();
1172             if (BitRate && F1)
1173                 Fill(Stream_Video, StreamPos, Video_Bits__Pixel_Frame_, BitRate/F1, 3, true);
1174         }
1175 
1176         //Well known bitrate values
1177         if (StreamKind==Stream_Video && (Parameter==Video_BitRate || Parameter==Video_BitRate_Nominal))
1178             Video_BitRate_Rounding(StreamPos, (video)Parameter);
1179         if (StreamKind==Stream_Audio && (Parameter==Audio_BitRate || Parameter==Audio_BitRate_Nominal))
1180             Audio_BitRate_Rounding(StreamPos, (audio)Parameter);
1181     }
1182 }
1183 
1184 //---------------------------------------------------------------------------
Fill(stream_t StreamKind,size_t StreamPos,size_t Parameter,float64 Value,int8u AfterComma,bool Replace)1185 void File__Analyze::Fill (stream_t StreamKind, size_t StreamPos, size_t Parameter, float64 Value, int8u AfterComma, bool Replace)
1186 {
1187     if (StreamKind==Stream_Video && Parameter==Video_FrameRate)
1188     {
1189         Clear(StreamKind, StreamPos, Video_FrameRate_Num);
1190         Clear(StreamKind, StreamPos, Video_FrameRate_Den);
1191 
1192         if (Value)
1193         {
1194             if (float64_int64s(Value) - Value*1.001000 > -0.000002
1195              && float64_int64s(Value) - Value*1.001000 < +0.000002) // Detection of precise 1.001 (e.g. 24000/1001) taking into account precision of 64-bit float
1196             {
1197                 Fill(StreamKind, StreamPos, Video_FrameRate_Num,  Value*1001, 0, Replace);
1198                 Fill(StreamKind, StreamPos, Video_FrameRate_Den,   1001, 10, Replace);
1199             }
1200             if (float64_int64s(Value) - Value*1.001001 > -0.000002
1201              && float64_int64s(Value) - Value*1.001001 < +0.000002) // Detection of rounded 1.001 (e.g. 23976/1000) taking into account precision of 64-bit float
1202             {
1203                 Fill(StreamKind, StreamPos, Video_FrameRate_Num,  Value*1000, 0, Replace);
1204                 Fill(StreamKind, StreamPos, Video_FrameRate_Den,   1000, 10, Replace);
1205             }
1206         }
1207     }
1208 
1209     if (StreamKind==Stream_Other && Parameter==Other_FrameRate)
1210     {
1211         Clear(StreamKind, StreamPos, Other_FrameRate_Num);
1212         Clear(StreamKind, StreamPos, Other_FrameRate_Den);
1213 
1214         if (Value)
1215         {
1216             if (float32_int32s(Value) - Value*1.001000 > -0.000002
1217              && float32_int32s(Value) - Value*1.001000 < +0.000002) // Detection of precise 1.001 (e.g. 24000/1001) taking into account precision of 32-bit float
1218             {
1219                 Fill(StreamKind, StreamPos, Other_FrameRate_Num,  Value*1001, 0, Replace);
1220                 Fill(StreamKind, StreamPos, Other_FrameRate_Den,   1001, 10, Replace);
1221             }
1222             if (float32_int32s(Value) - Value*1.001001 > -0.000002
1223              && float32_int32s(Value) - Value*1.001001 < +0.000002) // Detection of rounded 1.001 (e.g. 23976/1000) taking into account precision of 32-bit float
1224             {
1225                 Fill(StreamKind, StreamPos, Other_FrameRate_Num,  Value*1000, 0, Replace);
1226                 Fill(StreamKind, StreamPos, Other_FrameRate_Den,   1000, 10, Replace);
1227             }
1228         }
1229     }
1230 
1231     Fill(StreamKind, StreamPos, Parameter, Ztring::ToZtring(Value, AfterComma), Replace);
1232 }
1233 
1234 //---------------------------------------------------------------------------
Fill_Dup(stream_t StreamKind,size_t StreamPos,const char * Parameter,const Ztring & Value,bool Replace)1235 void File__Analyze::Fill_Dup(stream_t StreamKind, size_t StreamPos, const char* Parameter, const Ztring& Value, bool Replace)
1236 {
1237     const Ztring& OldValue=Retrieve_Const(StreamKind, StreamPos, Parameter);
1238     if (Value!=OldValue)
1239         Fill(StreamKind, StreamPos, Parameter, Value, Replace);
1240 }
1241 
1242 //---------------------------------------------------------------------------
Fill_Measure(stream_t StreamKind,size_t StreamPos,const char * Parameter,const Ztring & Value,const Ztring & Measure,bool Replace)1243 void File__Analyze::Fill_Measure(stream_t StreamKind, size_t StreamPos, const char* Parameter, const Ztring& Value, const Ztring& Measure, bool Replace)
1244 {
1245     string Parameter_String(Parameter);
1246     Parameter_String+="/String";
1247     Fill(StreamKind, StreamPos, Parameter, Value, Replace);
1248     Fill_SetOptions(StreamKind, StreamPos, Parameter, "N NFY");
1249     Fill(StreamKind, StreamPos, Parameter_String.c_str(), MediaInfoLib::Config.Language_Get(Value, Measure), Replace);
1250     Fill_SetOptions(StreamKind, StreamPos, Parameter_String.c_str(), "Y NFN");
1251 }
1252 
1253 //---------------------------------------------------------------------------
Fill(stream_t StreamKind,size_t StreamPos,const char * Parameter,const Ztring & Value,bool Replace)1254 void File__Analyze::Fill (stream_t StreamKind, size_t StreamPos, const char* Parameter, const Ztring &Value, bool Replace)
1255 {
1256     //Integrity
1257     if (StreamKind>Stream_Max || Parameter==NULL || Parameter[0]=='\0')
1258         return;
1259 
1260     //Handling values with \r\n inside
1261     if (Value.find_first_of(__T("\r\n"))!=string::npos)
1262     {
1263         Ztring CarriageReturnReplace=MediaInfoLib::Config.CarriageReturnReplace_Get();
1264         if (!CarriageReturnReplace.empty())
1265         {
1266             Ztring NewValue=Value;
1267             NewValue.FindAndReplace(__T("\r\n"), CarriageReturnReplace, 0, Ztring_Recursive);
1268             NewValue.FindAndReplace(__T("\r"), CarriageReturnReplace, 0, Ztring_Recursive);
1269             NewValue.FindAndReplace(__T("\n"), CarriageReturnReplace, 0, Ztring_Recursive);
1270             if (NewValue.size()>=CarriageReturnReplace.size() && NewValue.rfind(CarriageReturnReplace)==NewValue.size()-CarriageReturnReplace.size())
1271                 NewValue.resize(NewValue.size()-CarriageReturnReplace.size());
1272             Fill(StreamKind, StreamPos, Parameter, NewValue, Replace);
1273             return;
1274         }
1275     }
1276 
1277     //Handle Value before StreamKind
1278     if (StreamKind==Stream_Max || StreamPos>=(*Stream)[StreamKind].size())
1279     {
1280         size_t StreamKindS=(size_t)StreamKind;
1281         if (StreamKind!=Stream_Max)
1282         {
1283             //Stream kind is found, moving content
1284             for (size_t Pos=0; Pos<Fill_Temp[Stream_Max].size(); Pos++)
1285                 Fill_Temp[StreamKind].push_back(Fill_Temp[Stream_Max][Pos]);
1286             Fill_Temp[Stream_Max].clear();
1287         }
1288         else
1289         {
1290             //Stream kind is not found, checking if it was found previously
1291             for (StreamKindS=(size_t)Stream_General+1; StreamKindS<(size_t)Stream_Max; StreamKindS++)
1292                 if (!Fill_Temp[StreamKindS].empty())
1293                     break;
1294         }
1295 
1296         const Ztring Parameter_UTF8 = Ztring().From_UTF8(Parameter);
1297         if (Replace)
1298         {
1299             for (size_t Pos=0; Pos<Fill_Temp[StreamKindS].size(); Pos++)
1300                 if (Fill_Temp[StreamKindS][Pos].Parameter== Parameter_UTF8)
1301                 {
1302                     Fill_Temp[StreamKindS][Pos].Value=Value;
1303                     return;
1304                 }
1305         }
1306         fill_temp_item NewList;
1307         NewList.Parameter= Parameter_UTF8;
1308         NewList.Value=Value;
1309         Fill_Temp[StreamKindS].push_back(NewList);
1310         return; //No streams
1311     }
1312 
1313     //Handling of well known parameters
1314     const Ztring Parameter_Local = Ztring().From_UTF8(Parameter);
1315     const size_t Pos=MediaInfoLib::Config.Info_Get(StreamKind).Find(Parameter_Local);
1316     if (Pos!=Error)
1317     {
1318         Fill(StreamKind, StreamPos, Pos, Value, Replace);
1319         return;
1320     }
1321 
1322     if (StreamKind==Stream_Other && !strcmp(Parameter, "Codec"))
1323         return; // "Codec" does not exist in "Other"
1324 
1325     //Handling of unknown parameters
1326     ZtringListList& Stream_More_Item = (*Stream_More)[StreamKind][StreamPos];
1327     const Ztring Parameter_ISO = Ztring().From_ISO_8859_1(Parameter);
1328     if (Value.empty())
1329     {
1330         if (Replace)
1331         {
1332             const size_t Pos_ToReplace= Stream_More_Item.Find(Parameter_ISO, Info_Name);
1333             if (Pos_ToReplace!=(size_t)-1)
1334                 Stream_More_Item.erase(Stream_More_Item.begin()+Pos_ToReplace); //Empty value --> remove the line
1335         }
1336     }
1337     else
1338     {
1339         size_t Space=Parameter_ISO.find(__T(' '));
1340         size_t LastFound=(size_t)-1;
1341         if (Space!=string::npos)
1342         {
1343             Ztring ToSearch=Parameter_ISO.substr(0, Space);
1344             for (size_t i=0; i<Stream_More_Item.size(); i++)
1345             {
1346                 if (Stream_More_Item(i, Info_Name).rfind(ToSearch, ToSearch.size())==0 && (Stream_More_Item(i, Info_Name).size()==ToSearch.size() || Stream_More_Item(i, Info_Name)[ToSearch.size()]==__T(' ')))
1347                     LastFound=i;
1348             }
1349             if (LastFound!=(size_t)-1)
1350             {
1351                 ZtringList ToInsert;
1352                 ToInsert(Info_Name)=Parameter_ISO;
1353                 Stream_More_Item.insert(Stream_More_Item.begin()+LastFound+1, ToInsert);
1354             }
1355         }
1356 
1357         Ztring &Target= Stream_More_Item(Parameter_ISO, Info_Text);
1358         if (Target.empty() || Replace)
1359         {
1360             Target=Value; //First value
1361             Stream_More_Item(Parameter_ISO, Info_Name_Text)=MediaInfoLib::Config.Language_Get(Parameter_Local);
1362             Fill_SetOptions(StreamKind, StreamPos, Parameter, "Y NT");
1363         }
1364         else
1365         {
1366             Target+=MediaInfoLib::Config.TagSeparator_Get();
1367             Target+=Value;
1368         }
1369     }
1370     Fill(StreamKind, StreamPos, (size_t)General_Count, Count_Get(StreamKind, StreamPos), 10, true);
1371 }
1372 
1373 //---------------------------------------------------------------------------
Fill(stream_t StreamKind,size_t StreamPos,const char * Parameter,ZtringList & Value,ZtringList & Id,bool Replace)1374 void File__Analyze::Fill (stream_t StreamKind, size_t StreamPos, const char* Parameter, ZtringList &Value, ZtringList& Id, bool Replace)
1375 {
1376     //Test if not empty
1377     size_t Value_Size=Value.size();
1378     size_t i=0;
1379     for (; i<Value_Size; i++)
1380         if (!Value[i].empty())
1381             break;
1382     if (i==Value_Size)
1383         return;
1384 
1385     if (Value.size()!=Id.size())
1386     {
1387         Value.Separator_Set(0, __T(" / "));
1388         Fill(StreamKind, StreamPos, Parameter, Value.Read());
1389         return;
1390     }
1391 
1392     ZtringList List;
1393     List.Separator_Set(0, __T(" / "));
1394     for (size_t i=0; i<Value.size(); i++)
1395         if (!Value[i].empty()) // Only if there is a content
1396             List.push_back(Value[i]+(Id[i].empty()?Ztring():(__T(" (")+Id[i]+__T(')'))));
1397     Fill(StreamKind, StreamPos, Parameter, List.Read());
1398 }
1399 
1400 //---------------------------------------------------------------------------
Fill_SetOptions(stream_t StreamKind,size_t StreamPos,const char * Parameter,const char * Options)1401 void File__Analyze::Fill_SetOptions(stream_t StreamKind, size_t StreamPos, const char* Parameter, const char* Options)
1402 {
1403     //Integrity
1404     if (StreamKind>Stream_Max || Parameter==NULL || Parameter[0]=='\0')
1405         return;
1406 
1407     //Handle Value before StreamKind
1408     if (!Status[IsAccepted] || StreamKind==Stream_Max || StreamPos>=(*Stream)[StreamKind].size())
1409     {
1410         Fill_Temp_Options[StreamKind][Parameter]=Options;
1411         return; //No streams
1412     }
1413 
1414     //Handling of well known parameters
1415     size_t Pos=MediaInfoLib::Config.Info_Get(StreamKind).Find(Ztring().From_UTF8(Parameter));
1416     if (Pos!=Error)
1417     {
1418         //We can not change that
1419         return;
1420     }
1421 
1422     (*Stream_More)[StreamKind][StreamPos](Ztring().From_ISO_8859_1(Parameter), Info_Options).From_UTF8(Options);
1423 }
1424 
1425 //---------------------------------------------------------------------------
Retrieve_Const(stream_t StreamKind,size_t StreamPos,size_t Parameter,info_t KindOfInfo)1426 const Ztring &File__Analyze::Retrieve_Const (stream_t StreamKind, size_t StreamPos, size_t Parameter, info_t KindOfInfo)
1427 {
1428     //Integrity
1429     if (StreamKind>=Stream_Max
1430      || StreamPos>=(*Stream)[StreamKind].size()
1431      || Parameter>=MediaInfoLib::Config.Info_Get(StreamKind).size()+(*Stream_More)[StreamKind][StreamPos].size())
1432     {
1433         if (StreamKind<sizeof(Fill_Temp)/sizeof(vector<fill_temp_item>))
1434         {
1435             Ztring Parameter_Local;
1436             Parameter_Local.From_Number(Parameter);
1437             for (size_t Pos=0; Pos<Fill_Temp[StreamKind].size(); Pos++)
1438                 if (Fill_Temp[StreamKind][Pos].Parameter==Parameter_Local)
1439                     return Fill_Temp[StreamKind][Pos].Value;
1440         }
1441 
1442         return MediaInfoLib::Config.EmptyString_Get();
1443     }
1444 
1445     if (Parameter>=MediaInfoLib::Config.Info_Get(StreamKind).size())
1446     {
1447         Parameter-=MediaInfoLib::Config.Info_Get(StreamKind).size();
1448         if (KindOfInfo>=(*Stream_More)[StreamKind][StreamPos][Parameter].size())
1449             return MediaInfoLib::Config.EmptyString_Get();
1450         return (*Stream_More)[StreamKind][StreamPos][Parameter][KindOfInfo];
1451     }
1452 
1453     if (KindOfInfo!=Info_Text)
1454         return MediaInfoLib::Config.Info_Get(StreamKind, Parameter, KindOfInfo);
1455 
1456     if (StreamKind>=(*Stream).size() || StreamPos>=(*Stream)[StreamKind].size() || Parameter>=(*Stream)[StreamKind][StreamPos].size())
1457         return MediaInfoLib::Config.EmptyString_Get();
1458     return (*Stream)[StreamKind][StreamPos](Parameter);
1459 }
1460 
1461 //---------------------------------------------------------------------------
Retrieve(stream_t StreamKind,size_t StreamPos,size_t Parameter,info_t KindOfInfo)1462 Ztring File__Analyze::Retrieve (stream_t StreamKind, size_t StreamPos, size_t Parameter, info_t KindOfInfo)
1463 {
1464     //Integrity
1465     if (StreamKind>=Stream_Max
1466      || StreamPos>=(*Stream)[StreamKind].size()
1467      || Parameter>=MediaInfoLib::Config.Info_Get(StreamKind).size()+(*Stream_More)[StreamKind][StreamPos].size())
1468         return MediaInfoLib::Config.EmptyString_Get();
1469 
1470     if (Parameter>=MediaInfoLib::Config.Info_Get(StreamKind).size())
1471     {
1472         Parameter-=MediaInfoLib::Config.Info_Get(StreamKind).size();
1473         if (KindOfInfo>=(*Stream_More)[StreamKind][StreamPos][Parameter].size())
1474             return MediaInfoLib::Config.EmptyString_Get();
1475         return (*Stream_More)[StreamKind][StreamPos][Parameter][KindOfInfo];
1476     }
1477 
1478     if (KindOfInfo!=Info_Text)
1479         return MediaInfoLib::Config.Info_Get(StreamKind, Parameter, KindOfInfo);
1480 
1481     if (StreamKind>=(*Stream).size() || StreamPos>=(*Stream)[StreamKind].size() || Parameter>=(*Stream)[StreamKind][StreamPos].size())
1482         return MediaInfoLib::Config.EmptyString_Get();
1483     return (*Stream)[StreamKind][StreamPos](Parameter);
1484 }
1485 
1486 //---------------------------------------------------------------------------
Retrieve_Const(stream_t StreamKind,size_t StreamPos,const char * Parameter,info_t KindOfInfo)1487 const Ztring &File__Analyze::Retrieve_Const (stream_t StreamKind, size_t StreamPos, const char* Parameter, info_t KindOfInfo)
1488 {
1489     //Integrity
1490     if (StreamKind>=Stream_Max
1491      || Parameter==NULL
1492      || Parameter[0]=='\0')
1493         return MediaInfoLib::Config.EmptyString_Get();
1494 
1495     if (KindOfInfo!=Info_Text)
1496         return MediaInfoLib::Config.Info_Get(StreamKind, Parameter, KindOfInfo);
1497     const Ztring Parameter_Local = Ztring().From_UTF8(Parameter);
1498     size_t Parameter_Pos=MediaInfoLib::Config.Info_Get(StreamKind).Find(Parameter_Local);
1499     if (Parameter_Pos==Error)
1500     {
1501         if (StreamPos==(*Stream)[StreamKind].size())
1502         {
1503             for (size_t Pos=0; Pos<Fill_Temp[StreamKind].size(); Pos++)
1504                 if (Fill_Temp[StreamKind][Pos].Parameter==Parameter_Local)
1505                     return Fill_Temp[StreamKind][Pos].Value;
1506         }
1507         if (StreamPos>=(*Stream)[StreamKind].size())
1508             return MediaInfoLib::Config.EmptyString_Get();
1509         Parameter_Pos=(*Stream_More)[StreamKind][StreamPos].Find(Parameter_Local);
1510         if (Parameter_Pos==Error)
1511             return MediaInfoLib::Config.EmptyString_Get();
1512         return (*Stream_More)[StreamKind][StreamPos](Parameter_Pos, 1);
1513     }
1514     if (StreamKind>=(*Stream).size() || StreamPos>=(*Stream)[StreamKind].size() || Parameter_Pos>=(*Stream)[StreamKind][StreamPos].size())
1515         return MediaInfoLib::Config.EmptyString_Get();
1516     return (*Stream)[StreamKind][StreamPos](Parameter_Pos);
1517 }
1518 
1519 //---------------------------------------------------------------------------
Retrieve(stream_t StreamKind,size_t StreamPos,const char * Parameter,info_t KindOfInfo)1520 Ztring File__Analyze::Retrieve (stream_t StreamKind, size_t StreamPos, const char* Parameter, info_t KindOfInfo)
1521 {
1522     //Integrity
1523     if (StreamKind>=Stream_Max
1524      || StreamPos>=(*Stream)[StreamKind].size()
1525      || Parameter==NULL
1526      || Parameter[0]=='\0')
1527         return MediaInfoLib::Config.EmptyString_Get();
1528 
1529     if (KindOfInfo!=Info_Text)
1530         return MediaInfoLib::Config.Info_Get(StreamKind, Parameter, KindOfInfo);
1531     const Ztring Parameter_Local = Ztring().From_UTF8(Parameter);
1532     size_t Parameter_Pos=MediaInfoLib::Config.Info_Get(StreamKind).Find(Parameter_Local);
1533     if (Parameter_Pos==Error)
1534     {
1535         Parameter_Pos=(*Stream_More)[StreamKind][StreamPos].Find(Parameter_Local);
1536         if (Parameter_Pos==Error)
1537             return MediaInfoLib::Config.EmptyString_Get();
1538         return (*Stream_More)[StreamKind][StreamPos](Parameter_Pos, 1);
1539     }
1540     if (StreamKind>=(*Stream).size() || StreamPos>=(*Stream)[StreamKind].size() || Parameter_Pos>=(*Stream)[StreamKind][StreamPos].size())
1541         return MediaInfoLib::Config.EmptyString_Get();
1542     return (*Stream)[StreamKind][StreamPos](Parameter_Pos);
1543 }
1544 
1545 //---------------------------------------------------------------------------
Clear(stream_t StreamKind,size_t StreamPos,const char * Parameter)1546 void File__Analyze::Clear (stream_t StreamKind, size_t StreamPos, const char* Parameter)
1547 {
1548     //Integrity
1549     if (StreamKind>=Stream_Max
1550      || Parameter==NULL
1551      || Parameter[0]=='\0')
1552         return;
1553 
1554     if (StreamPos>=(*Stream)[StreamKind].size())
1555     {
1556         Ztring Parameter_String=Ztring().From_UTF8(Parameter);
1557         for (size_t Pos=0; Pos<Fill_Temp[StreamKind].size(); Pos++)
1558             if (Fill_Temp[StreamKind][Pos].Parameter==Parameter_String)
1559             {
1560                 Fill_Temp[StreamKind].erase(Fill_Temp[StreamKind].begin() + Pos);
1561                 Pos--;
1562             }
1563         return;
1564     }
1565     const Ztring Parameter_Local = Ztring().From_UTF8(Parameter);
1566     size_t Parameter_Pos=MediaInfoLib::Config.Info_Get(StreamKind).Find(Parameter_Local);
1567     if (Parameter_Pos==Error)
1568     {
1569         Parameter_Pos=(*Stream_More)[StreamKind][StreamPos].Find(Parameter_Local);
1570         if (Parameter_Pos==Error)
1571             return;
1572         (*Stream_More)[StreamKind][StreamPos](Parameter_Pos, 1).clear();
1573         return;
1574     }
1575 
1576     Clear(StreamKind, StreamPos, Parameter_Pos);
1577 }
1578 
1579 //---------------------------------------------------------------------------
Clear(stream_t StreamKind,size_t StreamPos,size_t Parameter)1580 void File__Analyze::Clear (stream_t StreamKind, size_t StreamPos, size_t Parameter)
1581 {
1582     //Integrity
1583     if (StreamKind>=Stream_Max
1584      || StreamPos>=(*Stream)[StreamKind].size())
1585         return;
1586 
1587     //Normal
1588     if (Parameter<MediaInfoLib::Config.Info_Get(StreamKind).size())
1589     {
1590         //Is something available?
1591         if (Parameter>=(*Stream)[StreamKind][StreamPos].size())
1592             return; //Was never filled, no nead to clear it
1593 
1594         //Clearing
1595         (*Stream)[StreamKind][StreamPos][Parameter].clear();
1596 
1597         //Human readable
1598         if (MediaInfoLib::Config.ReadByHuman_Get())
1599         {
1600             //Strings
1601             const Ztring &List_Measure_Value=MediaInfoLib::Config.Info_Get(StreamKind).Read(Parameter, Info_Measure);
1602                  if (List_Measure_Value==__T(" byte"))
1603             {
1604                 const Ztring &Temp=MediaInfoLib::Config.Info_Get(StreamKind).Read(Parameter, Info_Name);
1605                 size_t List_Size=Temp.find(__T("StreamSize"))==string::npos?5:7; //for /String5, with percentage, and proportion
1606                 for (size_t Pos=Parameter+1; Pos<=Parameter+List_Size; Pos++)
1607                     if (Pos<(*Stream)[StreamKind][StreamPos].size())
1608                         (*Stream)[StreamKind][StreamPos][Pos].clear();
1609             }
1610             else if (List_Measure_Value==__T(" bps") || List_Measure_Value==__T(" Hz"))
1611             {
1612                 if (Parameter+1<(*Stream)[StreamKind][StreamPos].size())
1613                     (*Stream)[StreamKind][StreamPos][Parameter+1].clear();
1614             }
1615             else if (List_Measure_Value==__T(" ms"))
1616             {
1617                 for (size_t Pos=Parameter+1; Pos<=Parameter+6; Pos++)
1618                     if (Pos<(*Stream)[StreamKind][StreamPos].size())
1619                         (*Stream)[StreamKind][StreamPos][Pos].clear();
1620             }
1621             else if (List_Measure_Value==__T("Yes"))
1622             {
1623                 if (Parameter+1<(*Stream)[StreamKind][StreamPos].size())
1624                     (*Stream)[StreamKind][StreamPos][Parameter+1].clear();
1625             }
1626             else if (!List_Measure_Value.empty())
1627             {
1628                 if (Parameter+1<(*Stream)[StreamKind][StreamPos].size())
1629                     (*Stream)[StreamKind][StreamPos][Parameter+1].clear();
1630             }
1631             else if (Parameter+1<(*Stream)[StreamKind][StreamPos].size() && MediaInfoLib::Config.Info_Get(StreamKind).Read(Parameter+1, Info_Name).find(__T("/String"))!=string::npos)
1632             {
1633                 (*Stream)[StreamKind][StreamPos][Parameter+1].clear();
1634             }
1635         }
1636 
1637         return;
1638     }
1639 
1640     //More
1641     Parameter-=(*Stream)[StreamKind][StreamPos].size(); //For having Stream_More position
1642     if (Parameter<(*Stream_More)[StreamKind][StreamPos].size())
1643     {
1644         (*Stream_More)[StreamKind][StreamPos].erase((*Stream_More)[StreamKind][StreamPos].begin()+Parameter);
1645         return;
1646     }
1647 }
1648 
1649 //---------------------------------------------------------------------------
Clear(stream_t StreamKind,size_t StreamPos)1650 void File__Analyze::Clear (stream_t StreamKind, size_t StreamPos)
1651 {
1652     //Integrity
1653     if (StreamKind>=Stream_Max
1654      || StreamPos>=(*Stream)[StreamKind].size())
1655         return;
1656 
1657     (*Stream)[StreamKind].erase((*Stream)[StreamKind].begin()+StreamPos);
1658 }
1659 
1660 //---------------------------------------------------------------------------
Clear(stream_t StreamKind)1661 void File__Analyze::Clear (stream_t StreamKind)
1662 {
1663     //Integrity
1664     if (StreamKind>=Stream_Max)
1665         return;
1666 
1667     (*Stream)[StreamKind].clear();
1668 }
1669 
1670 //---------------------------------------------------------------------------
Fill_Flush()1671 void File__Analyze::Fill_Flush()
1672 {
1673     Stream_Prepare(Stream_Max); //clear filling
1674     for (size_t StreamKind=(size_t)Stream_General; StreamKind<(size_t)Stream_Max+1; StreamKind++) // +1 because Fill_Temp[Stream_Max] is used when StreamKind is unknown
1675     {
1676         Fill_Temp[StreamKind].clear();
1677         Fill_Temp_Options[StreamKind].clear();
1678     }
1679 }
1680 
1681 //---------------------------------------------------------------------------
Merge(MediaInfo_Internal & ToAdd,bool)1682 size_t File__Analyze::Merge(MediaInfo_Internal &ToAdd, bool)
1683 {
1684     size_t Count=0;
1685     for (size_t StreamKind=(size_t)Stream_General; StreamKind<(size_t)Stream_Max; StreamKind++)
1686     {
1687         size_t StreamPos_Count=ToAdd.Count_Get((stream_t)StreamKind);
1688         for (size_t StreamPos=0; StreamPos<StreamPos_Count; StreamPos++)
1689         {
1690             //Prepare a new stream
1691             if (StreamPos>=Count_Get((stream_t)StreamKind))
1692                 Stream_Prepare((stream_t)StreamKind);
1693 
1694             //Merge
1695             size_t Pos_Count=ToAdd.Count_Get((stream_t)StreamKind, StreamPos);
1696             for (size_t Pos=0; Pos<Pos_Count; Pos++)
1697             {
1698                 if (StreamKind!=Stream_General
1699                  || !(Pos==General_CompleteName
1700                    || Pos==General_CompleteName_Last
1701                    || Pos==General_FolderName
1702                    || Pos==General_FileName
1703                    || Pos==General_FileExtension
1704                    || Pos==General_File_Created_Date
1705                    || Pos==General_Format
1706                    || Pos==General_Format_String
1707                    || Pos==General_Format_Extensions
1708                    || Pos==General_Format_Info
1709                    || Pos==General_Codec
1710                    || Pos==General_Codec_String
1711                    || Pos==General_Codec_Extensions
1712                    || Pos==General_FileSize
1713                    || Pos==General_FileSize_String
1714                    || Pos==General_FileSize_String1
1715                    || Pos==General_FileSize_String2
1716                    || Pos==General_FileSize_String3
1717                    || Pos==General_FileSize_String4
1718                    || Pos==General_File_Created_Date_Local
1719                    || Pos==General_File_Modified_Date
1720                    || Pos==General_File_Modified_Date_Local))
1721                     Fill((stream_t)StreamKind, StreamPos, Ztring(ToAdd.Get((stream_t)StreamKind, StreamPos, Pos, Info_Name)).To_UTF8().c_str(), ToAdd.Get((stream_t)StreamKind, StreamPos, Pos), true);
1722             }
1723 
1724             Count++;
1725         }
1726     }
1727 
1728     return Count;
1729 }
1730 
1731 //---------------------------------------------------------------------------
Merge(MediaInfo_Internal & ToAdd,stream_t StreamKind,size_t StreamPos_From,size_t StreamPos_To,bool)1732 size_t File__Analyze::Merge(MediaInfo_Internal &ToAdd, stream_t StreamKind, size_t StreamPos_From, size_t StreamPos_To, bool)
1733 {
1734     size_t Pos_Count=ToAdd.Count_Get(StreamKind, StreamPos_From);
1735     for (size_t Pos=General_Inform; Pos<Pos_Count; Pos++)
1736         if (!ToAdd.Get(StreamKind, StreamPos_From, Pos).empty())
1737             Fill(StreamKind, StreamPos_To, Ztring(ToAdd.Get((stream_t)StreamKind, StreamPos_From, Pos, Info_Name)).To_UTF8().c_str(), ToAdd.Get(StreamKind, StreamPos_From, Pos), true);
1738 
1739     return 1;
1740 }
1741 
1742 //---------------------------------------------------------------------------
Merge(File__Analyze & ToAdd,bool Erase)1743 size_t File__Analyze::Merge(File__Analyze &ToAdd, bool Erase)
1744 {
1745     MergedStreams_Last.clear();
1746 
1747     size_t Count=0;
1748     for (size_t StreamKind=(size_t)Stream_General+1; StreamKind<(size_t)Stream_Max; StreamKind++)
1749         for (size_t StreamPos=0; StreamPos<(*ToAdd.Stream)[StreamKind].size(); StreamPos++)
1750         {
1751             //Prepare a new stream
1752             Stream_Prepare((stream_t)StreamKind);
1753             MergedStreams_Last.push_back(streamidentity(StreamKind_Last, StreamPos_Last));
1754 
1755             //Merge
1756             Merge(ToAdd, (stream_t)StreamKind, StreamPos, StreamPos_Last, Erase);
1757 
1758             Count++;
1759         }
1760     return Count;
1761 }
1762 
1763 //---------------------------------------------------------------------------
Merge(File__Analyze & ToAdd,stream_t StreamKind,size_t StreamPos_From,size_t StreamPos_To,bool Erase)1764 size_t File__Analyze::Merge(File__Analyze &ToAdd, stream_t StreamKind, size_t StreamPos_From, size_t StreamPos_To, bool Erase)
1765 {
1766     //Integrity
1767     if (StreamKind>=Stream_Max || !ToAdd.Stream || StreamPos_From>=(*ToAdd.Stream)[StreamKind].size())
1768         return 0;
1769 
1770     //Destination
1771     while (StreamPos_To>=(*Stream)[StreamKind].size())
1772         Stream_Prepare(StreamKind);
1773 
1774     //Specific stuff
1775     Ztring Width_Temp, Height_Temp, PixelAspectRatio_Temp, DisplayAspectRatio_Temp, FrameRate_Temp, FrameRate_Num_Temp, FrameRate_Den_Temp, FrameRate_Mode_Temp, ScanType_Temp, ScanOrder_Temp, HDR_Temp[Video_HDR_Format_Compatibility-Video_HDR_Format+1], Channels_Temp[4], Delay_Temp, Delay_DropFrame_Temp, Delay_Source_Temp, Delay_Settings_Temp, Source_Temp, Source_Kind_Temp, Source_Info_Temp;
1776     if (StreamKind==Stream_Video)
1777     {
1778         Width_Temp=Retrieve(Stream_Video, StreamPos_To, Video_Width);
1779         Height_Temp=Retrieve(Stream_Video, StreamPos_To, Video_Height);
1780         PixelAspectRatio_Temp=Retrieve(Stream_Video, StreamPos_To, Video_PixelAspectRatio); //We want to keep the PixelAspectRatio_Temp of the video stream
1781         DisplayAspectRatio_Temp=Retrieve(Stream_Video, StreamPos_To, Video_DisplayAspectRatio); //We want to keep the DisplayAspectRatio_Temp of the video stream
1782         FrameRate_Temp=Retrieve(Stream_Video, StreamPos_To, Video_FrameRate); //We want to keep the FrameRate of AVI 120 fps
1783         FrameRate_Num_Temp=Retrieve(Stream_Video, StreamPos_To, Video_FrameRate_Num);
1784         FrameRate_Den_Temp=Retrieve(Stream_Video, StreamPos_To, Video_FrameRate_Den);
1785         FrameRate_Mode_Temp=Retrieve(Stream_Video, StreamPos_To, Video_FrameRate_Mode); //We want to keep the FrameRate_Mode of AVI 120 fps
1786         ScanType_Temp=Retrieve(Stream_Video, StreamPos_To, Video_ScanType);
1787         ScanOrder_Temp=Retrieve(Stream_Video, StreamPos_To, Video_ScanOrder);
1788         for (size_t i=Video_HDR_Format; i<=Video_HDR_Format_Compatibility; i++)
1789             HDR_Temp[i-Video_HDR_Format]=Retrieve(Stream_Video, StreamPos_To, i);
1790     }
1791     if (StreamKind==Stream_Audio)
1792     {
1793         Channels_Temp[0]=Retrieve(Stream_Audio, StreamPos_To, Audio_Channel_s_);
1794         Channels_Temp[2]=Retrieve(Stream_Audio, StreamPos_To, Audio_ChannelPositions);
1795         Channels_Temp[3]=Retrieve(Stream_Audio, StreamPos_To, Audio_ChannelPositions_String2);
1796         Channels_Temp[1]=Retrieve(Stream_Audio, StreamPos_To, Audio_ChannelLayout);
1797     }
1798     if (ToAdd.Retrieve(StreamKind, StreamPos_From, Fill_Parameter(StreamKind, Generic_Delay_Source))==__T("Container"))
1799     {
1800         Fill(StreamKind, StreamPos_To, "Delay_Original", Retrieve(StreamKind, StreamPos_To, "Delay"), true);
1801         Clear(StreamKind, StreamPos_To, "Delay");
1802         Fill(StreamKind, StreamPos_To, "Delay_Original_DropFrame", Retrieve(StreamKind, StreamPos_To, "Delay_DropFrame"), true);
1803         Clear(StreamKind, StreamPos_To, "Delay_DropFrame");
1804         Fill(StreamKind, StreamPos_To, "Delay_Original_Source", Retrieve(StreamKind, StreamPos_To, "Delay_Source"), true);
1805         Clear(StreamKind, StreamPos_To, "Delay_Source");
1806         if (!ToAdd.Retrieve(StreamKind, StreamPos_To, "Format").empty()) //Exception: MPEG-4 TimeCode, settings are in the MPEG-4 header
1807         {
1808             Fill(StreamKind, StreamPos_To, "Delay_Original_Settings", Retrieve(StreamKind, StreamPos_To, "Delay_Settings"), true);
1809             Clear(StreamKind, StreamPos_To, "Delay_Settings");
1810         }
1811     }
1812     else
1813     {
1814         Delay_Temp=Retrieve(StreamKind, StreamPos_To, "Delay"); //We want to keep the Delay from the stream
1815         Delay_Settings_Temp=Retrieve(StreamKind, StreamPos_To, "Delay_Settings"); //We want to keep the Delay_Settings from the stream
1816         Delay_DropFrame_Temp=Retrieve(StreamKind, StreamPos_To, "Delay_DropFrame"); //We want to keep the Delay_Source from the stream
1817         Delay_Source_Temp=Retrieve(StreamKind, StreamPos_To, "Delay_Source"); //We want to keep the Delay_Source from the stream
1818     }
1819     Source_Temp=Retrieve(StreamKind, StreamPos_To, "Source");
1820     Source_Kind_Temp=Retrieve(StreamKind, StreamPos_To, "Source_Kind");
1821     Source_Info_Temp=Retrieve(StreamKind, StreamPos_To, "Source_Info");
1822     Ztring BitRate_Temp=Retrieve(StreamKind, StreamPos_To, "BitRate");
1823     Ztring CodecID_Temp=Retrieve(StreamKind, StreamPos_To, "CodecID");
1824     Ztring Title_Temp=Retrieve(StreamKind, StreamPos_To, "Title");
1825 
1826     //Merging
1827     size_t Size=ToAdd.Count_Get(StreamKind, StreamPos_From);
1828     for (size_t Pos=General_Inform; Pos<Size; Pos++)
1829     {
1830         const Ztring &ToFill_Value=ToAdd.Get(StreamKind, StreamPos_From, Pos);
1831         if (StreamKind==Stream_Video && ShowSource_IsInList((video)Pos))
1832         {
1833             const Ztring &ToFill_FromContainer=Get(StreamKind, StreamPos_To, Pos);
1834             if (!ToAdd.Retrieve_Const(StreamKind, StreamPos_From, Pos+1).empty())
1835             {
1836                 if (!Retrieve_Const(StreamKind, StreamPos_To, Pos+1).empty())
1837                 {
1838                     if (ToFill_Value==ToFill_FromContainer)
1839                     {
1840                         if (Retrieve_Const(StreamKind, StreamPos_To, Pos+1)!=ToAdd.Retrieve_Const(StreamKind, StreamPos_From, Pos+1))
1841                             Fill(StreamKind, StreamPos_To, Pos+1, Retrieve_Const(StreamKind, StreamPos_To, Pos+1)+MediaInfoLib::Config.TagSeparator_Get()+ToAdd.Retrieve_Const(StreamKind, StreamPos_From, Pos+1), true);
1842                     }
1843                     else
1844                     {
1845                         Fill(StreamKind, StreamPos_To, Pos+3, ToAdd.Retrieve_Const(StreamKind, StreamPos_From, Pos+1));
1846                         Fill(StreamKind, StreamPos_To, Pos+2, ToFill_Value);
1847                     }
1848                 }
1849                 else
1850                 {
1851                     Fill(StreamKind, StreamPos_To, Pos+1, ToAdd.Retrieve_Const(StreamKind, StreamPos_From, Pos+1));
1852                     Fill(StreamKind, StreamPos_To, Pos, ToFill_Value);
1853                 }
1854             }
1855         }
1856         else if (StreamKind==Stream_Video && Pos && ShowSource_IsInList((video)(Pos-1)))
1857         {
1858             //Ignore
1859         }
1860         else if (!ToFill_Value.empty() && (Erase || Get(StreamKind, StreamPos_To, Pos).empty()))
1861         {
1862             if (Pos<MediaInfoLib::Config.Info_Get(StreamKind).size())
1863                 Fill(StreamKind, StreamPos_To, Pos, ToFill_Value, true);
1864             else
1865             {
1866                 Fill(StreamKind, StreamPos_To, ToAdd.Get(StreamKind, StreamPos_From, Pos, Info_Name).To_UTF8().c_str(), ToFill_Value, true);
1867                 Fill_SetOptions(StreamKind, StreamPos_To, ToAdd.Get(StreamKind, StreamPos_From, Pos, Info_Name).To_UTF8().c_str(), ToAdd.Get(StreamKind, StreamPos_From, Pos, Info_Options).To_UTF8().c_str());
1868             }
1869         }
1870     }
1871 
1872     //Specific stuff
1873     if (StreamKind==Stream_Video)
1874     {
1875         Ztring PixelAspectRatio_Original=Retrieve(Stream_Video, StreamPos_To, Video_PixelAspectRatio);
1876         Ztring DisplayAspectRatio_Original=Retrieve(Stream_Video, StreamPos_To, Video_DisplayAspectRatio);
1877 
1878         if (!Width_Temp.empty() && Width_Temp!=Retrieve(Stream_Video, StreamPos_To, Video_Width)
1879             && !(Retrieve(Stream_Video, StreamPos_To, Video_Format) == __T("DV") && Width_Temp == __T("1920") && (Retrieve(Stream_Video, StreamPos_Last, Video_Width) == __T("1280") || Retrieve(Stream_Video, StreamPos_Last, Video_Width) == __T("1440")))) // Exception: DVCPRO HD is really 1440 but lot of containers fill the width value with the marketing width 1920, we ignore it
1880         {
1881             Fill(Stream_Video, StreamPos_To, Video_Width_Original, (*Stream)[Stream_Video][StreamPos_To][Video_Width], true);
1882             Fill(Stream_Video, StreamPos_To, Video_Width, Width_Temp, true);
1883         }
1884         if (!Height_Temp.empty() && Height_Temp!=Retrieve(Stream_Video, StreamPos_To, Video_Height))
1885         {
1886             Fill(Stream_Video, StreamPos_To, Video_Height_Original, (*Stream)[Stream_Video][StreamPos_To][Video_Height], true);
1887             Fill(Stream_Video, StreamPos_To, Video_Height, Height_Temp, true);
1888         }
1889         if (!PixelAspectRatio_Temp.empty() && PixelAspectRatio_Temp!=Retrieve(Stream_Video, StreamPos_To, Video_PixelAspectRatio))
1890         {
1891             Fill(Stream_Video, StreamPos_To, Video_PixelAspectRatio_Original, PixelAspectRatio_Original, true);
1892             Fill(Stream_Video, StreamPos_To, Video_PixelAspectRatio, PixelAspectRatio_Temp, true);
1893         }
1894         if (!DisplayAspectRatio_Temp.empty() && DisplayAspectRatio_Temp!=DisplayAspectRatio_Original)
1895         {
1896             Fill(Stream_Video, StreamPos_To, Video_DisplayAspectRatio_Original, DisplayAspectRatio_Original, true);
1897             Fill(Stream_Video, StreamPos_To, Video_DisplayAspectRatio, DisplayAspectRatio_Temp, true);
1898         }
1899         if (!FrameRate_Temp.empty())
1900         {
1901             const Ztring& FramesPerContainerBlock=Retrieve(Stream_Video, StreamPos_To, "FramesPerContainerBlock");
1902             if (!FramesPerContainerBlock.empty())
1903                 FrameRate_Temp.From_Number(FrameRate_Temp.To_float64()*FramesPerContainerBlock.To_float64());
1904         }
1905         if ((!FrameRate_Temp.empty() && FrameRate_Temp!=Retrieve(Stream_Video, StreamPos_To, Video_FrameRate))
1906          || (!FrameRate_Num_Temp.empty() && FrameRate_Num_Temp!=Retrieve(Stream_Video, StreamPos_To, Video_FrameRate_Num))
1907          || (!FrameRate_Den_Temp.empty() && FrameRate_Den_Temp!=Retrieve(Stream_Video, StreamPos_To, Video_FrameRate_Den)))
1908         {
1909             Fill(Stream_Video, StreamPos_To, Video_FrameRate_Original, ToAdd.Retrieve(Stream_Video, StreamPos_To, Video_FrameRate), true);
1910             Fill(Stream_Video, StreamPos_To, Video_FrameRate_Original_Num, ToAdd.Retrieve(Stream_Video, StreamPos_To, Video_FrameRate_Num), true);
1911             Fill(Stream_Video, StreamPos_To, Video_FrameRate_Original_Den, ToAdd.Retrieve(Stream_Video, StreamPos_To, Video_FrameRate_Den), true);
1912             Fill(Stream_Video, StreamPos_To, Video_FrameRate, FrameRate_Temp, true);
1913             Fill(Stream_Video, StreamPos_To, Video_FrameRate_Num, FrameRate_Num_Temp, true);
1914             Fill(Stream_Video, StreamPos_To, Video_FrameRate_Den, FrameRate_Den_Temp, true);
1915         }
1916         if (!FrameRate_Mode_Temp.empty() && FrameRate_Mode_Temp!=Retrieve(Stream_Video, StreamPos_To, Video_FrameRate_Mode))
1917         {
1918             Fill(Stream_Video, StreamPos_To, Video_FrameRate_Mode_Original, (*Stream)[Stream_Video][StreamPos_To][Video_FrameRate_Mode], true);
1919             Fill(Stream_Video, StreamPos_To, Video_FrameRate_Mode, FrameRate_Mode_Temp, true);
1920         }
1921         if (!ScanType_Temp.empty() && (ScanType_Temp!=Retrieve(Stream_Video, StreamPos_To, Video_ScanType) && !(ScanType_Temp==__T("Interlaced") && Retrieve(Stream_Video, StreamPos_To, Video_ScanType)==__T("MBAFF"))))
1922         {
1923             Fill(Stream_Video, StreamPos_To, Video_ScanType_Original, (*Stream)[Stream_Video][StreamPos_To][Video_ScanType], true);
1924             Fill(Stream_Video, StreamPos_To, Video_ScanType, ScanType_Temp, true);
1925         }
1926         if (Retrieve(Stream_Video, StreamPos_To, Video_ScanType_Original)!=__T("Progressive") && ((!ScanOrder_Temp.empty() && ScanOrder_Temp!=Retrieve(Stream_Video, StreamPos_To, Video_ScanOrder)) || !Retrieve(Stream_Video, StreamPos_To, Video_ScanType_Original).empty()))
1927         {
1928             Fill(Stream_Video, StreamPos_To, Video_ScanOrder_Original, (*Stream)[Stream_Video][StreamPos_To][Video_ScanOrder], true);
1929             if (ScanOrder_Temp.empty())
1930             {
1931                 Clear(Stream_Video, StreamPos_To, Video_ScanOrder);
1932                 Clear(Stream_Video, StreamPos_To, Video_ScanOrder_String);
1933             }
1934             else
1935                 Fill(Stream_Video, StreamPos_To, Video_ScanOrder, ScanOrder_Temp, true);
1936         }
1937         if (!HDR_Temp[0].empty() && !ToAdd.Retrieve_Const(Stream_Video, StreamPos_From, Video_HDR_Format).empty() && HDR_Temp[0]!=ToAdd.Retrieve_Const(Stream_Video, StreamPos_From, Video_HDR_Format))
1938         {
1939             for (size_t i=Video_HDR_Format; i<=Video_HDR_Format_Compatibility; i++)
1940             {
1941                 Ztring Container_Value=HDR_Temp[i-Video_HDR_Format];
1942                 Ztring Stream_Value=ToAdd.Retrieve(Stream_Video, StreamPos_From, i);
1943                 if (!Container_Value.empty() || !Stream_Value.empty())
1944                     Container_Value+=__T(" / ");
1945                 Container_Value+=Stream_Value;
1946                 Fill(Stream_Video, StreamPos_To, i, Container_Value, true);
1947             }
1948         }
1949     }
1950     if (StreamKind==Stream_Audio)
1951     {
1952         bool IsOkGlobal=true;
1953         static audio AudioField[4]={ Audio_Channel_s_, Audio_ChannelLayout, Audio_ChannelPositions, Audio_ChannelPositions_String2 };
1954         for (size_t i=0; i<4; i++)
1955             if (!Channels_Temp[i].empty())
1956             {
1957                 //Test with legacy streams information
1958                 bool IsOk=(Channels_Temp[i]==Retrieve(Stream_Audio, StreamPos_To, AudioField[i]));
1959                 if (!IsOk)
1960                 {
1961                     ZtringList Temp; Temp.Separator_Set(0, __T(" / "));
1962                     Temp.Write(Retrieve(Stream_Audio, StreamPos_To, AudioField[i]));
1963                     for (size_t Pos=0; Pos<Temp.size(); Pos++)
1964                         if (Channels_Temp[i]==Temp[Pos])
1965                             IsOk=true;
1966                 }
1967 
1968                 //Special case with AES3: wrong container information is accepted
1969                 if (!IsOk && Retrieve(Stream_Audio, StreamPos_To, Audio_MuxingMode).find(__T("SMPTE ST 337"))!=string::npos)
1970                     IsOk=true;
1971 
1972                 if (!IsOk)
1973                     IsOkGlobal=false;
1974             }
1975 
1976             if (!IsOkGlobal)
1977                 for (size_t i=0; i<4; i++)
1978                     if (Channels_Temp[i]!=(*Stream)[Stream_Audio][StreamPos_To][AudioField[i]])
1979                     {
1980                         string Original=Retrieve_Const(Stream_Audio, StreamPos_To, AudioField[i], Info_Name).To_UTF8();
1981                         size_t Original_Insert=Original.find('/');
1982                         if (Original_Insert==(size_t)-1)
1983                             Original_Insert=Original.size();
1984                         Original.insert(Original_Insert, "_Original");
1985                         Fill(Stream_Audio, StreamPos_To, Original.c_str(), (*Stream)[Stream_Audio][StreamPos_To][AudioField[i]], true);
1986                         Fill_SetOptions(Stream_Audio, StreamPos_To, Original.c_str(), Retrieve_Const(Stream_Audio, StreamPos_To, AudioField[i], Info_Options).To_UTF8().c_str());
1987                         Fill(Stream_Audio, StreamPos_To, AudioField[i], Channels_Temp[i], true);
1988                     }
1989     }
1990     if (!Delay_Source_Temp.empty() && Delay_Source_Temp!=Retrieve(StreamKind, StreamPos_To, "Delay_Source"))
1991     {
1992         Fill(StreamKind, StreamPos_To, "Delay_Original", Retrieve(StreamKind, StreamPos_To, "Delay"), true);
1993         Fill(StreamKind, StreamPos_To, "Delay", Delay_Temp, true);
1994         Fill(StreamKind, StreamPos_To, "Delay_Original_Settings", Retrieve(StreamKind, StreamPos_To, "Delay_Settings"), true);
1995         Fill(StreamKind, StreamPos_To, "Delay_Settings", Delay_Settings_Temp, true);
1996         Fill(StreamKind, StreamPos_To, "Delay_Original_DropFrame", Retrieve(StreamKind, StreamPos_To, "Delay_DropFrame"), true);
1997         Fill(StreamKind, StreamPos_To, "Delay_DropFrame", Delay_DropFrame_Temp, true);
1998         Fill(StreamKind, StreamPos_To, "Delay_Original_Source", Retrieve(StreamKind, StreamPos_To, "Delay_Source"), true);
1999         Fill(StreamKind, StreamPos_To, "Delay_Source", Delay_Source_Temp, true);
2000     }
2001     if (!Source_Temp.empty() && Source_Temp!=Retrieve(StreamKind, StreamPos_To, "Source"))
2002     {
2003         Fill(StreamKind, StreamPos_To, "Source_Original", Retrieve(StreamKind, StreamPos_To, "Source"), true);
2004         Fill(StreamKind, StreamPos_To, "Source", Source_Temp, true);
2005         Fill(StreamKind, StreamPos_To, "Source_Original_Kind", Retrieve(StreamKind, StreamPos_To, "Source_Kind"), true);
2006         Fill(StreamKind, StreamPos_To, "Source_Kind", Source_Info_Temp, true);
2007         Fill(StreamKind, StreamPos_To, "Source_Original_Info", Retrieve(StreamKind, StreamPos_To, "Source_Info"), true);
2008         Fill(StreamKind, StreamPos_To, "Source_Info", Source_Info_Temp, true);
2009     }
2010     if (!BitRate_Temp.empty() && BitRate_Temp.find(__T(" / ")) == string::npos && Retrieve(StreamKind, StreamPos_To, "BitRate").find(__T("Unknown")) != string::npos)
2011     {
2012         Ztring Temp=Retrieve(StreamKind, StreamPos_To, "BitRate");
2013         Temp.FindAndReplace(__T("Unknown"), BitRate_Temp, 0, Ztring_Recursive);
2014         Fill(StreamKind, StreamPos_To, "BitRate", Temp, true);
2015     }
2016     const Ztring& CodecID_New =ToAdd.Retrieve_Const(StreamKind, StreamPos_From, "CodecID");
2017     if (!CodecID_Temp.empty() && !CodecID_New.empty() && CodecID_Temp!=CodecID_New && (Config->File_IsReferenced_Get() ^ !ToAdd.Config->File_IsReferenced_Get())) //TODO: better handling of merges, avoiding duplicate merges so we can remeove hack CodecID_Temp!=CodecID_New
2018     {
2019         Fill(StreamKind, StreamPos_To, "CodecID", CodecID_Temp+__T('-')+ToAdd.Retrieve(StreamKind, StreamPos_From, "CodecID"), true);
2020     }
2021     const Ztring& Title_New=ToAdd.Retrieve_Const(StreamKind, StreamPos_From, "Title");
2022     if (StreamKind!=Stream_General && !Title_Temp.empty() && !Title_New.empty() && Title_Temp!=Title_New)
2023     {
2024         Title_Temp+=__T(" - ");
2025         if (Title_New.compare(0, Title_Temp.size(), Title_Temp)) //For a master file with title referencing a essence file with title and stream title, we check that master file title is not the essence file title (not same due to stream title)
2026             Fill(StreamKind, StreamPos_To, "Title", Title_Temp+Title_New, true);
2027     }
2028 
2029     Fill(StreamKind, StreamPos_To, (size_t)General_Count, Count_Get(StreamKind, StreamPos_To), 10, true);
2030     return 1;
2031 }
2032 
2033 //***************************************************************************
2034 // Helpers
2035 //***************************************************************************
2036 
2037 //---------------------------------------------------------------------------
Video_FrameRate_Rounding(size_t Pos,video Parameter)2038 void File__Analyze::Video_FrameRate_Rounding(size_t Pos, video Parameter)
2039 {
2040     float64 FrameRate=Retrieve(Stream_Video, Pos, Parameter).To_float64();
2041     float64 FrameRate_Sav=FrameRate;
2042 
2043          if (FrameRate> 9.990 && FrameRate<=10.010) FrameRate=10.000;
2044     else if (FrameRate>11.984 && FrameRate<=11.994) FrameRate=11.988;
2045     else if (FrameRate>11.994 && FrameRate<=12.010) FrameRate=12.000;
2046     else if (FrameRate>14.980 && FrameRate<=14.990) FrameRate=14.985;
2047     else if (FrameRate>14.990 && FrameRate<=15.010) FrameRate=15.000;
2048     else if (FrameRate>23.952 && FrameRate<=23.988) FrameRate=23.976;
2049     else if (FrameRate>23.988 && FrameRate<=24.024) FrameRate=24.000;
2050     else if (FrameRate>24.975 && FrameRate<=25.025) FrameRate=25.000;
2051     else if (FrameRate>29.940 && FrameRate<=29.985) FrameRate=29.970;
2052     else if (FrameRate>29.970 && FrameRate<=30.030) FrameRate=30.000;
2053     else if (FrameRate>23.952*2 && FrameRate<=23.988*2) FrameRate=23.976*2;
2054     else if (FrameRate>23.988*2 && FrameRate<=24.024*2) FrameRate=24.000*2;
2055     else if (FrameRate>24.975*2 && FrameRate<=25.025*2) FrameRate=25.000*2;
2056     else if (FrameRate>29.940*2 && FrameRate<=29.985*2) FrameRate=29.970*2;
2057     else if (FrameRate>29.970*2 && FrameRate<=30.030*2) FrameRate=30.000*2;
2058 
2059     if (std::fabs(FrameRate-FrameRate_Sav)>=0.000999999)
2060         Fill(Stream_Video, Pos, Parameter, FrameRate, 3, true);
2061 }
2062 
2063 //---------------------------------------------------------------------------
Video_BitRate_Rounding(size_t Pos,video Parameter)2064 void File__Analyze::Video_BitRate_Rounding(size_t Pos, video Parameter)
2065 {
2066     const Ztring& Format=Retrieve(Stream_Video, Pos, Video_Format);
2067     int32u BitRate=Retrieve(Stream_Video, Pos, Parameter).To_int32u();
2068     int32u BitRate_Sav=BitRate;
2069     if (Format==__T("AVC"))
2070     {
2071         if (BitRate>= 54942720 && BitRate<= 57185280) BitRate= 56064000; //AVC-INTRA50
2072         if (BitRate>=111390720 && BitRate<=115937280) BitRate=113664000; //AVC-INTRA100
2073     }
2074 
2075     if (BitRate!=BitRate_Sav)
2076         Fill(Stream_Video, Pos, Parameter, BitRate, 0, true);
2077 }
2078 
2079 //---------------------------------------------------------------------------
Audio_BitRate_Rounding(size_t Pos,audio Parameter)2080 void File__Analyze::Audio_BitRate_Rounding(size_t Pos, audio Parameter)
2081 {
2082     const Ztring& Format=Retrieve(Stream_Audio, Pos, Audio_Format);
2083     int32u BitRate=Retrieve(Stream_Audio, Pos, Parameter).To_int32u();
2084     int32u BitRate_Sav=BitRate;
2085     if (Format.find(__T("MPEG"))==0)
2086     {
2087         if (BitRate>=   7500 && BitRate<=   8500) BitRate=   8000;
2088         if (BitRate>=  15000 && BitRate<=  17000) BitRate=  16000;
2089         if (BitRate>=  23000 && BitRate<=  25000) BitRate=  24000;
2090         if (BitRate>=  31000 && BitRate<=  33000) BitRate=  32000;
2091         if (BitRate>=  38000 && BitRate<=  42000) BitRate=  40000;
2092         if (BitRate>=  46000 && BitRate<=  50000) BitRate=  48000;
2093         if (BitRate>=  54000 && BitRate<=  58000) BitRate=  56000;
2094         if (BitRate>=  62720 && BitRate<=  65280) BitRate=  64000;
2095         if (BitRate>=  78400 && BitRate<=  81600) BitRate=  80000;
2096         if (BitRate>=  94080 && BitRate<=  97920) BitRate=  96000;
2097         if (BitRate>= 109760 && BitRate<= 114240) BitRate= 112000;
2098         if (BitRate>= 125440 && BitRate<= 130560) BitRate= 128000;
2099         if (BitRate>= 156800 && BitRate<= 163200) BitRate= 160000;
2100         if (BitRate>= 156800 && BitRate<= 163200) BitRate= 160000;
2101         if (BitRate>= 188160 && BitRate<= 195840) BitRate= 192000;
2102         if (BitRate>= 219520 && BitRate<= 228480) BitRate= 224000;
2103         if (BitRate>= 219520 && BitRate<= 228480) BitRate= 224000;
2104         if (BitRate>= 250880 && BitRate<= 261120) BitRate= 256000;
2105         if (BitRate>= 282240 && BitRate<= 293760) BitRate= 288000;
2106         if (BitRate>= 313600 && BitRate<= 326400) BitRate= 320000;
2107         if (BitRate>= 344960 && BitRate<= 359040) BitRate= 352000;
2108         if (BitRate>= 376320 && BitRate<= 391680) BitRate= 384000;
2109         if (BitRate>= 407680 && BitRate<= 424320) BitRate= 416000;
2110         if (BitRate>= 439040 && BitRate<= 456960) BitRate= 448000;
2111         if (Retrieve(Stream_Audio, Pos, "BitRate_Mode")==__T("VBR"))
2112             BitRate=BitRate_Sav; //If VBR, we want the exact value
2113     }
2114 
2115     else if (Format.find(__T("AC3"))==0)
2116     {
2117         if (BitRate>=  31000 && BitRate<=  33000) BitRate=  32000;
2118         if (BitRate>=  39000 && BitRate<=  41000) BitRate=  40000;
2119         if (BitRate>=  46000 && BitRate<=  50000) BitRate=  48000;
2120         if (BitRate>=  54000 && BitRate<=  58000) BitRate=  56000;
2121         if (BitRate>=  62720 && BitRate<=  65280) BitRate=  64000;
2122         if (BitRate>=  78400 && BitRate<=  81600) BitRate=  80000;
2123         if (BitRate>=  94080 && BitRate<=  97920) BitRate=  96000;
2124         if (BitRate>= 109760 && BitRate<= 114240) BitRate= 112000;
2125         if (BitRate>= 125440 && BitRate<= 130560) BitRate= 128000;
2126         if (BitRate>= 156800 && BitRate<= 163200) BitRate= 160000;
2127         if (BitRate>= 188160 && BitRate<= 195840) BitRate= 192000;
2128         if (BitRate>= 219520 && BitRate<= 228480) BitRate= 224000;
2129         if (BitRate>= 250880 && BitRate<= 261120) BitRate= 256000;
2130         if (BitRate>= 313600 && BitRate<= 326400) BitRate= 320000;
2131         if (BitRate>= 376320 && BitRate<= 391680) BitRate= 384000;
2132         if (BitRate>= 439040 && BitRate<= 456960) BitRate= 448000;
2133         if (BitRate>= 501760 && BitRate<= 522240) BitRate= 512000;
2134         if (BitRate>= 564480 && BitRate<= 587520) BitRate= 576000;
2135         if (BitRate>= 627200 && BitRate<= 652800) BitRate= 640000;
2136     }
2137 
2138     else if (Format.find(__T("AAC"))==0)
2139     {
2140         if (BitRate>=  46000 && BitRate<=  50000) BitRate=  48000;
2141         if (BitRate>=  64827 && BitRate<=  67473) BitRate=  66150;
2142         if (BitRate>=  70560 && BitRate<=  73440) BitRate=  72000;
2143         if (BitRate>=  94080 && BitRate<=  97920) BitRate=  96000;
2144         if (BitRate>=  94080 && BitRate<=  97920) BitRate=  96000;
2145         if (BitRate>= 129654 && BitRate<= 134946) BitRate= 132300;
2146         if (BitRate>= 141120 && BitRate<= 146880) BitRate= 144000;
2147         if (BitRate>= 188160 && BitRate<= 195840) BitRate= 192000;
2148         if (BitRate>= 259308 && BitRate<= 269892) BitRate= 264600;
2149         if (BitRate>= 282240 && BitRate<= 293760) BitRate= 288000;
2150         if (BitRate>= 345744 && BitRate<= 359856) BitRate= 352800;
2151         if (BitRate>= 376320 && BitRate<= 391680) BitRate= 384000;
2152         if (BitRate>= 518616 && BitRate<= 539784) BitRate= 529200;
2153         if (BitRate>= 564480 && BitRate<= 587520) BitRate= 576000;
2154         if (BitRate>= 648270 && BitRate<= 674730) BitRate= 661500;
2155     }
2156 
2157     else if (Format==__T("PCM") || Format==__T("Qdesign 2"))
2158     {
2159         if (BitRate>=  62720 && BitRate<=  65280) BitRate=  64000;
2160         if (BitRate>=  86436 && BitRate<=  89964) BitRate=  88200;
2161         if (BitRate>= 125440 && BitRate<= 130560) BitRate= 128000;
2162         if (BitRate>= 172872 && BitRate<= 179928) BitRate= 176400;
2163         if (BitRate>= 188160 && BitRate<= 195840) BitRate= 192000;
2164         if (BitRate>= 250880 && BitRate<= 261120) BitRate= 256000;
2165         if (BitRate>= 345744 && BitRate<= 359856) BitRate= 352800;
2166         if (BitRate>= 376320 && BitRate<= 391680) BitRate= 384000;
2167         if (BitRate>= 501760 && BitRate<= 522240) BitRate= 512000;
2168         if (BitRate>= 691488 && BitRate<= 719712) BitRate= 705600;
2169         if (BitRate>= 752640 && BitRate<= 783360) BitRate= 768000;
2170         if (BitRate>=1003520 && BitRate<=1044480) BitRate=1024000;
2171         if (BitRate>=1128960 && BitRate<=1175040) BitRate=1152000;
2172         if (BitRate>=1382976 && BitRate<=1439424) BitRate=1411200;
2173         if (BitRate>=1505280 && BitRate<=1566720) BitRate=1536000;
2174         if (BitRate>=4515840 && BitRate<=4700160) BitRate=4608000;
2175         if (BitRate>=6021120 && BitRate<=6266880) BitRate=6144000;
2176     }
2177 
2178     else if (Format.find(__T("ADPCM"))==0
2179           || Format.find(__T("U-Law"))==0)
2180     {
2181         if (BitRate>=  42000 && BitRate<=  46000) BitRate=  44100;
2182         if (BitRate>=  62720 && BitRate<=  65280) BitRate=  64000;
2183         if (BitRate>=  86436 && BitRate<=  89964) BitRate=  88200;
2184         if (BitRate>= 125440 && BitRate<= 130560) BitRate= 128000;
2185         if (BitRate>= 172872 && BitRate<= 179928) BitRate= 176400;
2186         if (BitRate>= 188160 && BitRate<= 195840) BitRate= 192000;
2187         if (BitRate>= 250880 && BitRate<= 261120) BitRate= 256000;
2188         if (BitRate>= 345744 && BitRate<= 359856) BitRate= 352800;
2189         if (BitRate>= 376320 && BitRate<= 391680) BitRate= 384000;
2190     }
2191 
2192     if (BitRate!=BitRate_Sav)
2193         Fill(Stream_Audio, Pos, Parameter, BitRate, 0, true);
2194 }
2195 
2196 //---------------------------------------------------------------------------
Tags()2197 void File__Analyze::Tags()
2198 {
2199     //Integrity
2200     if (!Count_Get(Stream_General))
2201         return;
2202 
2203     //-Movie/Album
2204     if (!Retrieve(Stream_General, 0, General_Title).empty() && Retrieve(Stream_General, 0, General_Movie).empty() && Retrieve(Stream_General, 0, General_Track).empty())
2205     {
2206         if (Count_Get(Stream_Video) && Retrieve(Stream_General, 0, General_Collection).empty())
2207             Fill(Stream_General, 0, "Movie", Retrieve(Stream_General, 0, General_Title));
2208         else
2209             Fill(Stream_General, 0, "Track", Retrieve(Stream_General, 0, General_Title));
2210     }
2211     if (!Retrieve(Stream_General, 0, General_Title_More).empty() && Retrieve(Stream_General, 0, General_Movie_More).empty() && Retrieve(Stream_General, 0, General_Track_More).empty())
2212     {
2213         if (Count_Get(Stream_Video) && Retrieve(Stream_General, 0, General_Collection).empty())
2214             Fill(Stream_General, 0, "Movie_More", Retrieve(Stream_General, 0, General_Title_More));
2215         else
2216             Fill(Stream_General, 0, "Track_More", Retrieve(Stream_General, 0, General_Title_More));
2217     }
2218     if (!Retrieve(Stream_General, 0, General_Title_Url).empty() && Retrieve(Stream_General, 0, General_Movie_Url).empty() && Retrieve(Stream_General, 0, General_Track_Url).empty())
2219     {
2220         if (Count_Get(Stream_Video) && Retrieve(Stream_General, 0, General_Collection).empty())
2221             Fill(Stream_General, 0, "Movie/Url", Retrieve(Stream_General, 0, General_Title_Url));
2222         else
2223             Fill(Stream_General, 0, "Track/Url", Retrieve(Stream_General, 0, General_Title_Url));
2224     }
2225     //-Title
2226     if (Retrieve(Stream_General, 0, General_Title).empty() && !Retrieve(Stream_General, 0, General_Movie).empty())
2227         Fill(Stream_General, 0, "Title", Retrieve(Stream_General, 0, General_Movie));
2228     if (Retrieve(Stream_General, 0, General_Title).empty() && !Retrieve(Stream_General, 0, General_Track).empty())
2229         Fill(Stream_General, 0, "Title", Retrieve(Stream_General, 0, General_Track));
2230     if (Retrieve(Stream_General, 0, General_Title_More).empty() && !Retrieve(Stream_General, 0, General_Movie_More).empty())
2231         Fill(Stream_General, 0, "Title_More", Retrieve(Stream_General, 0, General_Movie_More));
2232     if (Retrieve(Stream_General, 0, General_Title_More).empty() && !Retrieve(Stream_General, 0, General_Track_More).empty())
2233         Fill(Stream_General, 0, "Title_More", Retrieve(Stream_General, 0, General_Track_More));
2234     if (Retrieve(Stream_General, 0, General_Title_Url).empty() && !Retrieve(Stream_General, 0, General_Movie_Url).empty())
2235         Fill(Stream_General, 0, "Title/Url", Retrieve(Stream_General, 0, General_Movie_Url));
2236     if (Retrieve(Stream_General, 0, General_Title_Url).empty() && !Retrieve(Stream_General, 0, General_Track_Url).empty())
2237         Fill(Stream_General, 0, "Title/Url", Retrieve(Stream_General, 0, General_Track_Url));
2238 
2239     //-Genre
2240     if (!Retrieve(Stream_General, 0, General_Genre).empty() && Retrieve(Stream_General, 0, General_Genre).size()<4 && Retrieve(Stream_General, 0, General_Genre)[0]>=__T('0') && Retrieve(Stream_General, 0, General_Genre)[0]<=__T('9'))
2241     {
2242         Ztring Genre;
2243         if (Retrieve(Stream_General, 0, General_Genre).size()==1) Genre=Ztring(__T("Genre_00"))+Retrieve(Stream_General, 0, General_Genre);
2244         if (Retrieve(Stream_General, 0, General_Genre).size()==2) Genre=Ztring(__T("Genre_0" ))+Retrieve(Stream_General, 0, General_Genre);
2245         if (Retrieve(Stream_General, 0, General_Genre).size()==3) Genre=Ztring(__T("Genre_"  ))+Retrieve(Stream_General, 0, General_Genre);
2246         Fill(Stream_General, 0, "Genre", MediaInfoLib::Config.Language_Get(Genre), true);
2247     }
2248 }
2249 
2250 //***************************************************************************
2251 // Internal Functions
2252 //***************************************************************************
2253 
2254 //---------------------------------------------------------------------------
2255 //Duration
Duration_Duration123(stream_t StreamKind,size_t StreamPos,size_t Parameter)2256 void File__Analyze::Duration_Duration123(stream_t StreamKind, size_t StreamPos, size_t Parameter)
2257 {
2258     if (Retrieve(StreamKind, StreamPos, Parameter).empty()
2259      || (StreamKind==Stream_Audio && (Parameter==Audio_Interleave_Duration || Parameter==Audio_Interleave_Preload))) //Exception: string is built also from frame rate, already computed. TODO: check behavior with MIXML input
2260         return;
2261 
2262     //Clearing old data
2263     Clear(StreamKind, StreamPos, Parameter+1);
2264     Clear(StreamKind, StreamPos, Parameter+2);
2265     Clear(StreamKind, StreamPos, Parameter+3);
2266     Clear(StreamKind, StreamPos, Parameter+4);
2267     Clear(StreamKind, StreamPos, Parameter+5);
2268     Clear(StreamKind, StreamPos, Parameter+6);
2269 
2270     //Retrieving multiple values
2271     ZtringList List;
2272     List.Separator_Set(0, __T(" / "));
2273     List.Write(Retrieve(StreamKind, StreamPos, Parameter));
2274 
2275     //Per value
2276     for (size_t Pos=0; Pos<List.size(); Pos++)
2277     {
2278         int32s HH, MM, Sec, MS;
2279         Ztring DurationString1, DurationString2, DurationString3;
2280         bool Negative=false;
2281         MS=List[Pos].To_int32s(); //in ms
2282 
2283         if (MS<0)
2284         {
2285             Negative=true;
2286             MS=-MS;
2287         }
2288 
2289         //Hours
2290         HH=MS/1000/60/60; //h
2291         if (HH>0)
2292         {
2293             DurationString1+=Ztring::ToZtring(HH)+MediaInfoLib::Config.Language_Get(__T("h"));
2294             DurationString2+=Ztring::ToZtring(HH)+MediaInfoLib::Config.Language_Get(__T("h"));
2295             if (HH<10)
2296                 DurationString3+=Ztring(__T("0"))+Ztring::ToZtring(HH)+__T(":");
2297             else
2298                 DurationString3+=Ztring::ToZtring(HH)+__T(":");
2299             MS-=HH*60*60*1000;
2300         }
2301         else
2302         {
2303             DurationString3+=__T("00:");
2304         }
2305 
2306         //Minutes
2307         MM=MS/1000/60; //mn
2308         if (MM>0 || HH>0)
2309         {
2310             if (DurationString1.size()>0)
2311                 DurationString1+=__T(" ");
2312             DurationString1+=Ztring::ToZtring(MM)+MediaInfoLib::Config.Language_Get(__T("mn"));
2313             if (DurationString2.size()<5)
2314             {
2315                 if (DurationString2.size()>0)
2316                     DurationString2+=__T(" ");
2317                 DurationString2+=Ztring::ToZtring(MM)+MediaInfoLib::Config.Language_Get(__T("mn"));
2318             }
2319             if (MM<10)
2320                 DurationString3+=Ztring(__T("0"))+Ztring::ToZtring(MM)+__T(":");
2321             else
2322                 DurationString3+=Ztring::ToZtring(MM)+__T(":");
2323             MS-=MM*60*1000;
2324         }
2325         else
2326         {
2327             DurationString3+=__T("00:");
2328         }
2329 
2330         //Seconds
2331         Sec=MS/1000; //s
2332         if (Sec>0 || MM>0 || HH>0)
2333         {
2334             if (DurationString1.size()>0)
2335                 DurationString1+=__T(" ");
2336             DurationString1+=Ztring::ToZtring(Sec)+MediaInfoLib::Config.Language_Get(__T("s"));
2337             if (HH==0)
2338             {
2339                 if (DurationString2.size()>0)
2340                     DurationString2+=__T(" ");
2341                 DurationString2+=Ztring::ToZtring(Sec)+MediaInfoLib::Config.Language_Get(__T("s"));
2342             }
2343             if (Sec<10)
2344                 DurationString3+=Ztring(__T("0"))+Ztring::ToZtring(Sec)+__T(".");
2345             else
2346                 DurationString3+=Ztring::ToZtring(Sec)+__T(".");
2347             MS-=Sec*1000;
2348         }
2349         else
2350         {
2351             DurationString3+=__T("00.");
2352         }
2353 
2354         //Milliseconds
2355         if (MS>0 || Sec>0 || MM>0 || HH>0)
2356         {
2357             if (DurationString1.size()>0)
2358                 DurationString1+=__T(" ");
2359             DurationString1+=Ztring::ToZtring(MS)+MediaInfoLib::Config.Language_Get(__T("ms"));
2360             if (HH==0 && MM==0)
2361             {
2362                 if (DurationString2.size()>0)
2363                     DurationString2+=__T(" ");
2364                 DurationString2+=Ztring::ToZtring(MS)+MediaInfoLib::Config.Language_Get(__T("ms"));
2365             }
2366             if (MS<10)
2367                 DurationString3+=Ztring(__T("00"))+Ztring::ToZtring(MS);
2368             else if (MS<100)
2369                 DurationString3+=Ztring(__T("0"))+Ztring::ToZtring(MS);
2370             else
2371                 DurationString3+=Ztring::ToZtring(MS);
2372         }
2373         else
2374         {
2375             DurationString3+=__T("000");
2376         }
2377 
2378         if (Negative)
2379         {
2380             DurationString1=Ztring(__T("-"))+DurationString1;
2381             DurationString2=Ztring(__T("-"))+DurationString2;
2382             DurationString3=Ztring(__T("-"))+DurationString3;
2383         }
2384 
2385         Fill(StreamKind, StreamPos, Parameter+1, DurationString2); // /String
2386         Fill(StreamKind, StreamPos, Parameter+2, DurationString1); // /String1
2387         Fill(StreamKind, StreamPos, Parameter+3, DurationString2); // /String2
2388         Fill(StreamKind, StreamPos, Parameter+4, DurationString3); // /String3
2389 
2390         if (Parameter==Fill_Parameter(StreamKind, Generic_Duration))
2391         {
2392             Ztring DurationString4;
2393             Ztring FrameRateS=Retrieve(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_FrameRate));
2394             Ztring FrameCountS=Retrieve(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_FrameCount));
2395             if (!FrameRateS.empty() && !FrameCountS.empty() && FrameRateS.To_int64u() && FrameRateS.To_int64u()<256)
2396             {
2397                 bool DropFrame=false;
2398                 bool DropFrame_IsValid=false;
2399 
2400                 // Testing time code
2401                 if (StreamKind==Stream_Video)
2402                 {
2403                     Ztring TC=Retrieve(Stream_Video, StreamPos, Video_TimeCode_FirstFrame);
2404                     if (TC.size()>=11 && TC[2]==__T(':') && TC[5]==__T(':'))
2405                     {
2406                         switch (TC[8])
2407                         {
2408                             case __T(':'):
2409                                             DropFrame=false;
2410                                             DropFrame_IsValid=true;
2411                                             break;
2412                             case __T(';'):
2413                                             DropFrame=true;
2414                                             DropFrame_IsValid=true;
2415                                             break;
2416                             default      :  ;
2417                         }
2418                     }
2419                 }
2420 
2421                 // Testing delay
2422                 if (!DropFrame_IsValid)
2423                 {
2424                     Ztring TC=Retrieve(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_Delay_Original_DropFrame));
2425                     if (TC.size()>=11 && TC[2]==__T(':') && TC[5]==__T(':'))
2426                     {
2427                         switch (TC[8])
2428                         {
2429                             case __T(':'):
2430                                             DropFrame=false;
2431                                             DropFrame_IsValid=true;
2432                                             break;
2433                             case __T(';'):
2434                                             DropFrame=true;
2435                                             DropFrame_IsValid=true;
2436                                             break;
2437                             default      :  ;
2438                         }
2439                     }
2440                 }
2441 
2442                 // Testing time code track
2443                 if (!DropFrame_IsValid)
2444                 {
2445                     for (size_t Step=Retrieve(Stream_General, 0, General_Format)==__T("MXF")?0:1; Step<2; ++Step)
2446                     {
2447                         for (size_t TC_Pos=0; TC_Pos<Count_Get(Stream_Other); ++TC_Pos)
2448                             if (Retrieve(Stream_Other, TC_Pos, Other_Type)==__T("Time code")
2449                              && (Step || Retrieve(Stream_Other, TC_Pos, Other_TimeCode_Settings)==__T("Source Package")))
2450                             {
2451                                 Ztring TC=Retrieve(Stream_Other, TC_Pos, Other_TimeCode_FirstFrame);
2452                                 if (TC.size()>=11 && TC[2]==__T(':') && TC[5]==__T(':'))
2453                                 {
2454                                     switch (TC[8])
2455                                     {
2456                                         case __T(':'):
2457                                                         DropFrame=false;
2458                                                         DropFrame_IsValid=true;
2459                                                         break;
2460                                         case __T(';'):
2461                                                         DropFrame=true;
2462                                                         DropFrame_IsValid=true;
2463                                                         break;
2464                                         default      :  ;
2465                                     }
2466                                 }
2467 
2468                                 if (DropFrame_IsValid)
2469                                     break; //Using first time code track
2470                             }
2471 
2472                         if (DropFrame_IsValid)
2473                             break; //Using first time code track
2474                     }
2475                 }
2476 
2477                 // Testing frame rate (1/1001)
2478                 if (!DropFrame_IsValid)
2479                 {
2480                     float32 FrameRateF=FrameRateS.To_float32();
2481                     int32s  FrameRateI=float32_int32s(FrameRateS.To_float32());
2482                     float FrameRateF_Min=((float32)FrameRateI)/((float32)1.002);
2483                     float FrameRateF_Max=(float32)FrameRateI;
2484                     if (FrameRateF>=FrameRateF_Min && FrameRateF<FrameRateF_Max)
2485                         DropFrame=true;
2486                     else
2487                         DropFrame=false;
2488                 }
2489 
2490                 TimeCode TC(FrameCountS.To_int64s(), (int8u)float32_int32s(FrameRateS.To_float32()), DropFrame);
2491                 DurationString4.From_UTF8(TC.ToString());
2492 
2493                 Fill(StreamKind, StreamPos, Parameter+5, DurationString4); // /String4
2494             }
2495             Ztring DurationString5(DurationString3);
2496             if (!DurationString4.empty())
2497             {
2498                 DurationString5+=__T(' ');
2499                 DurationString5+=__T('(');
2500                 DurationString5+=DurationString4;
2501                 DurationString5+=__T(')');
2502             }
2503             Fill(StreamKind, StreamPos, Parameter+6, DurationString5); // /String5
2504         }
2505     }
2506 }
2507 
2508 //---------------------------------------------------------------------------
2509 //FileSize
FileSize_FileSize123(stream_t StreamKind,size_t StreamPos,size_t Parameter)2510 void File__Analyze::FileSize_FileSize123(stream_t StreamKind, size_t StreamPos, size_t Parameter)
2511 {
2512     if (Retrieve(StreamKind, StreamPos, Parameter).empty())
2513         return;
2514 
2515     float F1=(float)Retrieve(StreamKind, StreamPos, Parameter).To_int64s(); //Video C++ 6 patch, should be int64u
2516 
2517     //--Bytes, KiB, MiB or GiB...
2518     int32u Pow3=0;
2519     while(F1>=1024)
2520     {
2521         F1/=1024;
2522         Pow3++;
2523     }
2524     //--Count of digits
2525     int8u I2, I3, I4;
2526          if (F1>=100)
2527     {
2528         I2=0;
2529         I3=0;
2530         I4=1;
2531     }
2532     else if (F1>=10)
2533     {
2534         I2=0;
2535         I3=1;
2536         I4=2;
2537     }
2538     else //if (F1>=1)
2539     {
2540         I2=1;
2541         I3=2;
2542         I4=3;
2543     }
2544     Ztring Measure; bool MeasureIsAlwaysSame;
2545     switch (Pow3)
2546     {
2547         case  0 : Measure=__T(" Byte"); MeasureIsAlwaysSame=false; break;
2548         case  1 : Measure=__T(" KiB");  MeasureIsAlwaysSame=true;  break;
2549         case  2 : Measure=__T(" MiB");  MeasureIsAlwaysSame=true;  break;
2550         case  3 : Measure=__T(" GiB");  MeasureIsAlwaysSame=true;  break;
2551         case  4 : Measure=__T(" TiB");  MeasureIsAlwaysSame=true;  break;
2552         default : Measure=__T(" ?iB");  MeasureIsAlwaysSame=true;
2553     }
2554     Fill(StreamKind, StreamPos, Parameter+2, MediaInfoLib::Config.Language_Get(Ztring::ToZtring(F1,  0), Measure, MeasureIsAlwaysSame), true); // /String1
2555     Fill(StreamKind, StreamPos, Parameter+3, MediaInfoLib::Config.Language_Get(Ztring::ToZtring(F1, I2), Measure, MeasureIsAlwaysSame), true); // /String2
2556     Fill(StreamKind, StreamPos, Parameter+4, MediaInfoLib::Config.Language_Get(Ztring::ToZtring(F1, I3), Measure, MeasureIsAlwaysSame), true); // /String3
2557     Fill(StreamKind, StreamPos, Parameter+5, MediaInfoLib::Config.Language_Get(Ztring::ToZtring(F1, I4), Measure, MeasureIsAlwaysSame), true); // /String4
2558     float64 F2=(float)Retrieve(StreamKind, StreamPos, Parameter).To_float64();
2559     float64 File_Size_WithReferencedFiles=(float)Retrieve(Stream_General, 0, General_FileSize).To_float64();
2560     if (File_Size_WithReferencedFiles>0 && Parameter==Fill_Parameter(StreamKind, Generic_StreamSize) && F2*100/File_Size_WithReferencedFiles<=100)
2561     {
2562         Fill(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_StreamSize_Proportion), F2/File_Size_WithReferencedFiles, 5, true);
2563         Fill(StreamKind, StreamPos, Parameter+6, MediaInfoLib::Config.Language_Get(Ztring::ToZtring(F1, I3), Measure, MeasureIsAlwaysSame)+__T(" (")+Ztring::ToZtring(F2*100/File_Size_WithReferencedFiles, 0)+__T("%)"), true); // /String5
2564         Fill(StreamKind, StreamPos, Parameter+1,  MediaInfoLib::Config.Language_Get(Ztring::ToZtring(F1, I3), Measure, MeasureIsAlwaysSame)+__T(" (")+Ztring::ToZtring(F2*100/File_Size_WithReferencedFiles, 0)+__T("%)"), true);
2565     }
2566     else if (File_Size_WithReferencedFiles>0 && Parameter==Fill_Parameter(StreamKind, Generic_StreamSize_Encoded) && F2*100/File_Size_WithReferencedFiles<=100)
2567     {
2568         Fill(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_StreamSize_Encoded_Proportion), F2/File_Size_WithReferencedFiles, 5, true);
2569         Fill(StreamKind, StreamPos, Parameter+6, MediaInfoLib::Config.Language_Get(Ztring::ToZtring(F1, I3), Measure, MeasureIsAlwaysSame)+__T(" (")+Ztring::ToZtring(F2*100/File_Size_WithReferencedFiles, 0)+__T("%)"), true); // /String5
2570         Fill(StreamKind, StreamPos, Parameter+1,  MediaInfoLib::Config.Language_Get(Ztring::ToZtring(F1, I3), Measure, MeasureIsAlwaysSame)+__T(" (")+Ztring::ToZtring(F2*100/File_Size_WithReferencedFiles, 0)+__T("%)"), true);
2571     }
2572     else if (File_Size_WithReferencedFiles>0 && Parameter==Fill_Parameter(StreamKind, Generic_Source_StreamSize) && F2*100/File_Size_WithReferencedFiles<=100)
2573     {
2574         Fill(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_Source_StreamSize_Proportion), F2/File_Size_WithReferencedFiles, 5, true);
2575         Fill(StreamKind, StreamPos, Parameter+6, MediaInfoLib::Config.Language_Get(Ztring::ToZtring(F1, I3), Measure, MeasureIsAlwaysSame)+__T(" (")+Ztring::ToZtring(F2*100/File_Size_WithReferencedFiles, 0)+__T("%)"), true); // /String5
2576         Fill(StreamKind, StreamPos, Parameter+1,  MediaInfoLib::Config.Language_Get(Ztring::ToZtring(F1, I3), Measure, MeasureIsAlwaysSame)+__T(" (")+Ztring::ToZtring(F2*100/File_Size_WithReferencedFiles, 0)+__T("%)"), true);
2577     }
2578     else if (File_Size_WithReferencedFiles>0 && Parameter==Fill_Parameter(StreamKind, Generic_Source_StreamSize_Encoded) && F2*100/File_Size_WithReferencedFiles<=100)
2579     {
2580         Fill(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_Source_StreamSize_Encoded_Proportion), F2/File_Size_WithReferencedFiles, 5, true);
2581         Fill(StreamKind, StreamPos, Parameter+6, MediaInfoLib::Config.Language_Get(Ztring::ToZtring(F1, I3), Measure, MeasureIsAlwaysSame)+__T(" (")+Ztring::ToZtring(F2*100/File_Size_WithReferencedFiles, 0)+__T("%)"), true); // /String5
2582         Fill(StreamKind, StreamPos, Parameter+1,  MediaInfoLib::Config.Language_Get(Ztring::ToZtring(F1, I3), Measure, MeasureIsAlwaysSame)+__T(" (")+Ztring::ToZtring(F2*100/File_Size_WithReferencedFiles, 0)+__T("%)"), true);
2583     }
2584     else
2585         Fill(StreamKind, StreamPos, Parameter+1,  MediaInfoLib::Config.Language_Get(Ztring::ToZtring(F1, I3), Measure, MeasureIsAlwaysSame), true);
2586 }
2587 
2588 //---------------------------------------------------------------------------
2589 //FileSize
Kilo_Kilo123(stream_t StreamKind,size_t StreamPos,size_t Parameter)2590 void File__Analyze::Kilo_Kilo123(stream_t StreamKind, size_t StreamPos, size_t Parameter)
2591 {
2592     if (Retrieve(StreamKind, StreamPos, Parameter).empty())
2593         return;
2594 
2595     //Clearing old data
2596     Clear(StreamKind, StreamPos, Parameter+1);
2597 
2598     //Retrieving multiple values
2599     ZtringList List;
2600     List.Separator_Set(0, __T(" / "));
2601     List.Write(Retrieve(StreamKind, StreamPos, Parameter));
2602     ZtringList List2;
2603     List2.Separator_Set(0, __T(" / "));
2604 
2605     //Per value
2606     for (size_t Pos=0; Pos<List.size(); Pos++)
2607     {
2608         int64u BitRate=List[Pos].To_int64u();
2609 
2610         //Text
2611         if (BitRate==0 && (List[Pos].empty() || List[Pos][0]>__T('9')))
2612         {
2613             List2.push_back(MediaInfoLib::Config.Language_Get(List[Pos]));
2614         }
2615         else
2616         {
2617             //Well known values
2618             Ztring BitRateS;
2619             if (StreamKind==Stream_Audio)
2620             {
2621                 if (Parameter==Audio_BitRate
2622                  && (Retrieve(Stream_Audio, StreamPos, Audio_Format)==__T("PCM")
2623                   || Retrieve(Stream_Audio, StreamPos, Audio_Format)==__T("ADPCM")
2624                   || Retrieve(Stream_Audio, StreamPos, Audio_Format)==__T("U-Law")
2625                   || Retrieve(Stream_Audio, StreamPos, Audio_Format)==__T("Qdesign 1")
2626                   || Retrieve(Stream_Audio, StreamPos, Audio_Format)==__T("Qdesign 2")
2627                   || Retrieve(Stream_Audio, StreamPos, Audio_Format)==__T("DTS")))
2628                 {
2629                     if (BitRate==  66150) BitRateS=  "66.15";
2630                     if (BitRate== 132300) BitRateS= "132.3";
2631                     if (BitRate== 176400) BitRateS= "176.4";
2632                     if (BitRate== 264600) BitRateS= "264.6";
2633                     if (BitRate== 352800) BitRateS= "352.8";
2634                     if (BitRate== 529200) BitRateS= "529.2";
2635                     if (BitRate== 705600) BitRateS= "705.6";
2636                     if (BitRate==1411200) BitRateS="1411.2";
2637                 }
2638                 if (Parameter==Audio_SamplingRate)
2639                 {
2640                     if (BitRate==  11024) BitRateS=  "11.024";
2641                     if (BitRate==  11025) BitRateS=  "11.025";
2642                     if (BitRate==  22050) BitRateS=  "22.05";
2643                     if (BitRate==  44100) BitRateS=  "44.1";
2644                     if (BitRate==  88200) BitRateS=  "88.2";
2645                     if (BitRate== 176400) BitRateS= "176.4";
2646                     if (BitRate== 352800) BitRateS= "352.8";
2647                 }
2648             }
2649             if (!BitRateS.empty())
2650             {
2651                 Ztring Measure=MediaInfoLib::Config.Info_Get(StreamKind).Read(Parameter, Info_Measure);
2652                 Measure.insert(1, __T("K"));
2653                 List2.push_back(MediaInfoLib::Config.Language_Get(BitRateS, Measure, true));
2654             }
2655             else
2656             {
2657                 //Standard
2658                 if (BitRate>10000000000LL)
2659                 {
2660                     Ztring Measure=MediaInfoLib::Config.Info_Get(StreamKind).Read(Parameter, Info_Measure);
2661                     Measure.insert(1, __T("G"));
2662                     List2.push_back(MediaInfoLib::Config.Language_Get(Ztring::ToZtring(((float)BitRate)/1000000000, BitRate>100000000000LL?0:1), Measure, true));
2663                 }
2664                 else if (BitRate>10000000)
2665                 {
2666                     Ztring Measure=MediaInfoLib::Config.Info_Get(StreamKind).Read(Parameter, Info_Measure);
2667                     Measure.insert(1, __T("M"));
2668                     List2.push_back(MediaInfoLib::Config.Language_Get(Ztring::ToZtring(((float)BitRate)/1000000, BitRate>100000000?0:1), Measure, true));
2669                 }
2670                 else if (BitRate>10000)
2671                 {
2672                     Ztring Measure=MediaInfoLib::Config.Info_Get(StreamKind).Read(Parameter, Info_Measure);
2673                     Measure.insert(1, __T("K"));
2674                     List2.push_back(MediaInfoLib::Config.Language_Get(Ztring::ToZtring(((float)BitRate)/1000, BitRate>100000?0:1), Measure, true));
2675                 }
2676                 else
2677                     List2.push_back(MediaInfoLib::Config.Language_Get(Ztring::ToZtring(BitRate), MediaInfoLib::Config.Info_Get(StreamKind).Read(Parameter, Info_Measure), true));
2678             }
2679         }
2680     }
2681 
2682     Fill(StreamKind, StreamPos, Parameter+1, List2.Read());
2683 }
2684 
2685 //---------------------------------------------------------------------------
2686 //Value --> Value with measure
Value_Value123(stream_t StreamKind,size_t StreamPos,size_t Parameter)2687 void File__Analyze::Value_Value123(stream_t StreamKind, size_t StreamPos, size_t Parameter)
2688 {
2689     if (Retrieve(StreamKind, StreamPos, Parameter, Info_Measure).empty())
2690         return;
2691 
2692     //Special cases
2693     if (StreamKind==Stream_Audio && Parameter==Audio_BitDepth_Detected && Retrieve(Stream_Audio, StreamPos, Audio_BitDepth)==Retrieve(Stream_Audio, StreamPos, Audio_BitDepth_Detected))
2694         return;
2695 
2696     //Clearing old data
2697     Clear(StreamKind, StreamPos, Parameter+1);
2698 
2699     //Retrieving multiple values
2700     ZtringList List;
2701     List.Separator_Set(0, __T(" / "));
2702     List.Write(Retrieve(StreamKind, StreamPos, Parameter));
2703     ZtringList List2;
2704     List2.Separator_Set(0, __T(" / "));
2705 
2706     //Per value
2707     for (size_t Pos=0; Pos<List.size(); Pos++)
2708     {
2709         //Filling
2710         List2.push_back(MediaInfoLib::Config.Language_Get(List[Pos], MediaInfoLib::Config.Info_Get(StreamKind).Read(Parameter, Info_Measure)));
2711 
2712         //Special case : Audio Channels with ChannelMode
2713         if (StreamKind==Stream_Audio && Parameter==Audio_Channel_s_)
2714         {
2715             const Ztring& ChannelMode=Retrieve_Const(Stream_Audio, StreamPos, "ChannelMode");
2716             if (ChannelMode.size()>3 || (ChannelMode.size()==3 && ChannelMode[2]!=__T('0')))
2717             {
2718                 List2[List2.size()-1]+=__T(" (");
2719                 List2[List2.size()-1]+=ChannelMode;
2720                 List2[List2.size()-1]+=__T(")");
2721             }
2722         }
2723     }
2724 
2725     //Special case : audio with samples per frames
2726     if (StreamKind == Stream_Audio && List2.size() == 1 && Parameter == Audio_FrameRate)
2727     {
2728         const Ztring &SamplesPerFrame = Retrieve(Stream_Audio, StreamPos, Audio_SamplesPerFrame);
2729         if (!SamplesPerFrame.empty())
2730         {
2731             List2[0] += __T(" (");
2732             List2[0] += SamplesPerFrame;
2733             List2[0] += __T(" SPF)");
2734         }
2735     }
2736 
2737     Fill(StreamKind, StreamPos, Parameter+1, List2.Read());
2738 }
2739 
2740 //---------------------------------------------------------------------------
2741 //Value --> Yes or No
YesNo_YesNo(stream_t StreamKind,size_t StreamPos,size_t Parameter)2742 void File__Analyze::YesNo_YesNo(stream_t StreamKind, size_t StreamPos, size_t Parameter)
2743 {
2744     //Filling
2745     Fill(StreamKind, StreamPos, Parameter+1, MediaInfoLib::Config.Language_Get(Retrieve(StreamKind, StreamPos, Parameter)), true);
2746 }
2747 
2748 //---------------------------------------------------------------------------
CodecID_Fill(const Ztring & Value,stream_t StreamKind,size_t StreamPos,infocodecid_format_t Format,stream_t StreamKind_CodecID)2749 void File__Analyze::CodecID_Fill(const Ztring &Value, stream_t StreamKind, size_t StreamPos, infocodecid_format_t Format, stream_t StreamKind_CodecID)
2750 {
2751     if (StreamKind_CodecID==Stream_Max)
2752         StreamKind_CodecID=StreamKind;
2753 
2754     Fill(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_CodecID), Value);
2755     const Ztring &C1=MediaInfoLib::Config.CodecID_Get(StreamKind_CodecID, Format, Value, InfoCodecID_Format);
2756     if (!C1.empty())
2757         Fill(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_Format), C1, true);
2758     Fill(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_CodecID_Info), MediaInfoLib::Config.CodecID_Get(StreamKind_CodecID, Format, Value, InfoCodecID_Description), true);
2759     Fill(StreamKind, StreamPos, "CodecID/Hint", MediaInfoLib::Config.CodecID_Get(StreamKind_CodecID, Format, Value, InfoCodecID_Hint), true);
2760     Fill(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_CodecID_Url), MediaInfoLib::Config.CodecID_Get(StreamKind_CodecID, Format, Value, InfoCodecID_Url), true);
2761     Fill(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_Format_Version), MediaInfoLib::Config.CodecID_Get(StreamKind_CodecID, Format, Value, InfoCodecID_Version), true);
2762     Fill(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_Format_Profile), MediaInfoLib::Config.CodecID_Get(StreamKind_CodecID, Format, Value, InfoCodecID_Profile), true);
2763     Fill(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_ColorSpace), MediaInfoLib::Config.CodecID_Get(StreamKind_CodecID, Format, Value, InfoCodecID_ColorSpace), true);
2764     Fill(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_ChromaSubsampling), MediaInfoLib::Config.CodecID_Get(StreamKind_CodecID, Format, Value, InfoCodecID_ChromaSubsampling), true);
2765     if (Retrieve(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_BitDepth)).empty() && !MediaInfoLib::Config.CodecID_Get(StreamKind_CodecID, Format, Value, InfoCodecID_BitDepth).empty())
2766         Fill(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_BitDepth), MediaInfoLib::Config.CodecID_Get(StreamKind_CodecID, Format, Value, InfoCodecID_BitDepth), true);
2767     if (Retrieve(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_Compression_Mode)).empty())
2768         Fill(StreamKind, StreamPos, Fill_Parameter(StreamKind, Generic_Compression_Mode), MediaInfoLib::Config.CodecID_Get(StreamKind_CodecID, Format, Value, InfoCodecID_Compression_Mode), true);
2769 
2770     //Specific cases
2771     if (Value==__T("v210") || Value==__T("V210"))
2772         Fill(Stream_Video, StreamPos, Video_BitDepth, 10);
2773 }
2774 
2775 //---------------------------------------------------------------------------
PixelAspectRatio_Fill(const Ztring & Value,stream_t StreamKind,size_t StreamPos,size_t Parameter_Width,size_t Parameter_Height,size_t Parameter_PixelAspectRatio,size_t Parameter_DisplayAspectRatio)2776 void File__Analyze::PixelAspectRatio_Fill(const Ztring &Value, stream_t StreamKind, size_t StreamPos, size_t Parameter_Width, size_t Parameter_Height, size_t Parameter_PixelAspectRatio, size_t Parameter_DisplayAspectRatio)
2777 {
2778     if (Value.empty() || !Retrieve(StreamKind, StreamPos, Parameter_DisplayAspectRatio).empty())
2779         return;
2780 
2781     if (Retrieve(StreamKind, StreamPos, Parameter_DisplayAspectRatio).empty())
2782     {
2783         //TODO: trash this crazy test after PAR is in num/den format.
2784         float32 PAR=Value.To_float32();
2785         if (PAR>(float32)12/(float32)11*0.999 && PAR<(float32)12/(float32)11*1.001)
2786             PAR=(float32)12/(float32)11;
2787         if (PAR>(float32)10/(float32)11*0.999 && PAR<(float32)10/(float32)11*1.001)
2788             PAR=(float32)10/(float32)11;
2789         if (PAR>(float32)16/(float32)11*0.999 && PAR<(float32)16/(float32)11*1.001)
2790             PAR=(float32)16/(float32)11;
2791         if (PAR>(float32)16/(float32)15*0.999 && PAR<(float32)16/(float32)15*1.001)
2792             PAR=(float32)16/(float32)15;
2793         if (PAR>(float32)40/(float32)33*0.999 && PAR<(float32)40/(float32)33*1.001)
2794             PAR=(float32)40/(float32)33;
2795         if (PAR>(float32)24/(float32)11*0.999 && PAR<(float32)24/(float32)11*1.001)
2796             PAR=(float32)24/(float32)11;
2797         if (PAR>(float32)20/(float32)11*0.999 && PAR<(float32)20/(float32)11*1.001)
2798             PAR=(float32)20/(float32)11;
2799         if (PAR>(float32)32/(float32)11*0.999 && PAR<(float32)32/(float32)11*1.001)
2800             PAR=(float32)32/(float32)11;
2801         if (PAR>(float32)80/(float32)33*0.999 && PAR<(float32)80/(float32)33*1.001)
2802             PAR=(float32)80/(float32)33;
2803         if (PAR>(float32)18/(float32)11*0.999 && PAR<(float32)18/(float32)11*1.001)
2804             PAR=(float32)18/(float32)11;
2805         if (PAR>(float32)15/(float32)11*0.999 && PAR<(float32)15/(float32)11*1.001)
2806             PAR=(float32)15/(float32)11;
2807         if (PAR>(float32)64/(float32)33*0.999 && PAR<(float32)64/(float32)33*1.001)
2808             PAR=(float32)64/(float32)33;
2809         if (PAR>(float32)160/(float32)99*0.999 && PAR<(float32)160/(float32)99*1.001)
2810             PAR=(float32)160/(float32)99;
2811         if (PAR>(float32)4/(float32)3*0.999 && PAR<(float32)4/(float32)3*1.01)
2812             PAR=(float32)4/(float32)3;
2813         if (PAR>(float32)3/(float32)2*0.999 && PAR<(float32)3/(float32)2*1.001)
2814             PAR=(float32)3/(float32)2;
2815         if (PAR>(float32)2/(float32)1*0.999 && PAR<(float32)2/(float32)1*1.001)
2816             PAR=(float32)2;
2817         if (PAR>(float32)59/(float32)54*0.999 && PAR<(float32)59/(float32)54*1.001)
2818             PAR=(float32)59/(float32)54;
2819         if (PAR>(float32)8/(float32)9*0.999 && PAR<(float32)8/(float32)9*1.001)
2820             PAR=(float32)8/(float32)9;
2821         float32 Width =Retrieve(StreamKind, StreamPos, Parameter_Width             ).To_float32();
2822         float32 Height=Retrieve(StreamKind, StreamPos, Parameter_Height            ).To_float32();
2823         if (PAR && Height && Width)
2824             Fill(StreamKind, StreamPos, Parameter_DisplayAspectRatio, ((float32)Width)/Height*PAR);
2825     }
2826 }
2827 
2828 //---------------------------------------------------------------------------
DisplayAspectRatio_Fill(const Ztring & Value,stream_t StreamKind,size_t StreamPos,size_t Parameter_Width,size_t Parameter_Height,size_t Parameter_PixelAspectRatio,size_t Parameter_DisplayAspectRatio)2829 void File__Analyze::DisplayAspectRatio_Fill(const Ztring &Value, stream_t StreamKind, size_t StreamPos, size_t Parameter_Width, size_t Parameter_Height, size_t Parameter_PixelAspectRatio, size_t Parameter_DisplayAspectRatio)
2830 {
2831     if (Value.empty())
2832         return;
2833 
2834     float DAR=Value.To_float32();
2835 
2836     if (Retrieve(StreamKind, StreamPos, Parameter_PixelAspectRatio).empty())
2837     {
2838         float Width =Retrieve(StreamKind, StreamPos, Parameter_Width).To_float32();
2839         float Height=Retrieve(StreamKind, StreamPos, Parameter_Height).To_float32();
2840         if (DAR && Height && Width)
2841         {
2842             if (Value==__T("1.778"))
2843                 DAR=((float)16)/9; //More exact value
2844             if (Value==__T("1.333"))
2845                 DAR=((float)4)/3; //More exact value
2846             Fill(StreamKind, StreamPos, Parameter_PixelAspectRatio, DAR/(((float32)Width)/Height));
2847         }
2848     }
2849 
2850     // /String version
2851     Ztring DARS;
2852          if (DAR>=(float)1.23 && DAR<(float)1.27)   DARS=__T("5:4");
2853     else if (DAR>=(float)1.30 && DAR<(float)1.37)   DARS=__T("4:3");
2854     else if (DAR>=(float)1.45 && DAR<(float)1.55)   DARS=__T("3:2");
2855     else if (DAR>=(float)1.55 && DAR<(float)1.65)   DARS=__T("16:10");
2856     else if (DAR>=(float)1.65 && DAR<(float)1.70)   DARS=__T("5:3");
2857     else if (DAR>=(float)1.74 && DAR<(float)1.82)   DARS=__T("16:9");
2858     else if (DAR>=(float)1.82 && DAR<(float)1.88)   DARS=__T("1.85:1");
2859     else if (DAR>=(float)2.15 && DAR<(float)2.22)   DARS=__T("2.2:1");
2860     else if (DAR>=(float)2.23 && DAR<(float)2.30)   DARS=__T("2.25:1");
2861     else if (DAR>=(float)2.30 && DAR<(float)2.37)   DARS=__T("2.35:1");
2862     else if (DAR>=(float)2.37 && DAR<(float)2.45)   DARS=__T("2.40:1");
2863     else                                            DARS.From_Number(DAR);
2864       DARS.FindAndReplace(__T("."), MediaInfoLib::Config.Language_Get(__T("  Config_Text_FloatSeparator")));
2865     if (MediaInfoLib::Config.Language_Get(__T("  Language_ISO639"))==__T("fr") &&   DARS.find(__T(":1"))==string::npos)
2866           DARS.FindAndReplace(__T(":"), __T("/"));
2867     Fill(StreamKind, StreamPos, Parameter_DisplayAspectRatio+1, DARS, true);
2868 }
2869 
2870 //---------------------------------------------------------------------------
Fill_Parameter(stream_t StreamKind,generic StreamPos)2871 size_t File__Analyze::Fill_Parameter(stream_t StreamKind, generic StreamPos)
2872 {
2873     switch (StreamKind)
2874     {
2875         case Stream_General :
2876                                 switch (StreamPos)
2877                                 {
2878                                     case Generic_Format : return General_Format;
2879                                     case Generic_Format_Info : return General_Format_Info;
2880                                     case Generic_Format_Url : return General_Format_Url;
2881                                     case Generic_Format_String : return General_Format_String;
2882                                     case Generic_Format_Version : return General_Format_Version;
2883                                     case Generic_Format_Commercial : return General_Format_Commercial;
2884                                     case Generic_Format_Commercial_IfAny : return General_Format_Commercial_IfAny;
2885                                     case Generic_Format_Profile : return General_Format_Profile;
2886                                     case Generic_Format_Level: return General_Format_Level;
2887                                     case Generic_Format_Settings : return General_Format_Settings;
2888                                     case Generic_Format_AdditionalFeatures : return General_Format_AdditionalFeatures;
2889                                     case Generic_InternetMediaType : return General_InternetMediaType;
2890                                     case Generic_CodecID : return General_CodecID;
2891                                     case Generic_CodecID_Info : return General_CodecID_Info;
2892                                     case Generic_CodecID_Hint : return General_CodecID_Hint;
2893                                     case Generic_CodecID_Url : return General_CodecID_Url;
2894                                     case Generic_CodecID_Description : return General_CodecID_Description;
2895                                     case Generic_Codec : return General_Codec;
2896                                     case Generic_Codec_String : return General_Codec_String;
2897                                     case Generic_Codec_Info : return General_Codec_Info;
2898                                     case Generic_Codec_Url : return General_Codec_Url;
2899                                     case Generic_Duration : return General_Duration;
2900                                     case Generic_Duration_String : return General_Duration_String;
2901                                     case Generic_Duration_String1 : return General_Duration_String1;
2902                                     case Generic_Duration_String2 : return General_Duration_String2;
2903                                     case Generic_Duration_String3 : return General_Duration_String3;
2904                                     case Generic_Duration_String4 : return General_Duration_String4;
2905                                     case Generic_Duration_String5 : return General_Duration_String5;
2906                                     case Generic_FrameRate : return General_FrameRate;
2907                                     case Generic_FrameCount : return General_FrameCount;
2908                                     case Generic_Delay : return General_Delay;
2909                                     case Generic_Delay_String : return General_Delay_String;
2910                                     case Generic_Delay_String1 : return General_Delay_String1;
2911                                     case Generic_Delay_String2 : return General_Delay_String2;
2912                                     case Generic_Delay_String3 : return General_Delay_String3;
2913                                     case Generic_Delay_String4 : return General_Delay_String4;
2914                                     case Generic_Delay_String5 : return General_Delay_String5;
2915                                     case Generic_Delay_Settings : return General_Delay_Settings;
2916                                     case Generic_Delay_DropFrame : return General_Delay_DropFrame;
2917                                     case Generic_Delay_Source : return General_Delay_Source;
2918                                     case Generic_Delay_Source_String : return General_Delay_Source_String;
2919                                     case Generic_StreamSize : return General_StreamSize;
2920                                     case Generic_StreamSize_String : return General_StreamSize_String;
2921                                     case Generic_StreamSize_String1 : return General_StreamSize_String1;
2922                                     case Generic_StreamSize_String2 : return General_StreamSize_String2;
2923                                     case Generic_StreamSize_String3 : return General_StreamSize_String3;
2924                                     case Generic_StreamSize_String4 : return General_StreamSize_String4;
2925                                     case Generic_StreamSize_String5 : return General_StreamSize_String5;
2926                                     case Generic_StreamSize_Proportion : return General_StreamSize_Proportion;
2927                                     case Generic_ServiceName : return General_ServiceName;
2928                                     case Generic_ServiceProvider : return General_ServiceProvider;
2929                                     default: return (size_t)-1;
2930                                 }
2931         case Stream_Video :
2932                                 switch (StreamPos)
2933                                 {
2934                                     case Generic_Format : return Video_Format;
2935                                     case Generic_Format_Info : return Video_Format_Info;
2936                                     case Generic_Format_Url : return Video_Format_Url;
2937                                     case Generic_Format_String: return Video_Format_String;
2938                                     case Generic_Format_Commercial : return Video_Format_Commercial;
2939                                     case Generic_Format_Commercial_IfAny : return Video_Format_Commercial_IfAny;
2940                                     case Generic_Format_Version : return Video_Format_Version;
2941                                     case Generic_Format_Profile : return Video_Format_Profile;
2942                                     case Generic_Format_Level: return Video_Format_Level;
2943                                     case Generic_Format_Tier: return Video_Format_Tier;
2944                                     case Generic_Format_Settings : return Video_Format_Settings;
2945                                     case Generic_Format_AdditionalFeatures : return Video_Format_AdditionalFeatures;
2946                                     case Generic_InternetMediaType : return Video_InternetMediaType;
2947                                     case Generic_CodecID : return Video_CodecID;
2948                                     case Generic_CodecID_Info : return Video_CodecID_Info;
2949                                     case Generic_CodecID_Hint : return Video_CodecID_Hint;
2950                                     case Generic_CodecID_Url : return Video_CodecID_Url;
2951                                     case Generic_CodecID_Description : return Video_CodecID_Description;
2952                                     case Generic_Codec : return Video_Codec;
2953                                     case Generic_Codec_String : return Video_Codec_String;
2954                                     case Generic_Codec_Info : return Video_Codec_Info;
2955                                     case Generic_Codec_Url : return Video_Codec_Url;
2956                                     case Generic_Codec_CC : return Video_Codec_CC;
2957                                     case Generic_Duration : return Video_Duration;
2958                                     case Generic_Duration_String : return Video_Duration_String;
2959                                     case Generic_Duration_String1 : return Video_Duration_String1;
2960                                     case Generic_Duration_String2 : return Video_Duration_String2;
2961                                     case Generic_Duration_String3 : return Video_Duration_String3;
2962                                     case Generic_Duration_String4 : return Video_Duration_String4;
2963                                     case Generic_Duration_String5 : return Video_Duration_String5;
2964                                     case Generic_Source_Duration : return Video_Source_Duration;
2965                                     case Generic_Source_Duration_String : return Video_Source_Duration_String;
2966                                     case Generic_Source_Duration_String1 : return Video_Source_Duration_String1;
2967                                     case Generic_Source_Duration_String2 : return Video_Source_Duration_String2;
2968                                     case Generic_Source_Duration_String3 : return Video_Source_Duration_String3;
2969                                     case Generic_Source_Duration_String4 : return Video_Source_Duration_String4;
2970                                     case Generic_Source_Duration_String5 : return Video_Source_Duration_String5;
2971                                     case Generic_BitRate_Mode : return Video_BitRate_Mode;
2972                                     case Generic_BitRate_Mode_String : return Video_BitRate_Mode_String;
2973                                     case Generic_BitRate : return Video_BitRate;
2974                                     case Generic_BitRate_String : return Video_BitRate_String;
2975                                     case Generic_BitRate_Minimum : return Video_BitRate_Minimum;
2976                                     case Generic_BitRate_Minimum_String : return Video_BitRate_Minimum_String;
2977                                     case Generic_BitRate_Nominal : return Video_BitRate_Nominal;
2978                                     case Generic_BitRate_Nominal_String : return Video_BitRate_Nominal_String;
2979                                     case Generic_BitRate_Maximum : return Video_BitRate_Maximum;
2980                                     case Generic_BitRate_Maximum_String : return Video_BitRate_Maximum_String;
2981                                     case Generic_BitRate_Encoded : return Video_BitRate_Encoded;
2982                                     case Generic_BitRate_Encoded_String : return Video_BitRate_Encoded_String;
2983                                     case Generic_FrameRate : return Video_FrameRate;
2984                                     case Generic_FrameCount : return Video_FrameCount;
2985                                     case Generic_Source_FrameCount : return Video_Source_FrameCount;
2986                                     case Generic_ColorSpace : return Video_ColorSpace;
2987                                     case Generic_ChromaSubsampling : return Video_ChromaSubsampling;
2988                                     case Generic_Resolution : return Video_Resolution;
2989                                     case Generic_Resolution_String : return Video_Resolution_String;
2990                                     case Generic_BitDepth : return Video_BitDepth;
2991                                     case Generic_BitDepth_String : return Video_BitDepth_String;
2992                                     case Generic_Compression_Mode : return Video_Compression_Mode;
2993                                     case Generic_Compression_Mode_String : return Video_Compression_Mode_String;
2994                                     case Generic_Compression_Ratio : return Video_Compression_Ratio;
2995                                     case Generic_Delay : return Video_Delay;
2996                                     case Generic_Delay_String : return Video_Delay_String;
2997                                     case Generic_Delay_String1 : return Video_Delay_String1;
2998                                     case Generic_Delay_String2 : return Video_Delay_String2;
2999                                     case Generic_Delay_String3 : return Video_Delay_String3;
3000                                     case Generic_Delay_String4 : return Video_Delay_String4;
3001                                     case Generic_Delay_String5 : return Video_Delay_String5;
3002                                     case Generic_Delay_Settings : return Video_Delay_Settings;
3003                                     case Generic_Delay_DropFrame : return Video_Delay_DropFrame;
3004                                     case Generic_Delay_Source : return Video_Delay_Source;
3005                                     case Generic_Delay_Source_String : return Video_Delay_Source_String;
3006                                     case Generic_Delay_Original : return Video_Delay_Original;
3007                                     case Generic_Delay_Original_String : return Video_Delay_Original_String;
3008                                     case Generic_Delay_Original_String1 : return Video_Delay_Original_String1;
3009                                     case Generic_Delay_Original_String2 : return Video_Delay_Original_String2;
3010                                     case Generic_Delay_Original_String3 : return Video_Delay_Original_String3;
3011                                     case Generic_Delay_Original_String4 : return Video_Delay_Original_String4;
3012                                     case Generic_Delay_Original_Settings : return Video_Delay_Original_Settings;
3013                                     case Generic_Delay_Original_DropFrame : return Video_Delay_Original_DropFrame;
3014                                     case Generic_Delay_Original_Source : return Video_Delay_Original_Source;
3015                                     case Generic_StreamSize : return Video_StreamSize;
3016                                     case Generic_StreamSize_String : return Video_StreamSize_String;
3017                                     case Generic_StreamSize_String1 : return Video_StreamSize_String1;
3018                                     case Generic_StreamSize_String2 : return Video_StreamSize_String2;
3019                                     case Generic_StreamSize_String3 : return Video_StreamSize_String3;
3020                                     case Generic_StreamSize_String4 : return Video_StreamSize_String4;
3021                                     case Generic_StreamSize_String5 : return Video_StreamSize_String5;
3022                                     case Generic_StreamSize_Proportion : return Video_StreamSize_Proportion;
3023                                     case Generic_StreamSize_Encoded : return Video_StreamSize_Encoded;
3024                                     case Generic_StreamSize_Encoded_String : return Video_StreamSize_Encoded_String;
3025                                     case Generic_StreamSize_Encoded_String1 : return Video_StreamSize_Encoded_String1;
3026                                     case Generic_StreamSize_Encoded_String2 : return Video_StreamSize_Encoded_String2;
3027                                     case Generic_StreamSize_Encoded_String3 : return Video_StreamSize_Encoded_String3;
3028                                     case Generic_StreamSize_Encoded_String4 : return Video_StreamSize_Encoded_String4;
3029                                     case Generic_StreamSize_Encoded_String5 : return Video_StreamSize_Encoded_String5;
3030                                     case Generic_StreamSize_Encoded_Proportion : return Video_StreamSize_Encoded_Proportion;
3031                                     case Generic_Source_StreamSize : return Video_Source_StreamSize;
3032                                     case Generic_Source_StreamSize_String : return Video_Source_StreamSize_String;
3033                                     case Generic_Source_StreamSize_String1 : return Video_Source_StreamSize_String1;
3034                                     case Generic_Source_StreamSize_String2 : return Video_Source_StreamSize_String2;
3035                                     case Generic_Source_StreamSize_String3 : return Video_Source_StreamSize_String3;
3036                                     case Generic_Source_StreamSize_String4 : return Video_Source_StreamSize_String4;
3037                                     case Generic_Source_StreamSize_String5 : return Video_Source_StreamSize_String5;
3038                                     case Generic_Source_StreamSize_Proportion : return Video_Source_StreamSize_Proportion;
3039                                     case Generic_Source_StreamSize_Encoded : return Video_Source_StreamSize_Encoded;
3040                                     case Generic_Source_StreamSize_Encoded_String : return Video_Source_StreamSize_Encoded_String;
3041                                     case Generic_Source_StreamSize_Encoded_String1 : return Video_Source_StreamSize_Encoded_String1;
3042                                     case Generic_Source_StreamSize_Encoded_String2 : return Video_Source_StreamSize_Encoded_String2;
3043                                     case Generic_Source_StreamSize_Encoded_String3 : return Video_Source_StreamSize_Encoded_String3;
3044                                     case Generic_Source_StreamSize_Encoded_String4 : return Video_Source_StreamSize_Encoded_String4;
3045                                     case Generic_Source_StreamSize_Encoded_String5 : return Video_Source_StreamSize_Encoded_String5;
3046                                     case Generic_Source_StreamSize_Encoded_Proportion : return Video_Source_StreamSize_Encoded_Proportion;
3047                                     case Generic_Language : return Video_Language;
3048                                     default: return (size_t)-1;
3049                                 }
3050         case Stream_Audio :
3051                                 switch (StreamPos)
3052                                 {
3053                                     case Generic_Format : return Audio_Format;
3054                                     case Generic_Format_Info : return Audio_Format_Info;
3055                                     case Generic_Format_Url : return Audio_Format_Url;
3056                                     case Generic_Format_String : return Audio_Format_String;
3057                                     case Generic_Format_Commercial : return Audio_Format_Commercial;
3058                                     case Generic_Format_Commercial_IfAny : return Audio_Format_Commercial_IfAny;
3059                                     case Generic_Format_Version : return Audio_Format_Version;
3060                                     case Generic_Format_Profile : return Audio_Format_Profile;
3061                                     case Generic_Format_Level: return Audio_Format_Level;
3062                                     case Generic_Format_Settings : return Audio_Format_Settings;
3063                                     case Generic_Format_AdditionalFeatures : return Audio_Format_AdditionalFeatures;
3064                                     case Generic_InternetMediaType : return Audio_InternetMediaType;
3065                                     case Generic_CodecID : return Audio_CodecID;
3066                                     case Generic_CodecID_Info : return Audio_CodecID_Info;
3067                                     case Generic_CodecID_Hint : return Audio_CodecID_Hint;
3068                                     case Generic_CodecID_Url : return Audio_CodecID_Url;
3069                                     case Generic_CodecID_Description : return Audio_CodecID_Description;
3070                                     case Generic_Codec : return Audio_Codec;
3071                                     case Generic_Codec_String : return Audio_Codec_String;
3072                                     case Generic_Codec_Info : return Audio_Codec_Info;
3073                                     case Generic_Codec_Url : return Audio_Codec_Url;
3074                                     case Generic_Codec_CC : return Audio_Codec_CC;
3075                                     case Generic_Duration : return Audio_Duration;
3076                                     case Generic_Duration_String : return Audio_Duration_String;
3077                                     case Generic_Duration_String1 : return Audio_Duration_String1;
3078                                     case Generic_Duration_String2 : return Audio_Duration_String2;
3079                                     case Generic_Duration_String3 : return Audio_Duration_String3;
3080                                     case Generic_Duration_String4 : return Audio_Duration_String4;
3081                                     case Generic_Duration_String5 : return Audio_Duration_String5;
3082                                     case Generic_Source_Duration : return Audio_Source_Duration;
3083                                     case Generic_Source_Duration_String : return Audio_Source_Duration_String;
3084                                     case Generic_Source_Duration_String1 : return Audio_Source_Duration_String1;
3085                                     case Generic_Source_Duration_String2 : return Audio_Source_Duration_String2;
3086                                     case Generic_Source_Duration_String3 : return Audio_Source_Duration_String3;
3087                                     case Generic_Source_Duration_String4 : return Audio_Source_Duration_String4;
3088                                     case Generic_Source_Duration_String5 : return Audio_Source_Duration_String5;
3089                                     case Generic_BitRate_Mode : return Audio_BitRate_Mode;
3090                                     case Generic_BitRate_Mode_String : return Audio_BitRate_Mode_String;
3091                                     case Generic_BitRate : return Audio_BitRate;
3092                                     case Generic_BitRate_String : return Audio_BitRate_String;
3093                                     case Generic_BitRate_Minimum : return Audio_BitRate_Minimum;
3094                                     case Generic_BitRate_Minimum_String : return Audio_BitRate_Minimum_String;
3095                                     case Generic_BitRate_Nominal : return Audio_BitRate_Nominal;
3096                                     case Generic_BitRate_Nominal_String : return Audio_BitRate_Nominal_String;
3097                                     case Generic_BitRate_Maximum : return Audio_BitRate_Maximum;
3098                                     case Generic_BitRate_Maximum_String : return Audio_BitRate_Maximum_String;
3099                                     case Generic_BitRate_Encoded : return Audio_BitRate_Encoded;
3100                                     case Generic_BitRate_Encoded_String : return Audio_BitRate_Encoded_String;
3101                                     case Generic_FrameRate : return Audio_FrameRate;
3102                                     case Generic_FrameCount : return Audio_FrameCount;
3103                                     case Generic_Source_FrameCount : return Audio_Source_FrameCount;
3104                                     case Generic_Resolution : return Audio_Resolution;
3105                                     case Generic_Resolution_String : return Audio_Resolution_String;
3106                                     case Generic_BitDepth : return Audio_BitDepth;
3107                                     case Generic_BitDepth_String : return Audio_BitDepth_String;
3108                                     case Generic_Compression_Mode : return Audio_Compression_Mode;
3109                                     case Generic_Compression_Mode_String : return Audio_Compression_Mode_String;
3110                                     case Generic_Compression_Ratio : return Audio_Compression_Ratio;
3111                                     case Generic_Delay : return Audio_Delay;
3112                                     case Generic_Delay_String : return Audio_Delay_String;
3113                                     case Generic_Delay_String1 : return Audio_Delay_String1;
3114                                     case Generic_Delay_String2 : return Audio_Delay_String2;
3115                                     case Generic_Delay_String3 : return Audio_Delay_String3;
3116                                     case Generic_Delay_String4 : return Audio_Delay_String4;
3117                                     case Generic_Delay_String5 : return Audio_Delay_String5;
3118                                     case Generic_Delay_Settings : return Audio_Delay_Settings;
3119                                     case Generic_Delay_DropFrame : return Audio_Delay_DropFrame;
3120                                     case Generic_Delay_Source : return Audio_Delay_Source;
3121                                     case Generic_Delay_Source_String : return Audio_Delay_Source_String;
3122                                     case Generic_Delay_Original : return Audio_Delay_Original;
3123                                     case Generic_Delay_Original_String : return Audio_Delay_Original_String;
3124                                     case Generic_Delay_Original_String1 : return Audio_Delay_Original_String1;
3125                                     case Generic_Delay_Original_String2 : return Audio_Delay_Original_String2;
3126                                     case Generic_Delay_Original_String3 : return Audio_Delay_Original_String3;
3127                                     case Generic_Delay_Original_String4 : return Audio_Delay_Original_String4;
3128                                     case Generic_Delay_Original_Settings : return Audio_Delay_Original_Settings;
3129                                     case Generic_Delay_Original_DropFrame : return Audio_Delay_Original_DropFrame;
3130                                     case Generic_Delay_Original_Source : return Audio_Delay_Original_Source;
3131                                     case Generic_Video_Delay : return Audio_Video_Delay;
3132                                     case Generic_Video_Delay_String : return Audio_Video_Delay_String;
3133                                     case Generic_Video_Delay_String1 : return Audio_Video_Delay_String1;
3134                                     case Generic_Video_Delay_String2 : return Audio_Video_Delay_String2;
3135                                     case Generic_Video_Delay_String3 : return Audio_Video_Delay_String3;
3136                                     case Generic_Video_Delay_String4 : return Audio_Video_Delay_String4;
3137                                     case Generic_StreamSize : return Audio_StreamSize;
3138                                     case Generic_StreamSize_String : return Audio_StreamSize_String;
3139                                     case Generic_StreamSize_String1 : return Audio_StreamSize_String1;
3140                                     case Generic_StreamSize_String2 : return Audio_StreamSize_String2;
3141                                     case Generic_StreamSize_String3 : return Audio_StreamSize_String3;
3142                                     case Generic_StreamSize_String4 : return Audio_StreamSize_String4;
3143                                     case Generic_StreamSize_String5 : return Audio_StreamSize_String5;
3144                                     case Generic_StreamSize_Proportion : return Audio_StreamSize_Proportion;
3145                                     case Generic_StreamSize_Encoded : return Audio_StreamSize_Encoded;
3146                                     case Generic_StreamSize_Encoded_String : return Audio_StreamSize_Encoded_String;
3147                                     case Generic_StreamSize_Encoded_String1 : return Audio_StreamSize_Encoded_String1;
3148                                     case Generic_StreamSize_Encoded_String2 : return Audio_StreamSize_Encoded_String2;
3149                                     case Generic_StreamSize_Encoded_String3 : return Audio_StreamSize_Encoded_String3;
3150                                     case Generic_StreamSize_Encoded_String4 : return Audio_StreamSize_Encoded_String4;
3151                                     case Generic_StreamSize_Encoded_String5 : return Audio_StreamSize_Encoded_String5;
3152                                     case Generic_StreamSize_Encoded_Proportion : return Audio_StreamSize_Encoded_Proportion;
3153                                     case Generic_Source_StreamSize : return Audio_Source_StreamSize;
3154                                     case Generic_Source_StreamSize_String : return Audio_Source_StreamSize_String;
3155                                     case Generic_Source_StreamSize_String1 : return Audio_Source_StreamSize_String1;
3156                                     case Generic_Source_StreamSize_String2 : return Audio_Source_StreamSize_String2;
3157                                     case Generic_Source_StreamSize_String3 : return Audio_Source_StreamSize_String3;
3158                                     case Generic_Source_StreamSize_String4 : return Audio_Source_StreamSize_String4;
3159                                     case Generic_Source_StreamSize_String5 : return Audio_Source_StreamSize_String5;
3160                                     case Generic_Source_StreamSize_Proportion : return Audio_Source_StreamSize_Proportion;
3161                                     case Generic_Source_StreamSize_Encoded : return Audio_Source_StreamSize_Encoded;
3162                                     case Generic_Source_StreamSize_Encoded_String : return Audio_Source_StreamSize_Encoded_String;
3163                                     case Generic_Source_StreamSize_Encoded_String1 : return Audio_Source_StreamSize_Encoded_String1;
3164                                     case Generic_Source_StreamSize_Encoded_String2 : return Audio_Source_StreamSize_Encoded_String2;
3165                                     case Generic_Source_StreamSize_Encoded_String3 : return Audio_Source_StreamSize_Encoded_String3;
3166                                     case Generic_Source_StreamSize_Encoded_String4 : return Audio_Source_StreamSize_Encoded_String4;
3167                                     case Generic_Source_StreamSize_Encoded_String5 : return Audio_Source_StreamSize_Encoded_String5;
3168                                     case Generic_Source_StreamSize_Encoded_Proportion : return Audio_Source_StreamSize_Encoded_Proportion;
3169                                     case Generic_Language : return Audio_Language;
3170                                     default: return (size_t)-1;
3171                                 }
3172         case Stream_Text :
3173                                 switch (StreamPos)
3174                                 {
3175                                     case Generic_Format : return Text_Format;
3176                                     case Generic_Format_Info : return Text_Format_Info;
3177                                     case Generic_Format_Url : return Text_Format_Url;
3178                                     case Generic_Format_String : return Text_Format_String;
3179                                     case Generic_Format_Commercial : return Text_Format_Commercial;
3180                                     case Generic_Format_Commercial_IfAny : return Text_Format_Commercial_IfAny;
3181                                     case Generic_Format_Version : return Text_Format_Version;
3182                                     case Generic_Format_Profile : return Text_Format_Profile;
3183                                     case Generic_Format_Settings : return Text_Format_Settings;
3184                                     case Generic_Format_AdditionalFeatures : return Text_Format_AdditionalFeatures;
3185                                     case Generic_InternetMediaType : return Text_InternetMediaType;
3186                                     case Generic_CodecID : return Text_CodecID;
3187                                     case Generic_CodecID_Info : return Text_CodecID_Info;
3188                                     case Generic_CodecID_Hint : return Text_CodecID_Hint;
3189                                     case Generic_CodecID_Url : return Text_CodecID_Url;
3190                                     case Generic_CodecID_Description : return Text_CodecID_Description;
3191                                     case Generic_Codec : return Text_Codec;
3192                                     case Generic_Codec_String : return Text_Codec_String;
3193                                     case Generic_Codec_Info : return Text_Codec_Info;
3194                                     case Generic_Codec_Url : return Text_Codec_Url;
3195                                     case Generic_Codec_CC : return Text_Codec_CC;
3196                                     case Generic_Duration : return Text_Duration;
3197                                     case Generic_Duration_String : return Text_Duration_String;
3198                                     case Generic_Duration_String1 : return Text_Duration_String1;
3199                                     case Generic_Duration_String2 : return Text_Duration_String2;
3200                                     case Generic_Duration_String3 : return Text_Duration_String3;
3201                                     case Generic_Duration_String4 : return Text_Duration_String4;
3202                                     case Generic_Duration_String5 : return Text_Duration_String5;
3203                                     case Generic_Source_Duration : return Text_Source_Duration;
3204                                     case Generic_Source_Duration_String : return Text_Source_Duration_String;
3205                                     case Generic_Source_Duration_String1 : return Text_Source_Duration_String1;
3206                                     case Generic_Source_Duration_String2 : return Text_Source_Duration_String2;
3207                                     case Generic_Source_Duration_String3 : return Text_Source_Duration_String3;
3208                                     case Generic_Source_Duration_String4 : return Text_Source_Duration_String4;
3209                                     case Generic_Source_Duration_String5 : return Text_Source_Duration_String5;
3210                                     case Generic_BitRate_Mode : return Text_BitRate_Mode;
3211                                     case Generic_BitRate_Mode_String : return Text_BitRate_Mode_String;
3212                                     case Generic_BitRate : return Text_BitRate;
3213                                     case Generic_BitRate_String : return Text_BitRate_String;
3214                                     case Generic_BitRate_Minimum : return Text_BitRate_Minimum;
3215                                     case Generic_BitRate_Minimum_String : return Text_BitRate_Minimum_String;
3216                                     case Generic_BitRate_Nominal : return Text_BitRate_Nominal;
3217                                     case Generic_BitRate_Nominal_String : return Text_BitRate_Nominal_String;
3218                                     case Generic_BitRate_Maximum : return Text_BitRate_Maximum;
3219                                     case Generic_BitRate_Maximum_String : return Text_BitRate_Maximum_String;
3220                                     case Generic_BitRate_Encoded : return Text_BitRate_Encoded;
3221                                     case Generic_BitRate_Encoded_String : return Text_BitRate_Encoded_String;
3222                                     case Generic_FrameRate : return Text_FrameRate;
3223                                     case Generic_FrameCount : return Text_FrameCount;
3224                                     case Generic_Source_FrameCount : return Text_Source_FrameCount;
3225                                     case Generic_ColorSpace : return Text_ColorSpace;
3226                                     case Generic_ChromaSubsampling : return Text_ChromaSubsampling;
3227                                     case Generic_Resolution : return Text_Resolution;
3228                                     case Generic_Resolution_String : return Text_Resolution_String;
3229                                     case Generic_BitDepth : return Text_BitDepth;
3230                                     case Generic_BitDepth_String : return Text_BitDepth_String;
3231                                     case Generic_Compression_Mode : return Text_Compression_Mode;
3232                                     case Generic_Compression_Mode_String : return Text_Compression_Mode_String;
3233                                     case Generic_Compression_Ratio : return Text_Compression_Ratio;
3234                                     case Generic_Delay : return Text_Delay;
3235                                     case Generic_Delay_String : return Text_Delay_String;
3236                                     case Generic_Delay_String1 : return Text_Delay_String1;
3237                                     case Generic_Delay_String2 : return Text_Delay_String2;
3238                                     case Generic_Delay_String3 : return Text_Delay_String3;
3239                                     case Generic_Delay_String4 : return Text_Delay_String4;
3240                                     case Generic_Delay_String5 : return Text_Delay_String5;
3241                                     case Generic_Delay_Settings : return Text_Delay_Settings;
3242                                     case Generic_Delay_DropFrame : return Text_Delay_DropFrame;
3243                                     case Generic_Delay_Source : return Text_Delay_Source;
3244                                     case Generic_Delay_Source_String : return Text_Delay_Source_String;
3245                                     case Generic_Delay_Original : return Text_Delay_Original;
3246                                     case Generic_Delay_Original_String : return Text_Delay_Original_String;
3247                                     case Generic_Delay_Original_String1 : return Text_Delay_Original_String1;
3248                                     case Generic_Delay_Original_String2 : return Text_Delay_Original_String2;
3249                                     case Generic_Delay_Original_String3 : return Text_Delay_Original_String3;
3250                                     case Generic_Delay_Original_String4 : return Text_Delay_Original_String4;
3251                                     case Generic_Delay_Original_Settings : return Text_Delay_Original_Settings;
3252                                     case Generic_Delay_Original_DropFrame : return Text_Delay_Original_DropFrame;
3253                                     case Generic_Delay_Original_Source : return Text_Delay_Original_Source;
3254                                     case Generic_Video_Delay : return Text_Video_Delay;
3255                                     case Generic_Video_Delay_String : return Text_Video_Delay_String;
3256                                     case Generic_Video_Delay_String1 : return Text_Video_Delay_String1;
3257                                     case Generic_Video_Delay_String2 : return Text_Video_Delay_String2;
3258                                     case Generic_Video_Delay_String3 : return Text_Video_Delay_String3;
3259                                     case Generic_Video_Delay_String4 : return Text_Video_Delay_String4;
3260                                     case Generic_StreamSize : return Text_StreamSize;
3261                                     case Generic_StreamSize_String : return Text_StreamSize_String;
3262                                     case Generic_StreamSize_String1 : return Text_StreamSize_String1;
3263                                     case Generic_StreamSize_String2 : return Text_StreamSize_String2;
3264                                     case Generic_StreamSize_String3 : return Text_StreamSize_String3;
3265                                     case Generic_StreamSize_String4 : return Text_StreamSize_String4;
3266                                     case Generic_StreamSize_String5 : return Text_StreamSize_String5;
3267                                     case Generic_StreamSize_Proportion : return Text_StreamSize_Proportion;
3268                                     case Generic_StreamSize_Encoded : return Text_StreamSize_Encoded;
3269                                     case Generic_StreamSize_Encoded_String : return Text_StreamSize_Encoded_String;
3270                                     case Generic_StreamSize_Encoded_String1 : return Text_StreamSize_Encoded_String1;
3271                                     case Generic_StreamSize_Encoded_String2 : return Text_StreamSize_Encoded_String2;
3272                                     case Generic_StreamSize_Encoded_String3 : return Text_StreamSize_Encoded_String3;
3273                                     case Generic_StreamSize_Encoded_String4 : return Text_StreamSize_Encoded_String4;
3274                                     case Generic_StreamSize_Encoded_String5 : return Text_StreamSize_Encoded_String5;
3275                                     case Generic_StreamSize_Encoded_Proportion : return Text_StreamSize_Encoded_Proportion;
3276                                     case Generic_Source_StreamSize : return Text_Source_StreamSize;
3277                                     case Generic_Source_StreamSize_String : return Text_Source_StreamSize_String;
3278                                     case Generic_Source_StreamSize_String1 : return Text_Source_StreamSize_String1;
3279                                     case Generic_Source_StreamSize_String2 : return Text_Source_StreamSize_String2;
3280                                     case Generic_Source_StreamSize_String3 : return Text_Source_StreamSize_String3;
3281                                     case Generic_Source_StreamSize_String4 : return Text_Source_StreamSize_String4;
3282                                     case Generic_Source_StreamSize_String5 : return Text_Source_StreamSize_String5;
3283                                     case Generic_Source_StreamSize_Proportion : return Text_Source_StreamSize_Proportion;
3284                                     case Generic_Source_StreamSize_Encoded : return Text_Source_StreamSize_Encoded;
3285                                     case Generic_Source_StreamSize_Encoded_String : return Text_Source_StreamSize_Encoded_String;
3286                                     case Generic_Source_StreamSize_Encoded_String1 : return Text_Source_StreamSize_Encoded_String1;
3287                                     case Generic_Source_StreamSize_Encoded_String2 : return Text_Source_StreamSize_Encoded_String2;
3288                                     case Generic_Source_StreamSize_Encoded_String3 : return Text_Source_StreamSize_Encoded_String3;
3289                                     case Generic_Source_StreamSize_Encoded_String4 : return Text_Source_StreamSize_Encoded_String4;
3290                                     case Generic_Source_StreamSize_Encoded_String5 : return Text_Source_StreamSize_Encoded_String5;
3291                                     case Generic_Source_StreamSize_Encoded_Proportion : return Text_Source_StreamSize_Encoded_Proportion;
3292                                     case Generic_Language : return Text_Language;
3293                                     default: return (size_t)-1;
3294                                 }
3295         case Stream_Other :
3296                                 switch (StreamPos)
3297                                 {
3298                                     case Generic_Format : return Other_Format;
3299                                     case Generic_Format_Info : return Other_Format_Info;
3300                                     case Generic_Format_Url : return Other_Format_Url;
3301                                     case Generic_Format_String : return Other_Format_String;
3302                                     case Generic_Format_Commercial : return Other_Format_Commercial;
3303                                     case Generic_Format_Commercial_IfAny : return Other_Format_Commercial_IfAny;
3304                                     case Generic_Format_Version : return Other_Format_Version;
3305                                     case Generic_Format_Profile : return Other_Format_Profile;
3306                                     case Generic_Format_Settings : return Other_Format_Settings;
3307                                     case Generic_Format_AdditionalFeatures : return Other_Format_AdditionalFeatures;
3308                                     case Generic_CodecID : return Other_CodecID;
3309                                     case Generic_CodecID_Info : return Other_CodecID_Info;
3310                                     case Generic_CodecID_Hint : return Other_CodecID_Hint;
3311                                     case Generic_CodecID_Url : return Other_CodecID_Url;
3312                                     case Generic_CodecID_Description : return Other_CodecID_Description;
3313                                     case Generic_Duration : return Other_Duration;
3314                                     case Generic_Duration_String : return Other_Duration_String;
3315                                     case Generic_Duration_String1 : return Other_Duration_String1;
3316                                     case Generic_Duration_String2 : return Other_Duration_String2;
3317                                     case Generic_Duration_String3 : return Other_Duration_String3;
3318                                     case Generic_Duration_String4 : return Other_Duration_String4;
3319                                     case Generic_Duration_String5 : return Other_Duration_String5;
3320                                     case Generic_FrameRate : return Other_FrameRate;
3321                                     case Generic_FrameCount : return Other_FrameCount;
3322                                     case Generic_Delay : return Other_Delay;
3323                                     case Generic_Delay_String : return Other_Delay_String;
3324                                     case Generic_Delay_String1 : return Other_Delay_String1;
3325                                     case Generic_Delay_String2 : return Other_Delay_String2;
3326                                     case Generic_Delay_String3 : return Other_Delay_String3;
3327                                     case Generic_Delay_String4 : return Other_Delay_String4;
3328                                     case Generic_Delay_String5 : return Other_Delay_String5;
3329                                     case Generic_Delay_Settings : return Other_Delay_Settings;
3330                                     case Generic_Delay_DropFrame : return Other_Delay_DropFrame;
3331                                     case Generic_Delay_Source : return Other_Delay_Source;
3332                                     case Generic_Delay_Source_String : return Other_Delay_Source_String;
3333                                     case Generic_Delay_Original : return Other_Delay_Original;
3334                                     case Generic_Delay_Original_String : return Other_Delay_Original_String;
3335                                     case Generic_Delay_Original_String1 : return Other_Delay_Original_String1;
3336                                     case Generic_Delay_Original_String2 : return Other_Delay_Original_String2;
3337                                     case Generic_Delay_Original_String3 : return Other_Delay_Original_String3;
3338                                     case Generic_Delay_Original_String4 : return Other_Delay_Original_String4;
3339                                     case Generic_Delay_Original_Settings : return Other_Delay_Original_Settings;
3340                                     case Generic_Delay_Original_DropFrame : return Other_Delay_Original_DropFrame;
3341                                     case Generic_Delay_Original_Source : return Other_Delay_Original_Source;
3342                                     case Generic_Video_Delay : return Other_Video_Delay;
3343                                     case Generic_Video_Delay_String : return Other_Video_Delay_String;
3344                                     case Generic_Video_Delay_String1 : return Other_Video_Delay_String1;
3345                                     case Generic_Video_Delay_String2 : return Other_Video_Delay_String2;
3346                                     case Generic_Video_Delay_String3 : return Other_Video_Delay_String3;
3347                                     case Generic_Video_Delay_String4 : return Other_Video_Delay_String4;
3348                                     case Generic_Language : return Other_Language;
3349                                     default: return (size_t)-1;
3350                                 }
3351         case Stream_Image :
3352                                 switch (StreamPos)
3353                                 {
3354                                     case Generic_Format : return Image_Format;
3355                                     case Generic_Format_Info : return Image_Format_Info;
3356                                     case Generic_Format_Url : return Image_Format_Url;
3357                                     case Generic_Format_String : return Image_Format_String;
3358                                     case Generic_Format_Commercial : return Image_Format_Commercial;
3359                                     case Generic_Format_Commercial_IfAny : return Image_Format_Commercial_IfAny;
3360                                     case Generic_Format_Version : return Image_Format_Version;
3361                                     case Generic_Format_Profile : return Image_Format_Profile;
3362                                     case Generic_Format_AdditionalFeatures : return Image_Format_AdditionalFeatures;
3363                                     case Generic_InternetMediaType : return Image_InternetMediaType;
3364                                     case Generic_CodecID : return Image_CodecID;
3365                                     case Generic_CodecID_Info : return Image_CodecID_Info;
3366                                     case Generic_CodecID_Hint : return Image_CodecID_Hint;
3367                                     case Generic_CodecID_Url : return Image_CodecID_Url;
3368                                     case Generic_CodecID_Description : return Image_CodecID_Description;
3369                                     case Generic_Codec : return Image_Codec;
3370                                     case Generic_Codec_String : return Image_Codec_String;
3371                                     case Generic_Codec_Info : return Image_Codec_Info;
3372                                     case Generic_Codec_Url : return Image_Codec_Url;
3373                                     case Generic_ColorSpace : return Image_ColorSpace;
3374                                     case Generic_ChromaSubsampling : return Image_ChromaSubsampling;
3375                                     case Generic_Resolution : return Image_Resolution;
3376                                     case Generic_Resolution_String : return Image_Resolution_String;
3377                                     case Generic_BitDepth : return Image_BitDepth;
3378                                     case Generic_BitDepth_String : return Image_BitDepth_String;
3379                                     case Generic_Compression_Mode : return Image_Compression_Mode;
3380                                     case Generic_Compression_Mode_String : return Image_Compression_Mode_String;
3381                                     case Generic_Compression_Ratio : return Image_Compression_Ratio;
3382                                     case Generic_StreamSize : return Image_StreamSize;
3383                                     case Generic_StreamSize_String : return Image_StreamSize_String;
3384                                     case Generic_StreamSize_String1 : return Image_StreamSize_String1;
3385                                     case Generic_StreamSize_String2 : return Image_StreamSize_String2;
3386                                     case Generic_StreamSize_String3 : return Image_StreamSize_String3;
3387                                     case Generic_StreamSize_String4 : return Image_StreamSize_String4;
3388                                     case Generic_StreamSize_String5 : return Image_StreamSize_String5;
3389                                     case Generic_StreamSize_Proportion : return Image_StreamSize_Proportion;
3390                                     case Generic_Language : return Image_Language;
3391                                     default: return (size_t)-1;
3392                                 }
3393         case Stream_Menu :
3394                                 switch (StreamPos)
3395                                 {
3396                                     case Generic_Format : return Menu_Format;
3397                                     case Generic_Format_Info : return Menu_Format_Info;
3398                                     case Generic_Format_Url : return Menu_Format_Url;
3399                                     case Generic_Format_String : return Menu_Format_String;
3400                                     case Generic_Format_Commercial : return Menu_Format_Commercial;
3401                                     case Generic_Format_Commercial_IfAny : return Menu_Format_Commercial_IfAny;
3402                                     case Generic_Format_Version : return Menu_Format_Version;
3403                                     case Generic_Format_Profile : return Menu_Format_Profile;
3404                                     case Generic_Format_Settings : return Menu_Format_Settings;
3405                                     case Generic_CodecID : return Menu_CodecID;
3406                                     case Generic_CodecID_Info : return Menu_CodecID_Info;
3407                                     case Generic_CodecID_Hint : return Menu_CodecID_Hint;
3408                                     case Generic_CodecID_Url : return Menu_CodecID_Url;
3409                                     case Generic_CodecID_Description : return Menu_CodecID_Description;
3410                                     case Generic_Codec : return Menu_Codec;
3411                                     case Generic_Codec_String : return Menu_Codec_String;
3412                                     case Generic_Codec_Info : return Menu_Codec_Info;
3413                                     case Generic_Codec_Url : return Menu_Codec_Url;
3414                                     case Generic_Duration : return Menu_Duration;
3415                                     case Generic_Duration_String : return Menu_Duration_String;
3416                                     case Generic_Duration_String1 : return Menu_Duration_String1;
3417                                     case Generic_Duration_String2 : return Menu_Duration_String2;
3418                                     case Generic_Duration_String3 : return Menu_Duration_String3;
3419                                     case Generic_Duration_String4 : return Menu_Duration_String4;
3420                                     case Generic_Duration_String5 : return Menu_Duration_String5;
3421                                     case Generic_Language : return Menu_Language;
3422                                     case Generic_ServiceName : return Menu_ServiceName;
3423                                     case Generic_ServiceProvider : return Menu_ServiceProvider;
3424                                     default: return (size_t)-1;
3425                                 }
3426         default: return (size_t)-1;
3427     }
3428 }
3429 
3430 } //NameSpace
3431