Skip to content

Commit a6d98cd

Browse files
+ MP4: improve display of operating system and hardware
Focused on Android (Samsung and Google) and iOS but also handle some cameras
1 parent e4c1955 commit a6d98cd

11 files changed

+283
-17
lines changed

Source/MediaInfo/File__Analyse_Automatic.h

+10
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,16 @@ enum general
460460
General_Encoded_Library_Date,
461461
General_Encoded_Library_Settings,
462462
General_Encoded_OperatingSystem,
463+
General_Encoded_OperatingSystem_String,
464+
General_Encoded_OperatingSystem_CompanyName,
465+
General_Encoded_OperatingSystem_Name,
466+
General_Encoded_OperatingSystem_Version,
467+
General_Encoded_Hardware,
468+
General_Encoded_Hardware_String,
469+
General_Encoded_Hardware_CompanyName,
470+
General_Encoded_Hardware_Name,
471+
General_Encoded_Hardware_Model,
472+
General_Encoded_Hardware_Version,
463473
General_Cropped,
464474
General_Dimensions,
465475
General_DotsPerInch,

Source/MediaInfo/File__Analyze.h

+16
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,21 @@ template <class T> inline Ztring Get_Hex_ID(const T& Value)
4040
return ID_String;
4141
}
4242

43+
template <class T> inline T IsAsciiLower(T Value)
44+
{
45+
return ((unsigned)Value - 'a') < 26;
46+
}
47+
48+
template <class T> inline T IsAsciiUpper(T Value)
49+
{
50+
return ((unsigned)Value - 'A') < 26;
51+
}
52+
53+
template <class T> inline T IsAsciiDigit(T Value)
54+
{
55+
return ((unsigned)Value - '0') < 10;
56+
}
57+
4358
struct buffer_data
4459
{
4560
size_t Size;
@@ -879,6 +894,7 @@ public :
879894
#define Info_UTF8(_BYTES, _INFO, _NAME) Ztring _INFO; Get_UTF8 (_BYTES, _INFO, _NAME)
880895
#define Info_UTF16B(_BYTES, _INFO, _NAME) Ztring _INFO; Get_UTF16B(_BYTES, _INFO, _NAME)
881896
#define Info_UTF16L(_BYTES, _INFO, _NAME) Ztring _INFO; Get_UTF16L(_BYTES, _INFO, _NAME)
897+
size_t SizeUpTo0();
882898

883899
//***************************************************************************
884900
// PAscal strings

Source/MediaInfo/File__Analyze_Buffer.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -2023,6 +2023,17 @@ void File__Analyze::Skip_UTF16L(int64u Bytes, const char* Name)
20232023
Element_Offset+=Bytes;
20242024
}
20252025

2026+
//---------------------------------------------------------------------------
2027+
size_t File__Analyze::SizeUpTo0()
2028+
{
2029+
auto Buffer_Begin=Buffer+Buffer_Offset+(size_t)Element_Offset;
2030+
auto Buffer_Current=Buffer_Begin;
2031+
auto Buffer_End=Buffer+Buffer_Offset+(size_t)Element_Size;
2032+
while (Buffer_Current<Buffer_End && *Buffer_Current)
2033+
Buffer_Current++;
2034+
return Buffer_Current-Buffer_Begin;
2035+
}
2036+
20262037
//***************************************************************************
20272038
// Text
20282039
//***************************************************************************

Source/MediaInfo/File__Analyze_Buffer_MinimizeSize.cpp

+22
Original file line numberDiff line numberDiff line change
@@ -1399,6 +1399,17 @@ void File__Analyze::Get_String(int64u Bytes, std::string &Info)
13991399
Element_Offset+=Bytes;
14001400
}
14011401

