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