/* Copyright (c) MediaArea.net SARL. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license that can
* be found in the License.html file in the root of the source tree.
*/
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Main part
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//---------------------------------------------------------------------------
// Pre-compilation
#include "MediaInfo/PreComp.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
#include "MediaInfo/Setup.h"
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
#ifdef MEDIAINFO_WM_YES
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
#include "MediaInfo/Multiple/File_Wm.h"
#if defined(MEDIAINFO_MPEGPS_YES)
#include "MediaInfo/Multiple/File_MpegPs.h"
#endif
#if MEDIAINFO_EVENTS
#include "MediaInfo/MediaInfo_Events.h"
#endif //MEDIAINFO_EVENTS
#include "ZenLib/Utils.h"
using namespace ZenLib;
//---------------------------------------------------------------------------
namespace MediaInfoLib
{
//***************************************************************************
// Format
//***************************************************************************
//---------------------------------------------------------------------------
File_Wm::File_Wm()
:File__Analyze()
{
//Configuration
ParserName="Wm";
#if MEDIAINFO_EVENTS
ParserIDs[0]=MediaInfo_Parser_Wm;
StreamIDs_Width[0]=2;
#endif //MEDIAINFO_EVENTS
#if MEDIAINFO_DEMUX
Demux_Level=2; //Container
#endif //MEDIAINFO_DEMUX
DataMustAlwaysBeComplete=false;
//Stream
Packet_Count=0;
MaximumDataPacketSize=(int32u)-1;
Header_ExtendedContentDescription_AspectRatioX=0;
Header_ExtendedContentDescription_AspectRatioY=0;
SizeOfMediaObject_BytesAlreadyParsed=0;
FileProperties_Preroll=0;
Codec_Description_Count=0;
Stream_Number=0;
Data_Parse_Padding=0;
NumberPayloads=1;
NumberPayloads_Pos=0;
Data_Parse_Begin=true;
IsDvrMs=false;
}
//***************************************************************************
// Streams management
//***************************************************************************
//---------------------------------------------------------------------------
void File_Wm::Streams_Finish()
{
//Encryption management
/*const Ztring& Encryption=Retrieve(Stream_General, 0, General_Encryption);
if (!Encryption.empty())
{
for (size_t StreamKind=Stream_General+1; StreamKind<Stream_Max; StreamKind++)
for (size_t Pos=0; Pos<(*Stream[StreamKind]).size(); Pos++)
Fill ((stream_t)StreamKind, 0, "Encryption", Encryption);
}
Fill("BitRate", CurrentBitRate[StreamNumber]);
*/
std::map<int16u, stream>::iterator Temp=Stream.begin();
while (Temp!=Stream.end())
{
for (std::map<std::string, ZenLib::Ztring>::iterator Info_Temp=Temp->second.Info.begin(); Info_Temp!=Temp->second.Info.end(); ++Info_Temp)
Fill(Temp->second.StreamKind, Temp->second.StreamPos, Info_Temp->first.c_str(), Info_Temp->second, true);
//Codec Info
for (size_t Pos=0; Pos<CodecInfos.size(); Pos++)
{
if ((CodecInfos[Pos].Type==1 && Temp->second.StreamKind==Stream_Video)
|| (CodecInfos[Pos].Type==2 && Temp->second.StreamKind==Stream_Audio))
{
Fill(Temp->second.StreamKind, Temp->second.StreamPos, "CodecID_Description", CodecInfos[Pos].Info, true);
Fill(Temp->second.StreamKind, Temp->second.StreamPos, "Codec_Description", CodecInfos[Pos].Info, true);
}
}
if (Temp->second.StreamKind==Stream_Video)
{
//Some tests about the frame rate
int32u PresentationTime_Previous=(int32u)-1;
size_t TimeDiffs_Sum=0;
std::map<int32u, size_t> TimeDiffs;
for (std::set<int32u>::iterator PresentationTime=Temp->second.PresentationTimes.begin(); PresentationTime!=Temp->second.PresentationTimes.end(); ++PresentationTime)
{
if (PresentationTime_Previous!=(int32u)-1)
TimeDiffs[*PresentationTime-PresentationTime_Previous]++;
PresentationTime_Previous=*PresentationTime;
}
for (std::map<int32u, size_t>::iterator TimeDiff=TimeDiffs.begin(); TimeDiff!=TimeDiffs.end();)
{
if (TimeDiff->second<=2)
TimeDiffs.erase(TimeDiff++);
else
{
TimeDiffs_Sum+=TimeDiff->second;
++TimeDiff;
}
}
if (TimeDiffs.empty()
|| (TimeDiffs.size()==1 && TimeDiffs_Sum<16)
|| (TimeDiffs.size()==2 && TimeDiffs_Sum<32)
|| TimeDiffs.begin()->first==1)
{
if (Temp->second.AverageTimePerFrame>0)
Fill(Stream_Video, Temp->second.StreamPos, Video_FrameRate, ((float)10000000)/(Temp->second.AverageTimePerFrame*(Temp->second.Parser && Temp->second.Parser->Retrieve(Stream_Video, 0, Video_ScanType)==__T("Interlaced")?2:1)), 3, true);
}
else if (TimeDiffs.size()==1)
{
Fill(Stream_Video, Temp->second.StreamPos, Video_FrameRate, 1000/((float64)TimeDiffs.begin()->first), 3, true);
if (Temp->second.AverageTimePerFrame>0)
Fill(Stream_Video, Temp->second.StreamPos, Video_FrameRate_Nominal, ((float)10000000)/(Temp->second.AverageTimePerFrame*(Temp->second.Parser && Temp->second.Parser->Retrieve(Stream_Video, 0, Video_ScanType)==__T("Interlaced")?2:1)), 3, true);
}
else if (TimeDiffs.size()==2)
{
std::map<int32u, size_t>::iterator PresentationTime_Delta_Most=TimeDiffs.begin();
float64 PresentationTime_Deltas_1_Value=(float64)PresentationTime_Delta_Most->first;
float64 PresentationTime_Deltas_1_Count=(float64)PresentationTime_Delta_Most->second;
++PresentationTime_Delta_Most;
float64 PresentationTime_Deltas_2_Value=(float64)PresentationTime_Delta_Most->first;
float64 PresentationTime_Deltas_2_Count=(float64)PresentationTime_Delta_Most->second;
float64 FrameRate_Real=1000/(((PresentationTime_Deltas_1_Value*PresentationTime_Deltas_1_Count)+(PresentationTime_Deltas_2_Value*PresentationTime_Deltas_2_Count))/(PresentationTime_Deltas_1_Count+PresentationTime_Deltas_2_Count));
Fill(Temp->second.StreamKind, Temp->second.StreamPos, Video_FrameRate, FrameRate_Real, 3, true);
if (Temp->second.AverageTimePerFrame>0)
Fill(Stream_Video, Temp->second.StreamPos, Video_FrameRate_Nominal, ((float)10000000)/(Temp->second.AverageTimePerFrame*(Temp->second.Parser && Temp->second.Parser->Retrieve(Stream_Video, 0, Video_ScanType)==__T("Interlaced")?2:1)), 3, true);
}
else
{
Fill(Stream_Video, Temp->second.StreamPos, Video_FrameRate_Mode, "VFR");
if (Temp->second.AverageTimePerFrame>0)
Fill(Stream_Video, Temp->second.StreamPos, Video_FrameRate_Nominal, ((float)10000000)/(Temp->second.AverageTimePerFrame*(Temp->second.Parser && Temp->second.Parser->Retrieve(Stream_Video, 0, Video_ScanType)==__T("Interlaced")?2:1)), 3, true);
}
}
if (Temp->second.AverageBitRate>0)
Fill(Temp->second.StreamKind, Temp->second.StreamPos, "BitRate", Temp->second.AverageBitRate, 10, true);
if (Temp->second.LanguageID!=(int16u)-1 && Temp->second.LanguageID<(int16u)Languages.size())
Fill(Temp->second.StreamKind, Temp->second.StreamPos, "Language", Languages[Temp->second.LanguageID]);
else if (!Language_ForAll.empty())
Fill(Temp->second.StreamKind, Temp->second.StreamPos, "Language", Language_ForAll);
if (Temp->second.Parser)
{
if (Temp->second.StreamKind==Stream_Max)
if (Temp->second.Parser->Count_Get(Stream_Audio))
{
Stream_Prepare(Stream_Audio);
Temp->second.StreamKind=StreamKind_Last;
Temp->second.StreamPos=StreamPos_Last;
}
Ztring Format_Profile;
if (Temp->second.StreamKind==Stream_Video)
Format_Profile=Retrieve(Stream_Video, Temp->second.StreamPos, Video_Format_Profile);
Finish(Temp->second.Parser);
if (Temp->second.Parser->Get(Stream_Video, 0, Video_Format)==__T("MPEG Video"))
{
//Width/Height are junk
Clear(Stream_Video, Temp->second.StreamPos, Video_Width);
Clear(Stream_Video, Temp->second.StreamPos, Video_Height);
Clear(Stream_Video, Temp->second.StreamPos, Video_PixelAspectRatio);
Clear(Stream_Video, Temp->second.StreamPos, Video_DisplayAspectRatio);
}
//Delay (in case of MPEG-PS)
if (Temp->second.TimeCode_First!=(int64u)-1)
{
Fill(Temp->second.StreamKind, Temp->second.StreamPos, Fill_Parameter(Temp->second.StreamKind, Generic_Delay), Temp->second.TimeCode_First, 10);
Fill(Temp->second.StreamKind, Temp->second.StreamPos, Fill_Parameter(Temp->second.StreamKind, Generic_Delay_Source), "Container");
}
Merge(*Temp->second.Parser, Temp->second.StreamKind, 0, Temp->second.StreamPos);
if (!Format_Profile.empty() && Format_Profile.find(Retrieve(Stream_Video, Temp->second.StreamPos, Video_Format_Profile))==0)
Fill(Stream_Video, Temp->second.StreamPos, Video_Format_Profile, Format_Profile, true);
}
++Temp;
}
if (Count_Get(Stream_Video)==0 && Count_Get(Stream_Image)==0)
Fill(Stream_General, 0, General_InternetMediaType, "audio/x-ms-wma", Unlimited, true, true);
//Purge what is not needed anymore
if (!File_Name.empty()) //Only if this is not a buffer, with buffer we can have more data
Stream.clear();
}
//***************************************************************************
// Buffer
//***************************************************************************
//---------------------------------------------------------------------------
void File_Wm::Header_Parse()
{
if (!MustUseAlternativeParser)
{
//Parsing
int128u Name;
int64u Size;
Get_GUID(Name, "Name");
Get_L8 (Size, "Size");
//Filling
Header_Fill_Code(Name.hi, Ztring().From_GUID(Name));
Header_Fill_Size(Size);
}
else
{
Header_Fill_Code(0, "Packet");
Header_Fill_Size(MaximumDataPacketSize);
}
}
//***************************************************************************
// C++
//***************************************************************************
} //NameSpace
#endif //MEDIAINFO_WM_YES
↑ V730 Not all members of a class are initialized inside the constructor. Consider inspecting: Data_Parse_MultiplePayloads, Data_Parse_CompressedPayload, Streams_Count, Header_StreamProperties_StreamOrder, Data_AfterTheDataChunk, ReplicatedDataLengthType, ...
↑ V783 Dereferencing of the invalid iterator 'PresentationTime_Delta_Most' might take place.
↑ V807 Decreased performance. Consider creating a reference to avoid using the 'Temp->second' expression repeatedly.