1402+
//---------------------------------------------------------------------------
1403+
size_t File__Analyze::Get_StringSize()
1404+
{
1405+
auto Buffer_Begin=Buffer+Buffer_Offset+(size_t)Element_Offset;
1406+
auto Buffer_Current=Buffer_Begin;
1407+
auto Buffer_End=Buffer+Buffer_Offset+(size_t)Element_Size;
1408+
while (Buffer_Current<Buffer_End && *Buffer_Current)
1409+
Buffer_Current++;
1410+
return Buffer_Current-Buffer_Begin;
1411+
}
1412+
14021413
//---------------------------------------------------------------------------
14031414
void File__Analyze::Peek_Local(int64u Bytes, Ztring &Info)
14041415
{
@@ -1449,6 +1460,17 @@ void File__Analyze::Get_UTF16L(int64u Bytes, Ztring &Info)
14491460
Element_Offset+=Bytes;
14501461
}
14511462

1463+
//---------------------------------------------------------------------------
1464+
size_t File__Analyze::SizeUpTo0()
1465+
{
1466+
auto Buffer_Begin=Buffer+Buffer_Offset+(size_t)Element_Offset;
1467+
auto Buffer_Current=Buffer_Begin;
1468+
auto Buffer_End=Buffer+Buffer_Offset+(size_t)Element_Size;
1469+
while (Buffer_Current<Buffer_End && *Buffer_Current)
1470+
Buffer_Current++;
1471+
return Buffer_Current-Buffer_Begin;
1472+
}
1473+
14521474
//***************************************************************************
14531475
// Text
14541476
//***************************************************************************

Source/MediaInfo/File__Analyze_MinimizeSize.h

+1
Original file line numberDiff line numberDiff line change
@@ -760,6 +760,7 @@ public :
760760
#define Info_UTF8(_BYTES, _INFO, _NAME) Ztring _INFO; Get_UTF8 (_BYTES, _INFO, _NAME)
761761
#define Info_UTF16B(_BYTES, _INFO, _NAME) Ztring _INFO; Get_UTF16B(_BYTES, _INFO, _NAME)
762762
#define Info_UTF16L(_BYTES, _INFO, _NAME) Ztring _INFO; Get_UTF16L(_BYTES, _INFO, _NAME)
763+
size_t SizeUpTo0();
763764

764765
//***************************************************************************
765766
// Pascal strings

Source/MediaInfo/File__Analyze_Streams_Finish.cpp

+171-7
Original file line numberDiff line numberDiff line change
@@ -991,6 +991,173 @@ void File__Analyze::Streams_Finish_StreamOnly_General(size_t StreamPos)
991991
if (Channels_Total)
992992
Fill(Stream_General, StreamPos, General_Audio_Channels_Total, Channels_Total);
993993
}
994+
995+
//Exceptions (empiric)
996+
{
997+
const auto& Application_Name=Retrieve_Const(Stream_General, StreamPos, General_Encoded_Application_Name);
998+
if (Application_Name.size()>=5 && Application_Name.find(__T(", LLC"))==Application_Name.size()-5)
999+
{
1000+
Fill(Stream_General, 0, General_Encoded_Application_CompanyName, Application_Name.substr(0, Application_Name.size()-5));
1001+
Clear(Stream_General, StreamPos, General_Encoded_Application_Name);
1002+
}
1003+
}
1004+
{
1005+
const auto& Application_Name=Retrieve_Const(Stream_General, StreamPos, General_Encoded_Application_Name);
1006+
if (Application_Name.size()>=5 && Application_Name.rfind(__T("Mac OS X "), 0)==0)
1007+
{
1008+
Fill(Stream_General, 0, General_Encoded_Application_Version, Application_Name.substr(9), true);
1009+
const auto& Application_CompanyName=Retrieve_Const(Stream_General, StreamPos, General_Encoded_Application_CompanyName);
1010+
if (Application_CompanyName.empty())
1011+
Fill(Stream_General, 0, General_Encoded_Application_CompanyName, "Apple");
1012+
Fill(Stream_General, StreamPos, General_Encoded_Application_Name, "Mac OS X", Unlimited, true, true);
1013+
}
1014+
if (Application_Name.size()>=5 && Application_Name.rfind(__T("Sorenson "), 0)==0)
1015+
{
1016+
auto Application_Name_Max=Application_Name.find(__T(" / "));
1017+
if (Application_Name_Max!=(size_t)-1)
1018+
Application_Name_Max-=9;
1019+
Fill(Stream_General, 0, General_Encoded_Application_Name, Application_Name.substr(9, Application_Name_Max), true);
1020+
const auto& Application_CompanyName=Retrieve_Const(Stream_General, StreamPos, General_Encoded_Application_CompanyName);
1021+
if (Application_CompanyName.empty())
1022+
Fill(Stream_General, 0, General_Encoded_Application_CompanyName, "Sorenson");
1023+
}
1024+
}
1025+
{
1026+
const auto& Application_Name=Retrieve_Const(Stream_General, StreamPos, General_Encoded_Application_Name);
1027+
const auto& OperatingSystem_Version=Retrieve_Const(Stream_General, StreamPos, General_Encoded_OperatingSystem_Version);
1028+
const auto& Hardware_Name=Retrieve_Const(Stream_General, StreamPos, General_Encoded_Hardware_Name);
1029+
if (OperatingSystem_Version.empty() && !Application_Name.empty() && Application_Name.find_first_not_of(__T("0123456789."))==string::npos && Hardware_Name.rfind(__T("iPhone "), 0)==0)
1030+
{
1031+
Fill(Stream_General, 0, General_Encoded_OperatingSystem_Version, Application_Name);
1032+
Fill(Stream_General, 0, General_Encoded_OperatingSystem_Name, "iOS", Unlimited, true, true);
1033+
const auto& OperatingSystem_CompanyName=Retrieve_Const(Stream_General, StreamPos, General_Encoded_OperatingSystem_CompanyName);
1034+
if (OperatingSystem_CompanyName.empty())
1035+
Fill(Stream_General, 0, General_Encoded_OperatingSystem_CompanyName, "Apple");
1036+
Clear(Stream_General, StreamPos, General_Encoded_Application_Name);
1037+
}
1038+
}
1039+
{
1040+
const auto& Hardware_CompanyName=Retrieve_Const(Stream_General, StreamPos, General_Encoded_Hardware_CompanyName);
1041+
const auto& Hardware_Name=Retrieve_Const(Stream_General, StreamPos, General_Encoded_Hardware_Name);
1042+
if (Hardware_Name.rfind(Hardware_CompanyName+__T(' '), 0) == 0)
1043+
Fill(Stream_General, StreamPos, General_Encoded_Hardware_Name, Hardware_Name.substr(Hardware_CompanyName.size()+1), true);
1044+
}
1045+
if (Retrieve_Const(Stream_General, StreamPos, General_Encoded_Hardware_Name).empty())
1046+
{
1047+
const auto& Performer=Retrieve_Const(Stream_General, StreamPos, General_Performer);
1048+
const auto& Hardware_CompanyName=Retrieve_Const(Stream_General, StreamPos, General_Encoded_Hardware_CompanyName);
1049+
ZtringList PerformerList;
1050+
PerformerList.Separator_Set(0, __T(" / "));
1051+
PerformerList.Write(Performer);
1052+
set<Ztring> HardwareName_List;
1053+
for (size_t i=0; i<PerformerList.size(); i++)
1054+
{
1055+
const auto& PerformerItem=PerformerList[i];
1056+
if (PerformerItem.size()-Hardware_CompanyName.size()<=16 && PerformerItem.rfind(Hardware_CompanyName+__T(' '), 0)==0)
1057+
{
1058+
HardwareName_List.insert(PerformerItem.substr(Hardware_CompanyName.size() + 1));
1059+
PerformerList.erase(PerformerList.begin()+i);
1060+
continue;
1061+
}
1062+
if (Hardware_CompanyName==__T("Samsung") && PerformerItem.size()<=32 && PerformerItem.rfind(__T("Galaxy "), 0)==0)
1063+
{
1064+
ZtringList Items;
1065+
Items.Separator_Set(0, __T(" "));
1066+
Items.Write(PerformerItem);
1067+
if (Items.size()<6)
1068+
{
1069+
auto IsLikelyName=false;
1070+
auto LastHasOnlyDigits=false;
1071+
for (const auto& Item : Items)
1072+
{
1073+
size_t HasUpper=0;
1074+
size_t HasDigit=0;
1075+
for (const auto& Value : Item)
1076+
{
1077+
HasUpper+=IsAsciiUpper(Value);
1078+
HasDigit+=IsAsciiDigit(Value);
1079+
}
1080+
LastHasOnlyDigits=HasDigit==Item.size();
1081+
if (Item.size()==1 || HasUpper>=2 || (HasDigit && HasDigit<Item.size()))
1082+
IsLikelyName=true;
1083+
}
1084+
if (IsLikelyName || LastHasOnlyDigits)
1085+
{
1086+
HardwareName_List.insert(PerformerItem);
1087+
PerformerList.erase(PerformerList.begin()+i);
1088+
continue;
1089+
}
1090+
}
1091+
}
1092+
}
1093+
if (HardwareName_List.size()==1)
1094+
{
1095+
//Performer is likely the actual performer
1096+
Fill(Stream_General, StreamPos, General_Encoded_Hardware_Name, *HardwareName_List.begin());
1097+
Fill(Stream_General, StreamPos, General_Performer, PerformerList.Read(), true);
1098+
}
1099+
}
1100+
{
1101+
const auto& Name=Retrieve_Const(Stream_General, StreamPos, General_Encoded_Hardware_Name);
1102+
const auto& Model=Retrieve_Const(Stream_General, StreamPos, General_Encoded_Hardware_Model);
1103+
if (Name==Model)
1104+
{
1105+
//Name is actually the model (technical name), keeping only model
1106+
Clear(Stream_General, StreamPos, General_Encoded_Hardware_Name);
1107+
}
1108+
}
1109+
1110+
//OperatingSystem
1111+
if (Retrieve_Const(Stream_General, StreamPos, General_Encoded_OperatingSystem_String).empty())
1112+
{
1113+
//Filling
1114+
const auto& CompanyName=Retrieve_Const(Stream_General, StreamPos, General_Encoded_OperatingSystem_CompanyName);
1115+
const auto& Name=Retrieve_Const(Stream_General, StreamPos, General_Encoded_OperatingSystem_Name);
1116+
const auto& Version=Retrieve_Const(Stream_General, StreamPos, General_Encoded_OperatingSystem_Version);
1117+
Ztring OperatingSystem=CompanyName;
1118+
if (!Name.empty())
1119+
{
1120+
if (!OperatingSystem.empty())
1121+
OperatingSystem+=' ';
1122+
OperatingSystem+=Name;
1123+
if (!Version.empty())
1124+
{
1125+
OperatingSystem+=' ';
1126+
OperatingSystem+=Version;
1127+
}
1128+
}
1129+
Fill(Stream_General, StreamPos, General_Encoded_OperatingSystem_String, OperatingSystem);
1130+
}
1131+
1132+
//Hardware
1133+
if (Retrieve_Const(Stream_General, StreamPos, General_Encoded_Hardware_String).empty())
1134+
{
1135+
//Filling
1136+
const auto& CompanyName=Retrieve_Const(Stream_General, StreamPos, General_Encoded_Hardware_CompanyName);
1137+
const auto& Name=Retrieve_Const(Stream_General, StreamPos, General_Encoded_Hardware_Name);
1138+
const auto& Model=Retrieve_Const(Stream_General, StreamPos, General_Encoded_Hardware_Model);
1139+
const auto& Version=Retrieve_Const(Stream_General, StreamPos, General_Encoded_Hardware_Version);
1140+
Ztring Hardware=CompanyName;
1141+
if (!Name.empty())
1142+
{
1143+
if (!Hardware.empty())
1144+
Hardware+=' ';
1145+
Hardware+=Name;
1146+
}
1147+
if (!Model.empty())
1148+
{
1149+
if (!Hardware.empty())
1150+
Hardware+=' ';
1151+
if (!Name.empty())
1152+
Hardware+='(';
1153+
Hardware+=Model;
1154+
if (!Name.empty())
1155+
Hardware+=')';
1156+
}
1157+
if (!Hardware.empty() && !Version.empty())
1158+
Hardware+=Version;
1159+
Fill(Stream_General, StreamPos, General_Encoded_Hardware_String, Hardware);
1160+
}
9941161
}
9951162

9961163
//---------------------------------------------------------------------------
@@ -2149,14 +2316,11 @@ void File__Analyze::Streams_Finish_HumanReadable_PerStream(stream_t StreamKind,
21492316
Ztring Name=Retrieve(StreamKind, StreamPos, "Encoded_Application_Name");
21502317
Ztring Version=Retrieve(StreamKind, StreamPos, "Encoded_Application_Version");
21512318
Ztring Date=Retrieve(StreamKind, StreamPos, "Encoded_Application_Date");
2152-
if (!Name.empty())
2319+
if (!CompanyName.empty() || !Name.empty())
21532320
{
2154-
Ztring String;
2155-
if (!CompanyName.empty())
2156-
{
2157-
String+=CompanyName;
2158-
String+=__T(" ");
2159-
}
2321+
Ztring String=CompanyName;
2322+
if (!CompanyName.empty() && !Name.empty())
2323+
String+=' ';
21602324
String+=Name;
21612325
if (!Version.empty())
21622326
{

Source/MediaInfo/MediaInfo_Config_Automatic.cpp

+12-2
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,6 @@ void MediaInfo_Config_DefaultLanguage (Translation &Info)
215215
"Alignment_Split;Split across interleaves\n"
216216
"All;All\n"
217217
"AlternateGroup;Alternate group\n"
218-
"Android_Version;Android version\n"
219218
"Archival_Location;Archival location\n"
220219
"Arranger;Arranger\n"
221220
"ArtDirector;ArtDirector\n"
@@ -412,8 +411,10 @@ void MediaInfo_Config_DefaultLanguage (Translation &Info)
412411
"EMail;E-Mail\n"
413412
"Encoded_Application;Writing application\n"
414413
"Encoded_Date;Encoded date\n"
414+
"Encoded_Hardware;Writing hardware\n"
415415
"Encoded_Library;Writing library\n"
416416
"Encoded_Library_Settings;Encoding settings\n"
417+
"Encoded_OperatingSystem;Writing operating system\n"
417418
"Encoded_Original;Original support\n"
418419
"EncodedBy;Encoded by\n"
419420
"EPG_Positions;EPG positions (internal)\n"
@@ -1169,7 +1170,6 @@ void MediaInfo_Config_DefaultLanguage (Translation &Info)
11691170
"SamplesPerFrame;Samples per frame\n"
11701171
"SamplingCount;Samples count\n"
11711172
"SamplingRate;Sampling rate\n"
1172-
"Samsung_Model_Number;Samsung model number\n"
11731173
"Save;Save\n"
11741174
"ScanOrder;Scan order\n"
11751175
"ScanOrder_Original;Original scan order\n"
@@ -4600,6 +4600,16 @@ void MediaInfo_Config_General (ZtringListList &Info)
46004600
"Encoded_Library_Date;;;N YTY\n"
46014601
"Encoded_Library_Settings;;;Y YTY\n"
46024602
"Encoded_OperatingSystem;;;N YTY\n"
4603+
"Encoded_OperatingSystem/String;;;Y NT\n"
4604+
"Encoded_OperatingSystem_CompanyName;;;N YTY\n"
4605+
"Encoded_OperatingSystem_Name;;;N YTY\n"
4606+
"Encoded_OperatingSystem_Version;;;N YTY\n"
4607+
"Encoded_Hardware;;;N YTY\n"
4608+
"Encoded_Hardware/String;;;Y NT\n"
4609+
"Encoded_Hardware_CompanyName;;;N YTY\n"
4610+
"Encoded_Hardware_Name;;;N YTY\n"
4611+
"Encoded_Hardware_Model;;;N YTY\n"
4612+
"Encoded_Hardware_Version;;;N YTY\n"
46034613
"Cropped;;;Y YTY\n"
46044614
"Dimensions;;;Y YTY\n"
46054615
"DotsPerInch;;;Y YTY\n"

Source/MediaInfo/Multiple/File_Mpeg4_Elements.cpp

+24-2
Original file line numberDiff line numberDiff line change
@@ -3985,14 +3985,30 @@ void File_Mpeg4::moov_meta_ilst_xxxx_data()
39853985
Fill(Stream_General, 0, General_Comment, Value, true);
39863986
else if (Parameter=="com.apple.quicktime.description")
39873987
Fill(Stream_General, 0, General_Description, Value, true);
3988+
else if (Parameter == "com.apple.quicktime.creationdate")
3989+
Fill(Stream_General, 0, General_Recorded_Date, Value);
3990+
else if (Parameter == "com.apple.quicktime.make")
3991+
Fill(Stream_General, 0, General_Encoded_Hardware_CompanyName, Value);
3992+
else if (Parameter == "com.apple.quicktime.model")
3993+
Fill(Stream_General, 0, General_Encoded_Hardware_Name, Value);
3994+
else if (Parameter == "com.apple.quicktime.software")
3995+
Fill(Stream_General, 0, General_Encoded_Application_Name, Value);
39883996
else if (Parameter=="com.apple.finalcutstudio.media.uuid")
39893997
Fill(Stream_General, 0, "Media/UUID", Value);
39903998
else if (Parameter=="com.apple.finalcutstudio.media.history.uuid")
39913999
Fill(Stream_General, 0, "Media/History/UUID", Value);
39924000
else if (Parameter=="com.android.capture.fps")
39934001
FrameRate_Real=Value;
4002+
else if (Parameter=="com.android.manufacturer")
4003+
Fill(Stream_General, 0, General_Encoded_Hardware_CompanyName, Value);
4004+
else if (Parameter=="com.android.model")
4005+
Fill(Stream_General, 0, General_Encoded_Hardware_Name, Value);
39944006
else if (Parameter=="com.android.version")
3995-
Fill(Stream_General, 0, "Android_Version", Value);
4007+
{
4008+
Fill(Stream_General, 0, General_Encoded_OperatingSystem_CompanyName, "Google");
4009+
Fill(Stream_General, 0, General_Encoded_OperatingSystem_Name, "Android");
4010+
Fill(Stream_General, 0, General_Encoded_OperatingSystem_Version, Value);
4011+
}
39964012
else if (Parameter=="com.universaladid.idregistry")
39974013
{
39984014
Fill(Stream_General, 0, "UniversalAdID_Registry", Value);
@@ -4020,6 +4036,11 @@ void File_Mpeg4::moov_meta_ilst_xxxx_data()
40204036
if (i!=string::npos)
40214037
DisplayAspectRatio.From_Number(Ztring(DisplayAspectRatio.substr(0, i)).To_float64()/Ztring(DisplayAspectRatio.substr(i+1)).To_float64(), 3);
40224038
}
4039+
else if (Parameter=="Encoded_With")
4040+
{
4041+
if (Value!=Retrieve_Const(Stream_General, 0, General_Encoded_Application_Name))
4042+
Fill(Stream_General, 0, General_Encoded_Application_Name, Value);
4043+
}
40234044
else if (!Parameter.empty())
40244045
Fill(Stream_General, 0, Parameter.c_str(), Value, true);
40254046
FILLING_END();
@@ -9850,7 +9871,8 @@ void File_Mpeg4::moov_udta_smta_mdln()
98509871

98519872
//Filling
98529873
FILLING_BEGIN();
9853-
Fill(Stream_General, 0, "Samsung_Model_Number", SamsungModelNumber);
9874+
Fill(Stream_General, 0, General_Encoded_Hardware_CompanyName, "Samsung");
9875+
Fill(Stream_General, 0, General_Encoded_Hardware_Model, SamsungModelNumber);
98549876
FILLING_END();
98559877
}
98569878

0 commit comments

Comments
 (0)