//--------------------------------------------------------------------------- bool File_Dcp::FileHeader_Begin() { XMLDocument document; if (!FileHeader_Begin_XML(document)) return false; { std::string NameSpace; XMLElement* AssetMap=document.FirstChildElement("AssetMap"); if (AssetMap==NULL) { NameSpace="am:"; AssetMap=document.FirstChildElement((NameSpace+"AssetMap").c_str()); } if (AssetMap) { Accept("Dcp"); Fill(Stream_General, 0, General_Format, "DCP"); Fill(Stream_General, 0, General_Format_Version, NameSpace=="am:"?"SMPTE":"Interop"); ReferenceFiles=new File__ReferenceFilesHelper(this, Config); XMLElement* IssueDate=AssetMap->FirstChildElement((NameSpace+"IssueDate").c_str()); if (IssueDate) Fill(Stream_General, 0, General_Encoded_Date, IssueDate->GetText()); XMLElement* Issuer=AssetMap->FirstChildElement((NameSpace+"Issuer").c_str()); if (Issuer) Fill(Stream_General, 0, General_EncodedBy, Issuer->GetText()); XMLElement* Creator=AssetMap->FirstChildElement((NameSpace+"Creator").c_str()); if (Creator) Fill(Stream_General, 0, General_Encoded_Library, Creator->GetText()); XMLElement* AssetList=AssetMap->FirstChildElement((NameSpace+"AssetList").c_str()); if (AssetList) { XMLElement* Asset=AssetList->FirstChildElement((NameSpace+"Asset").c_str()); while (Asset) { XMLElement* ChunkList=Asset->FirstChildElement((NameSpace+"ChunkList").c_str()); if (ChunkList) { XMLElement* Chunk=ChunkList->FirstChildElement((NameSpace+"Chunk").c_str()); if (Chunk) { XMLElement* Path=Chunk->FirstChildElement((NameSpace+"Path").c_str()); if (Path) { File__ReferenceFilesHelper::reference ReferenceFile; ReferenceFile.FileNames.push_back(Path->GetText()); ReferenceFile.StreamID=ReferenceFiles->References.size()+1; ReferenceFiles->References.push_back(ReferenceFile); } } } Asset=Asset->NextSiblingElement(); } } } else { Reject("Dcp"); return false; } } Element_Offset=File_Size; //All should be OK... return true; }
//--------------------------------------------------------------------------- bool File_PropertyList::FileHeader_Begin() { XMLDocument document; if (!FileHeader_Begin_XML(document)) return false; XMLElement* plist=document.FirstChildElement("plist"); if (!plist) { Reject("XMP"); return false; } XMLElement* dict=plist->FirstChildElement("dict"); if (!dict) { Reject("XMP"); return false; } Accept("PropertyList"); string key; for (XMLElement* dict_Item=dict->FirstChildElement(); dict_Item; dict_Item=dict_Item->NextSiblingElement()) { //key if (!strcmp(dict_Item->Value(), "key")) { const char* Text=dict_Item->GetText(); if (Text) key=Text; } //string if (!strcmp(dict_Item->Value(), "string")) { const char* Text=dict_Item->GetText(); if (Text) Fill(Stream_General, 0, PropertyList_key(key), Text); key.clear(); } //string if (!strcmp(dict_Item->Value(), "array")) { for (XMLElement* array_Item=dict_Item->FirstChildElement(); array_Item; array_Item=array_Item->NextSiblingElement()) { //dict if (!strcmp(array_Item->Value(), "dict")) { string key2; for (XMLElement* dict2_Item=array_Item->FirstChildElement(); dict2_Item; dict2_Item=dict2_Item->NextSiblingElement()) { //key if (!strcmp(dict2_Item->Value(), "key")) { const char* Text=dict2_Item->GetText(); if (Text) key2=Text; } //string if (!strcmp(dict2_Item->Value(), "string")) { const char* Text2=dict2_Item->GetText(); if (Text2) Fill(Stream_General, 0, key2=="name"?PropertyList_key(key):((string(PropertyList_key(key))+", "+key2).c_str()), Text2); key2.clear(); } } } } key.clear(); } } Finish(); return true; }
//--------------------------------------------------------------------------- void File_Ttml::Read_Buffer_Continue() { tinyxml2::XMLDocument document; if (!FileHeader_Begin_XML(document)) return; XMLElement* Root=document.FirstChildElement("tt"); if (!Root) { Reject(); return; } if (!Status[IsAccepted]) { Accept(); #if MEDIAINFO_EVENTS MuxingMode=(int8u)-1; if (StreamIDs_Size>=2 && ParserIDs[StreamIDs_Size-2]==MediaInfo_Parser_Mpeg4) MuxingMode=11; //MPEG-4 #endif MEDIAINFO_EVENTS } tinyxml2::XMLElement* div=NULL; #if MEDIAINFO_EVENTS tinyxml2::XMLElement* p=NULL; #endif //MEDIAINFO_EVENTS for (XMLElement* tt_element=Root->FirstChildElement(); tt_element; tt_element=tt_element->NextSiblingElement()) { //body if (!strcmp(tt_element->Value(), "body")) { for (XMLElement* body_element=tt_element->FirstChildElement(); body_element; body_element=body_element->NextSiblingElement()) { //div if (!strcmp(body_element->Value(), "div")) { for (XMLElement* div_element=body_element->FirstChildElement(); div_element; div_element=div_element->NextSiblingElement()) { //p if (!strcmp(div_element->Value(), "p")) { div=body_element; #if MEDIAINFO_EVENTS p=div_element; #endif //MEDIAINFO_EVENTS break; } } if (div) break; } } if (div) break; } } #if MEDIAINFO_DEMUX Demux(Buffer, Buffer_Size, ContentType_MainStream); #endif //MEDIAINFO_DEMUX // Output #if MEDIAINFO_EVENTS for (; p; p=p->NextSiblingElement()) { //p if (!strcmp(p->Value(), "p")) { const char* Attribute; int64u DTS_Begin=(int64u)-1; Attribute=p->Attribute("begin"); if (Attribute) DTS_Begin=Ttml_str2timecode(Attribute); int64u DTS_End=(int64u)-1; Attribute=p->Attribute("end"); if (Attribute) DTS_End=Ttml_str2timecode(Attribute); Ztring Content; if (p->FirstChild()) Content.From_UTF8(p->FirstChild()->Value()); Frame_Count++; } } #endif MEDIAINFO_EVENTS Buffer_Offset=Buffer_Size; }
//--------------------------------------------------------------------------- bool File_DcpCpl::FileHeader_Begin() { XMLDocument document; if (!FileHeader_Begin_XML(document)) return false; bool IsDcp=false, IsImf=false; XMLElement* Root=document.FirstChildElement("CompositionPlaylist"); if (!Root) { Reject("DcpCpl"); return false; } const char* Attribute=Root->Attribute("xmlns"); if (!Attribute) { Reject("DcpCpl"); return false; } if (!strcmp(Attribute, "http://www.digicine.com/PROTO-ASDCP-CPL-20040511#") ||!strcmp(Attribute, "http://www.smpte-ra.org/schemas/429-7/2006/CPL")) IsDcp=true; if (!strcmp(Attribute, "http://www.smpte-ra.org/schemas/2067-3/XXXX") //Some muxers use XXXX instead of year || !strcmp(Attribute, "http://www.smpte-ra.org/schemas/2067-3/2013")) IsImf=true; if (!IsDcp && !IsImf) { Reject("DcpCpl"); return false; } Accept("DcpCpl"); Fill(Stream_General, 0, General_Format, IsDcp?"DCP CPL":"IMF CPL"); Config->File_ID_OnlyRoot_Set(false); ReferenceFiles=new File__ReferenceFilesHelper(this, Config); //Parsing main elements for (XMLElement* CompositionPlaylist_Item=Root->FirstChildElement(); CompositionPlaylist_Item; CompositionPlaylist_Item=CompositionPlaylist_Item->NextSiblingElement()) { //CompositionTimecode if (IsImf && (!strcmp(CompositionPlaylist_Item->Value(), "CompositionTimecode") || !strcmp(CompositionPlaylist_Item->Value(), "cpl:CompositionTimecode"))) { File__ReferenceFilesHelper::reference ReferenceFile; ReferenceFile.StreamKind=Stream_Other; ReferenceFile.Infos["Type"]=__T("Time code"); ReferenceFile.Infos["Format"]=__T("CPL TC"); ReferenceFile.Infos["TimeCode_Striped"]=__T("Yes"); bool IsDropFrame=false; for (XMLElement* CompositionTimecode_Item=CompositionPlaylist_Item->FirstChildElement(); CompositionTimecode_Item; CompositionTimecode_Item=CompositionTimecode_Item->NextSiblingElement()) { //TimecodeDropFrame if (!strcmp(CompositionTimecode_Item->Value(), "TimecodeDropFrame") || !strcmp(CompositionTimecode_Item->Value(), "cpl:TimecodeDropFrame")) { if (strcmp(CompositionTimecode_Item->GetText(), "") && strcmp(CompositionTimecode_Item->GetText(), "0")) IsDropFrame=true; } //TimecodeRate if (!strcmp(CompositionTimecode_Item->Value(), "TimecodeRate") || !strcmp(CompositionTimecode_Item->Value(), "cpl:TimecodeRate")) ReferenceFile.Infos["FrameRate"].From_UTF8(CompositionTimecode_Item->GetText()); //TimecodeStartAddress if (!strcmp(CompositionTimecode_Item->Value(), "TimecodeStartAddress") || !strcmp(CompositionTimecode_Item->Value(), "cpl:TimecodeStartAddress")) ReferenceFile.Infos["TimeCode_FirstFrame"].From_UTF8(CompositionTimecode_Item->GetText()); } //Adaptation if (IsDropFrame) { std::map<string, Ztring>::iterator Info=ReferenceFile.Infos.find("TimeCode_FirstFrame"); if (Info!=ReferenceFile.Infos.end() && Info->second.size()>=11 && Info->second[8]!=__T(';')) Info->second[8]=__T(';'); } ReferenceFile.StreamID=ReferenceFiles->References.size()+1; ReferenceFiles->References.push_back(ReferenceFile); Stream_Prepare(Stream_Other); Fill(Stream_Other, StreamPos_Last, Other_ID, ReferenceFile.StreamID); for (std::map<string, Ztring>::iterator Info=ReferenceFile.Infos.begin(); Info!=ReferenceFile.Infos.end(); ++Info) Fill(Stream_Other, StreamPos_Last, Info->first.c_str(), Info->second); } //ReelList / SegmentList if ((IsDcp && !strcmp(CompositionPlaylist_Item->Value(), "ReelList")) || (IsImf && !strcmp(CompositionPlaylist_Item->Value(), "SegmentList"))) { for (XMLElement* ReelList_Item=CompositionPlaylist_Item->FirstChildElement(); ReelList_Item; ReelList_Item=ReelList_Item->NextSiblingElement()) { //Reel if ((IsDcp && !strcmp(ReelList_Item->Value(), "Reel")) || (IsImf && !strcmp(ReelList_Item->Value(), "Segment"))) { for (XMLElement* Reel_Item=ReelList_Item->FirstChildElement(); Reel_Item; Reel_Item=Reel_Item->NextSiblingElement()) { //AssetList if ((IsDcp && !strcmp(Reel_Item->Value(), "AssetList")) || (IsImf && !strcmp(Reel_Item->Value(), "SequenceList"))) { for (XMLElement* AssetList_Item=Reel_Item->FirstChildElement(); AssetList_Item; AssetList_Item=AssetList_Item->NextSiblingElement()) { //File //if ((IsDcp && (!strcmp(AssetList_Item->Value(), "MainPicture") || !strcmp(AssetList_Item->Value(), "MainSound"))) // || (IsImf && (!strcmp(AssetList_Item->Value(), "cc:MainImageSequence") || !strcmp(AssetList_Item->Value(), "cc:MainImage")))) { File__ReferenceFilesHelper::reference ReferenceFile; Ztring Asset_Id; if ((IsDcp && !strcmp(AssetList_Item->Value(), "MainPicture")) || (IsImf && !strcmp(AssetList_Item->Value(), "cc:MainImageSequence"))) ReferenceFile.StreamKind=Stream_Video; if ((IsDcp && !strcmp(AssetList_Item->Value(), "MainSound")) || (IsImf && !strcmp(AssetList_Item->Value(), "cc:MainAudioSequence"))) ReferenceFile.StreamKind=Stream_Audio; for (XMLElement* File_Item=AssetList_Item->FirstChildElement(); File_Item; File_Item=File_Item->NextSiblingElement()) { //Id if (!strcmp(File_Item->Value(), "Id") && Asset_Id.empty()) Asset_Id.From_UTF8(File_Item->GetText()); //ResourceList if (IsImf && !strcmp(File_Item->Value(), "ResourceList")) { for (XMLElement* ResourceList_Item=File_Item->FirstChildElement(); ResourceList_Item; ResourceList_Item=ResourceList_Item->NextSiblingElement()) { //Resource if (!strcmp(ResourceList_Item->Value(), "Resource")) { Ztring Resource_Id; File__ReferenceFilesHelper::reference::completeduration Resource; for (XMLElement* Resource_Item=ResourceList_Item->FirstChildElement(); Resource_Item; Resource_Item=Resource_Item->NextSiblingElement()) { //EditRate if (!strcmp(Resource_Item->Value(), "EditRate")) { const char* EditRate=Resource_Item->GetText(); Resource.IgnoreFramesRate=atof(EditRate); const char* EditRate2=strchr(EditRate, ' '); if (EditRate2!=NULL) { float64 EditRate2f=atof(EditRate2); if (EditRate2f) Resource.IgnoreFramesRate/=EditRate2f; } } //EntryPoint if (!strcmp(Resource_Item->Value(), "EntryPoint")) { Resource.IgnoreFramesBefore=atoi(Resource_Item->GetText()); if (Resource.IgnoreFramesAfter!=(int64u)-1) Resource.IgnoreFramesAfter+=Resource.IgnoreFramesBefore; } //Id if (!strcmp(File_Item->Value(), "Id") && Resource_Id.empty()) Resource_Id.From_UTF8(File_Item->GetText()); //SourceDuration if (!strcmp(Resource_Item->Value(), "SourceDuration")) Resource.IgnoreFramesAfter=Resource.IgnoreFramesBefore+atoi(Resource_Item->GetText()); //TrackFileId if (!strcmp(Resource_Item->Value(), "TrackFileId")) Resource.FileName.From_UTF8(Resource_Item->GetText()); } if (Resource.FileName.empty()) Resource.FileName=Resource_Id; ReferenceFile.CompleteDuration.push_back(Resource); } } } } if (ReferenceFile.CompleteDuration.empty()) { File__ReferenceFilesHelper::reference::completeduration Resource; Resource.FileName=Asset_Id; ReferenceFile.CompleteDuration.push_back(Resource); } ReferenceFile.StreamID=ReferenceFiles->References.size()+1; ReferenceFiles->References.push_back(ReferenceFile); } } } } } } } } Element_Offset=File_Size; //Getting files names FileName Directory(File_Name); Ztring Assetmap_FileName=Directory.Path_Get()+PathSeparator+__T("ASSETMAP.xml"); bool IsOk=false; if (File::Exists(Assetmap_FileName)) IsOk=true; else { Assetmap_FileName.resize(Assetmap_FileName.size()-4); //Old fashion, without ".xml" if (File::Exists(Assetmap_FileName)) IsOk=true; } if (IsOk) { MediaInfo_Internal MI; MI.Option(__T("File_KeepInfo"), __T("1")); Ztring ParseSpeed_Save=MI.Option(__T("ParseSpeed_Get"), __T("")); Ztring Demux_Save=MI.Option(__T("Demux_Get"), __T("")); MI.Option(__T("ParseSpeed"), __T("0")); MI.Option(__T("Demux"), Ztring()); MI.Option(__T("File_IsReferenced"), __T("1")); size_t MiOpenResult=MI.Open(Assetmap_FileName); MI.Option(__T("ParseSpeed"), ParseSpeed_Save); //This is a global value, need to reset it. TODO: local value MI.Option(__T("Demux"), Demux_Save); //This is a global value, need to reset it. TODO: local value if (MiOpenResult && (MI.Get(Stream_General, 0, General_Format)==__T("DCP AM") || MI.Get(Stream_General, 0, General_Format)==__T("IMF AM"))) { MergeFromAm(((File_DcpAm*)MI.Info)->Streams); } } ReferenceFiles->FilesForStorage=true; //All should be OK... return true; }
//--------------------------------------------------------------------------- bool File_SequenceInfo::FileHeader_Begin() { XMLDocument document; if (!FileHeader_Begin_XML(document)) return false; { XMLElement* Root=document.FirstChildElement("SEQUENCEINFO"); if (Root) { Accept("SequenceInfo"); Fill(Stream_General, 0, General_Format, "SequenceInfo"); ReferenceFiles=new File__ReferenceFilesHelper(this, Config); sequence* Sequence=new sequence; Sequence->StreamKind=Stream_Video; FileName FN(File_Name); Ztring Base=FN.Path_Get(); size_t Pos=Base.rfind(PathSeparator); if (Pos!=string::npos) { Ztring ToAdd=Base.substr(Pos, string::npos); Ztring DirectoryBase=Base; DirectoryBase+=ToAdd; DirectoryBase+=__T('_'); size_t DirNumberCount=1; Ztring Directory=DirectoryBase; for (; DirNumberCount<9; DirNumberCount++) { Directory+=__T('0'); if (Dir::Exists(Directory)) break; } if (DirNumberCount<9) { int32u DirNumber=0; do { Ztring Number=Ztring::ToZtring(DirNumber); if (Number.size()<DirNumberCount) Number.insert(0, DirNumberCount-Number.size(), __T('0')); Directory=DirectoryBase; Directory+=Number; if (!Dir::Exists(Directory)) break; Ztring FileBase=Directory; FileBase+=ToAdd; FileBase+=__T('_'); FileBase+=__T('.'); size_t FileNumberCount=1; Ztring FullFile=FileBase; Ztring Extension; for (; FileNumberCount<10; FileNumberCount++) { FullFile.insert(FullFile.begin()+FullFile.size()-Extension.size()-1, __T('0')); if (Extension.empty()) { ZtringList List=Dir::GetAllFileNames(FullFile+__T('*')); if (List.size()>=2) { FileNumberCount=(size_t)-1; //Problem, which one to choose? break; } else if (List.size()==1) { FileName Temp(List[0]); Extension=Temp.Extension_Get(); FileBase+=Extension; FullFile=FileBase; break; } } else if (File::Exists(FullFile)) break; } bool FromZero=true; if (FileNumberCount>=9) { //Trying with consecutive file numbers betweens dirs Number=Ztring::ToZtring(Sequence->FileNames.size()); FullFile=FileBase; FullFile.insert(FullFile.size()-Extension.size()-1, Number); FileNumberCount=Number.size(); if (!File::Exists(FullFile)) { FileNumberCount++; for (; FileNumberCount<10; FileNumberCount++) { FullFile.insert(FullFile.begin()+FullFile.size()-Extension.size()-Number.size()-1, __T('0')); if (File::Exists(FullFile)) { FromZero=false; break; } } } else FromZero=false; } if (FileNumberCount<9) { size_t FileNumber=FromZero?0:Sequence->FileNames.size(); do { Number=Ztring::ToZtring(FileNumber); if (Number.size()<FileNumberCount) Number.insert(0, FileNumberCount-Number.size(), __T('0')); FullFile=FileBase; FullFile.insert(FullFile.size()-Extension.size()-1, Number); if (!File::Exists(FullFile)) break; Sequence->AddFileName(FullFile); FileNumber++; } while (FileNumber<1000000000); } DirNumber++; } while (DirNumber<1000000000); ReferenceFiles->AddSequence(Sequence); } } } else { Reject("SequenceInfo"); return false; } } Element_Offset=File_Size; //All should be OK... return true; }
//--------------------------------------------------------------------------- bool File_Xdcam_Clip::FileHeader_Begin() { XMLDocument document; if (!FileHeader_Begin_XML(document)) return false; { XMLElement* Root=document.FirstChildElement("NonRealTimeMeta"); if (Root) { Accept("Xdcam_Clip"); Fill(Stream_General, 0, General_Format, "XDCAM Clip"); XMLElement* Element; //CreationDate Element=Root->FirstChildElement("CreationDate"); if (Element) Fill(Stream_General, 0, General_Recorded_Date, Element->Attribute("value")); //LastUpdate Element=Root->FirstChildElement("LastUpdate"); if (Element) Fill(Stream_General, 0, General_Tagged_Date, Element->Attribute("value")); //Duration Ztring Duration, EditUnit; Element=Root->FirstChildElement("Duration"); if (Element) Duration=Element->Attribute("value"); Element=Root->FirstChildElement("LtcChangeTable"); if (Element) EditUnit=Element->Attribute("tcFps"); int64u Duration_Frames=Duration.To_int64u(); int64u EditUnit_Denominator=EditUnit.To_int64u(); if (Duration_Frames && EditUnit_Denominator) Fill(Stream_General, 0, General_Duration, ((float32)Duration_Frames)*1000/EditUnit_Denominator, 0); int64u File_Size_Total=File_Size; #if defined(MEDIAINFO_MXF_YES) if (File_Name.size()>12 && File_Name[File_Name.size()-7]==__T('M') && File_Name[File_Name.size()-6]==__T('0') && File_Name[File_Name.size()-5]==__T('1') && File_Name[File_Name.size()-4]==__T('.') && File_Name[File_Name.size()-3]==__T('X') && File_Name[File_Name.size()-2]==__T('M') && File_Name[File_Name.size()-1]==__T('L')) { Ztring file=File_Name.substr(File_Name.size()-12, 5); Ztring MXF_File=File_Name; MXF_File.resize(MXF_File.size()-12); MXF_File+=file; if (File::Exists(MXF_File+__T(".MXF"))) MXF_File+=__T(".MXF"); if (File::Exists(MXF_File+__T(".MP4"))) MXF_File+=__T(".MP4"); //int8u ReadByHuman=Ztring(MediaInfo::Option_Static(__T("ReadByHuman_Get"))).To_int8u(); //MediaInfo::Option_Static(__T("ReadByHuman"), __T("0")); MediaInfo_Internal MI; if (MI.Open(MXF_File)) { //MediaInfo::Option_Static(__T("ReadByHuman"), ReadByHuman?__T("1"):__T("0")); Merge(MI); Fill(Stream_Video, StreamPos_Last, "Source", MXF_File); File_Size_Total+=Ztring(MI.Get(Stream_General, 0, General_FileSize)).To_int64u(); //Commercial names Fill(Stream_General, 0, General_Format_Commercial_IfAny, MI.Get(Stream_General, 0, General_Format_Commercial_IfAny)); Ztring Format_Commercial=MI.Get(Stream_General, 0, General_Format_Commercial_IfAny); if (!Format_Commercial.empty()) { Format_Commercial.FindAndReplace(__T("XDCAM "), Ztring()); Fill(Stream_General, 0, General_Format_Commercial, __T("XDCAM Clip ")+Format_Commercial, true); } } //else // MediaInfo::Option_Static(__T("ReadByHuman"), ReadByHuman?__T("1"):__T("0")); } #endif //defined(MEDIAINFO_MXF_YES) //Device Element=Root->FirstChildElement("Device"); if (Element) Fill(Stream_General, 0, General_Encoded_Application, string(Element->Attribute("manufacturer"))+" "+Element->Attribute("modelName"), true, true); if (File_Size_Total!=File_Size) Fill(Stream_General, 0, General_FileSize, File_Size_Total, 10, true); } else { Reject("Xdcam_Clip"); return false; } } //All should be OK... return true; }
//--------------------------------------------------------------------------- bool File_DcpAm::FileHeader_Begin() { XMLDocument document; if (!FileHeader_Begin_XML(document)) return false; std::string NameSpace; XMLElement* AssetMap=document.FirstChildElement("AssetMap"); if (AssetMap==NULL) { NameSpace="am:"; AssetMap=document.FirstChildElement((NameSpace+"AssetMap").c_str()); } if (!AssetMap) { Reject("DcpAm"); return false; } const char* Attribute=AssetMap->Attribute(NameSpace.empty()?"xmlns":"xmlns:am"); if (!Attribute) { Reject("DcpAm"); return false; } if (strcmp(Attribute, "http://www.digicine.com/PROTO-ASDCP-AM-20040311#") && strcmp(Attribute, "http://www.smpte-ra.org/schemas/429-9/2007/AM")) { Reject("DcpAm"); return false; } Accept("DcpAm"); Fill(Stream_General, 0, General_Format, "DCP AM"); Fill(Stream_General, 0, General_Format_Version, NameSpace=="am:"?"SMPTE":"Interop"); Config->File_ID_OnlyRoot_Set(false); //Parsing main elements for (XMLElement* AssetMap_Item=AssetMap->FirstChildElement(); AssetMap_Item; AssetMap_Item=AssetMap_Item->NextSiblingElement()) { //AssetList if (!strcmp(AssetMap_Item->Value(), (NameSpace+"AssetList").c_str())) { for (XMLElement* AssetList_Item=AssetMap_Item->FirstChildElement(); AssetList_Item; AssetList_Item=AssetList_Item->NextSiblingElement()) { //Asset if (!strcmp(AssetList_Item->Value(), (NameSpace+"Asset").c_str())) { File_DcpPkl::stream Stream; for (XMLElement* Asset_Item=AssetList_Item->FirstChildElement(); Asset_Item; Asset_Item=Asset_Item->NextSiblingElement()) { //ChunkList if (!strcmp(Asset_Item->Value(), (NameSpace+"ChunkList").c_str())) { for (XMLElement* ChunkList_Item=Asset_Item->FirstChildElement(); ChunkList_Item; ChunkList_Item=ChunkList_Item->NextSiblingElement()) { //Chunk if (!strcmp(ChunkList_Item->Value(), (NameSpace+"Chunk").c_str())) { File_DcpPkl::stream::chunk Chunk; for (XMLElement* Chunk_Item=ChunkList_Item->FirstChildElement(); Chunk_Item; Chunk_Item=Chunk_Item->NextSiblingElement()) { //Path if (!strcmp(Chunk_Item->Value(), (NameSpace+"Path").c_str())) Chunk.Path=Chunk_Item->GetText(); } Stream.ChunkList.push_back(Chunk); } } } //Id if (!strcmp(Asset_Item->Value(), (NameSpace+"Id").c_str())) Stream.Id=Asset_Item->GetText(); //PackingList if (!strcmp(Asset_Item->Value(), (NameSpace+"PackingList").c_str())) { PKL_Pos=Streams.size(); Stream.StreamKind=(stream_t)(Stream_Max+2); // Means PKL } } Streams.push_back(Stream); } } } //Creator if (!strcmp(AssetMap_Item->Value(), (NameSpace+"Creator").c_str())) Fill(Stream_General, 0, General_Encoded_Library, AssetMap_Item->GetText()); //IssueDate if (!strcmp(AssetMap_Item->Value(), (NameSpace+"IssueDate").c_str())) Fill(Stream_General, 0, General_Encoded_Date, AssetMap_Item->GetText()); //Issuer if (!strcmp(AssetMap_Item->Value(), (NameSpace+"Issuer").c_str())) Fill(Stream_General, 0, General_EncodedBy, AssetMap_Item->GetText()); } Element_Offset=File_Size; //Merging with PKL if (PKL_Pos<Streams.size() && Streams[PKL_Pos].ChunkList.size()==1) { FileName Directory(File_Name); Ztring PKL_FileName; PKL_FileName.From_UTF8(Streams[PKL_Pos].ChunkList[0].Path); if (PKL_FileName.find(__T("file://"))==0 && PKL_FileName.find(__T("file:///"))==string::npos) PKL_FileName.erase(0, 7); //TODO: better handling of relative and absolute file naes MediaInfo_Internal MI; MI.Option(__T("File_KeepInfo"), __T("1")); Ztring ParseSpeed_Save=MI.Option(__T("ParseSpeed_Get"), __T("")); Ztring Demux_Save=MI.Option(__T("Demux_Get"), __T("")); MI.Option(__T("ParseSpeed"), __T("0")); MI.Option(__T("Demux"), Ztring()); MI.Option(__T("File_IsReferenced"), __T("1")); size_t MiOpenResult=MI.Open(Directory.Path_Get()+PathSeparator+PKL_FileName); MI.Option(__T("ParseSpeed"), ParseSpeed_Save); //This is a global value, need to reset it. TODO: local value MI.Option(__T("Demux"), Demux_Save); //This is a global value, need to reset it. TODO: local value if (MiOpenResult && (MI.Get(Stream_General, 0, General_Format)==__T("DCP PKL") || MI.Get(Stream_General, 0, General_Format)==__T("IMF PKL"))) { MergeFromPkl(((File_DcpPkl*)MI.Info)->Streams); for (size_t Pos=0; Pos<MI.Count_Get(Stream_Other); ++Pos) { Stream_Prepare(Stream_Other); Merge(*MI.Info, Stream_Other, Pos, StreamPos_Last); } } } //Creating the playlist if (!Config->File_IsReferenced_Get()) { ReferenceFiles=new File__ReferenceFilesHelper(this, Config); for (File_DcpPkl::streams::iterator Stream=Streams.begin(); Stream!=Streams.end(); ++Stream) if (Stream->StreamKind==(stream_t)(Stream_Max+1) && Stream->ChunkList.size()==1) // Means CPL { sequence* Sequence=new sequence; Sequence->FileNames.push_back(Ztring().From_UTF8(Stream->ChunkList[0].Path)); Sequence->StreamID=ReferenceFiles->Sequences_Size()+1; ReferenceFiles->AddSequence(Sequence); } ReferenceFiles->FilesForStorage=true; } //All should be OK... return true; }
//--------------------------------------------------------------------------- bool File_DcpPkl::FileHeader_Begin() { XMLDocument document; if (!FileHeader_Begin_XML(document)) return false; bool IsDcp=false, IsImf=false; XMLElement* PackingList=document.FirstChildElement("PackingList"); if (!PackingList) { Reject("DcpPkl"); return false; } const char* Attribute=PackingList->Attribute("xmlns"); if (!Attribute) { Reject("DcpPkl"); return false; } if (!strcmp(Attribute, "http://www.digicine.com/PROTO-ASDCP-PKL-20040311#")) IsDcp=true; if (!strcmp(Attribute, "http://www.smpte-ra.org/schemas/429-8/2007/PKL")) IsImf=true; if (!IsDcp && !IsImf) { Reject("DcpPkl"); return false; } Accept("DcpPkl"); Fill(Stream_General, 0, General_Format, IsDcp?"DCP PKL":"IMF PKL"); Config->File_ID_OnlyRoot_Set(false); ReferenceFiles=new File__ReferenceFilesHelper(this, Config); Ztring CPL_FileName; //Parsing main elements for (XMLElement* PackingList_Item=PackingList->FirstChildElement(); PackingList_Item; PackingList_Item=PackingList_Item->NextSiblingElement()) { //AssetList if (!strcmp(PackingList_Item->Value(), "AssetList")) { for (XMLElement* AssetList_Item=PackingList_Item->FirstChildElement(); AssetList_Item; AssetList_Item=AssetList_Item->NextSiblingElement()) { //Asset if (!strcmp(AssetList_Item->Value(), "Asset")) { File__ReferenceFilesHelper::reference ReferenceFile; bool IsCPL=false; bool PreviousFileNameIsAnnotationText=false; for (XMLElement* File_Item=AssetList_Item->FirstChildElement(); File_Item; File_Item=File_Item->NextSiblingElement()) { //Id if (!strcmp(File_Item->Value(), "Id")) ReferenceFile.Infos["UniqueID"].From_UTF8(File_Item->GetText()); //Type if (!strcmp(File_Item->Value(), "Type")) { if (!strcmp(File_Item->GetText(), "application/x-smpte-mxf;asdcpKind=Picture")) ReferenceFile.StreamKind=Stream_Video; else if (!strcmp(File_Item->GetText(), "application/x-smpte-mxf;asdcpKind=Sound")) ReferenceFile.StreamKind=Stream_Audio; else if (!strcmp(File_Item->GetText(), "text/xml;asdcpKind=CPL")) { HasCpl=IsCPL=true; } else ReferenceFile.StreamKind=Stream_Other; } //Id if (!strcmp(File_Item->Value(), "OriginalFileName") || (ReferenceFile.FileNames.empty() && !strcmp(File_Item->Value(), "AnnotationText"))) // Annotation contains file name (buggy IMF file) { if (PreviousFileNameIsAnnotationText) ReferenceFile.FileNames.clear(); // Annotation is something else, no need of it if (!strcmp(File_Item->Value(), "AnnotationText")) PreviousFileNameIsAnnotationText=true; ReferenceFile.FileNames.push_back(Ztring().From_UTF8(File_Item->GetText())); string Text=File_Item->GetText(); if (Text.size()>=8 && (Text.find("_cpl.xml")==Text.size()-8) || (Text.find("CPL_")==0 && Text.find(".xml")==Text.size()-4)) { HasCpl=IsCPL=true; ReferenceFile.StreamKind=Stream_Max; } } } if (IsCPL && CPL_FileName.empty()) for (size_t Pos=0; Pos<ReferenceFile.FileNames.size(); Pos++) { CPL_FileName=ReferenceFile.FileNames[Pos]; //Using only the first CPL file meet break; } ReferenceFile.StreamID=ReferenceFiles->References.size()+1; ReferenceFiles->References.push_back(ReferenceFile); } } } } Element_Offset=File_Size; //Getting links between files if (!CPL_FileName.empty() && !Config->File_IsReferenced_Get()) { FileName Directory(File_Name); if (CPL_FileName.find(__T("file://"))==0 && CPL_FileName.find(__T("file:///"))==string::npos) CPL_FileName.erase(0, 7); //TODO: better handling of relative and absolute file naes MediaInfo_Internal MI; MI.Option(__T("File_KeepInfo"), __T("1")); Ztring ParseSpeed_Save=MI.Option(__T("ParseSpeed_Get"), __T("")); Ztring Demux_Save=MI.Option(__T("Demux_Get"), __T("")); MI.Option(__T("ParseSpeed"), __T("0")); MI.Option(__T("Demux"), Ztring()); MI.Option(__T("File_IsReferenced"), __T("1")); size_t MiOpenResult=MI.Open(Directory.Path_Get()+PathSeparator+CPL_FileName); MI.Option(__T("ParseSpeed"), ParseSpeed_Save); //This is a global value, need to reset it. TODO: local value MI.Option(__T("Demux"), Demux_Save); //This is a global value, need to reset it. TODO: local value if (MiOpenResult && ((IsDcp && MI.Get(Stream_General, 0, General_Format)==__T("DCP CPL")) || (IsImf && MI.Get(Stream_General, 0, General_Format)==__T("IMF CPL")))) { DcpCpl_MergeFromPkl(((File_DcpCpl*)MI.Info)->ReferenceFiles, ReferenceFiles); ReferenceFiles->References=((File_DcpCpl*)MI.Info)->ReferenceFiles->References; } } ReferenceFiles->FilesForStorage=true; //All should be OK... return true; }
//--------------------------------------------------------------------------- bool File_HdsF4m::FileHeader_Begin() { XMLDocument document; if (!FileHeader_Begin_XML(document)) return false; { XMLElement* Root=document.FirstChildElement("manifest"); if (Root) { const char* Attribute=Root->Attribute("xmlns"); if (Attribute==NULL || Ztring().From_UTF8(Attribute)!=__T("http://ns.adobe.com/f4m/1.0")) { Reject("HdsF4m"); return false; } Accept("HdsF4m"); Fill(Stream_General, 0, General_Format, "HDS F4M"); Config->File_ID_OnlyRoot_Set(false); ReferenceFiles_Accept(this, Config); #if defined(MEDIAINFO_REFERENCES_YES) //Parsing main elements Ztring BaseURL; for (XMLElement* Root_Item=Root->FirstChildElement(); Root_Item; Root_Item=Root_Item->NextSiblingElement()) { //Common information if (string(Root_Item->Value())=="BaseURL") { if (BaseURL.empty()) //Using the first one BaseURL=Root_Item->GetText(); } //Period if (string(Root_Item->Value())=="media") { sequence* Sequence=new sequence; //Attributes - mineType const char* Attribute=Root_Item->Attribute("url"); if (Attribute) Sequence->AddFileName(Ztring().From_UTF8(Attribute)+__T("Seg1.f4f")); Sequence->StreamID=ReferenceFiles->Sequences_Size()+1; ReferenceFiles->AddSequence(Sequence); } } #endif //MEDIAINFO_REFERENCES_YES } else { Reject("HdsF4m"); return false; } } Element_Offset=File_Size; //All should be OK... return true; }
//--------------------------------------------------------------------------- void File_Ttml::Read_Buffer_Continue() { tinyxml2::XMLDocument document; if (!FileHeader_Begin_XML(document)) return; XMLElement* Root=document.FirstChildElement("tt"); if (!Root) { Reject(); return; } if (!Status[IsAccepted]) { Accept(); #if MEDIAINFO_EVENTS MuxingMode=(int8u)-1; if (StreamIDs_Size>=2 && ParserIDs[StreamIDs_Size-2]==MediaInfo_Parser_Mpeg4) MuxingMode=11; //MPEG-4 if (StreamIDs_Size>2 && ParserIDs[StreamIDs_Size-2]==MediaInfo_Parser_Mxf) //Only if referenced MXF MuxingMode=13; //MXF #endif //MEDIAINFO_EVENTS #if MEDIAINFO_DEMUX && MEDIAINFO_NEXTPACKET if (Config->NextPacket_Get() && Config->Event_CallBackFunction_IsSet()) return; // Waiting for NextPacket #endif //MEDIAINFO_DEMUX && MEDIAINFO_NEXTPACKET } tinyxml2::XMLElement* div=NULL; #if MEDIAINFO_EVENTS tinyxml2::XMLElement* p=NULL; #endif //MEDIAINFO_EVENTS for (XMLElement* tt_element=Root->FirstChildElement(); tt_element; tt_element=tt_element->NextSiblingElement()) { //body if (!strcmp(tt_element->Value(), "body")) { for (XMLElement* body_element=tt_element->FirstChildElement(); body_element; body_element=body_element->NextSiblingElement()) { //div if (!strcmp(body_element->Value(), "div")) { for (XMLElement* div_element=body_element->FirstChildElement(); div_element; div_element=div_element->NextSiblingElement()) { //p if (!strcmp(div_element->Value(), "p")) { div=body_element; #if MEDIAINFO_EVENTS p=div_element; #endif //MEDIAINFO_EVENTS break; } } if (div) break; } } if (div) break; } } #if MEDIAINFO_DEMUX Demux(Buffer, Buffer_Size, ContentType_MainStream); #endif //MEDIAINFO_DEMUX // Output #if MEDIAINFO_EVENTS for (; p; p=p->NextSiblingElement()) { //p if (!strcmp(p->Value(), "p")) { int64u DTS_Begin=(int64u)-1; const char* Attribute=p->Attribute("begin"); if (Attribute) DTS_Begin=Ttml_str2timecode(Attribute); int64u DTS_End=(int64u)-1; Attribute=p->Attribute("end"); if (Attribute) DTS_End=Ttml_str2timecode(Attribute); string ContentUtf8; XMLPrinter printer; p->Accept(&printer); ContentUtf8+=printer.CStr(); while (!ContentUtf8.empty() && (ContentUtf8[ContentUtf8.size()-1]=='\r' || ContentUtf8[ContentUtf8.size()-1]=='\n')) ContentUtf8.resize(ContentUtf8.size()-1); Ztring Content; Content.From_UTF8(ContentUtf8.c_str()); Frame_Count_NotParsedIncluded=Frame_Count; EVENT_BEGIN (Global, SimpleText, 0) //Hack: remove "p", "span", "br" Content.FindAndReplace(__T("\r"), Ztring(), 0, ZenLib::Ztring_Recursive); Content.FindAndReplace(__T("\n"), Ztring(), 0, ZenLib::Ztring_Recursive); for (;;) { size_t Span_Begin=Content.find(__T("<p")); if (Span_Begin==string::npos) break; size_t Span_End=Content.find(__T(">"), Span_Begin+5); if (Span_End==string::npos) break; size_t ShlashSpan_Begin=Content.find(__T("</p>"), Span_End+1); if (ShlashSpan_Begin==string::npos) break; Content.erase(ShlashSpan_Begin, 7); Content.erase(Span_Begin, Span_End-Span_Begin+1); } for (;;) { size_t Span_Begin=Content.find(__T("<span")); if (Span_Begin==string::npos) break; size_t Span_End=Content.find(__T(">"), Span_Begin+5); if (Span_End==string::npos) break; size_t ShlashSpan_Begin=Content.find(__T("</span>"), Span_End+1); if (ShlashSpan_Begin==string::npos) break; Content.erase(ShlashSpan_Begin, 7); Content.erase(Span_Begin, Span_End-Span_Begin+1); } Content.FindAndReplace(__T("<br>"), EOL, 0, ZenLib::Ztring_Recursive); Content.FindAndReplace(__T("<br/>"), EOL, 0, ZenLib::Ztring_Recursive); Content.FindAndReplace(__T("<br />"), EOL, 0, ZenLib::Ztring_Recursive); Event.DTS=DTS_Begin; Event.PTS=Event.DTS; Event.DUR=DTS_End-DTS_Begin; Event.Content=Content.c_str(); Event.Flags=0; Event.MuxingMode=MuxingMode; Event.Service=(int8u)Element_Code; Event.Row_Max=0; Event.Column_Max=0; Event.Row_Values=NULL; Event.Row_Attributes=NULL; EVENT_END () EVENT_BEGIN (Global, SimpleText, 0) Event.DTS=DTS_End; Event.PTS=Event.DTS; Event.DUR=0; Event.Content=__T(""); Event.Flags=0; Event.MuxingMode=MuxingMode; Event.Service=(int8u)Element_Code; Event.Row_Max=0; Event.Column_Max=0; Event.Row_Values=NULL; Event.Row_Attributes=NULL; EVENT_END () Frame_Count++; } } #endif //MEDIAINFO_EVENTS Buffer_Offset=Buffer_Size; }
//--------------------------------------------------------------------------- bool File_Xmp::FileHeader_Begin() { XMLDocument document; if (!FileHeader_Begin_XML(document)) return false; std::string NameSpace; XMLElement* XmpMeta=document.FirstChildElement("xmpmeta"); if (XmpMeta==NULL) { NameSpace="x:"; XmpMeta=document.FirstChildElement((NameSpace+"xmpmeta").c_str()); } if (!XmpMeta) { Reject("XMP"); return false; } XMLElement* Rdf=XmpMeta->FirstChildElement("RDF"); if (Rdf==NULL) { NameSpace="rdf:"; Rdf=XmpMeta->FirstChildElement((NameSpace+"RDF").c_str()); } if (!Rdf) { Reject("XMP"); return false; } Accept("XMP"); for (XMLElement* Rdf_Item=Rdf->FirstChildElement(); Rdf_Item; Rdf_Item=Rdf_Item->NextSiblingElement()) { //RDF item if (!strcmp(Rdf_Item->Value(), (NameSpace+"Description").c_str())) { const char* Attribute; Attribute=Rdf_Item->Attribute("xmlns:pdfaid"); if (Attribute) { string Profile; if (strcmp(Attribute, "http://www.aiim.org/pdfa/ns/id/")) Profile=Attribute; else { Profile+="A"; Attribute=Rdf_Item->Attribute("pdfaid:part"); if (Attribute) { Profile+='-'; Profile+=Attribute; Attribute=Rdf_Item->Attribute("pdfaid:conformance"); if (Attribute) { string Conformance(Attribute); if (Conformance.size()==1 && Conformance[0]>='A' && Conformance[0]<='Z') Conformance[0]+=0x20; // From "A" to "a" Profile+=Conformance; } } } Fill(Stream_General, 0, General_Format_Profile, Profile); } } } Finish(); return true; }
//--------------------------------------------------------------------------- bool File_DcpAm::FileHeader_Begin() { XMLDocument document; if (!FileHeader_Begin_XML(document)) return false; bool IsDcp=false, IsImf=false; std::string NameSpace; XMLElement* AssetMap=document.FirstChildElement("AssetMap"); if (AssetMap==NULL) { NameSpace="am:"; AssetMap=document.FirstChildElement((NameSpace+"AssetMap").c_str()); } if (!AssetMap) { Reject("DcpAm"); return false; } const char* Attribute=AssetMap->Attribute(NameSpace.empty()?"xmlns":"xmlns:am"); if (!Attribute) { Reject("DcpAm"); return false; } if (!strcmp(Attribute, "http://www.digicine.com/PROTO-ASDCP-AM-20040311#")) IsDcp=true; if (!strcmp(Attribute, "http://www.smpte-ra.org/schemas/429-9/2007/AM")) { if (NameSpace.empty()) IsImf=true; else IsDcp=true; } if (!IsDcp && !IsImf) { Reject("DcpAm"); return false; } Accept("DcpAm"); Fill(Stream_General, 0, General_Format, IsDcp?"DCP AM":"IMF AM"); if (IsDcp) Fill(Stream_General, 0, General_Format_Version, NameSpace=="am:"?"SMPTE":"Interop"); Config->File_ID_OnlyRoot_Set(false); ReferenceFiles=new File__ReferenceFilesHelper(this, Config); Ztring CPL_FileName; for (XMLElement* AssetMap_Item=AssetMap->FirstChildElement(); AssetMap_Item; AssetMap_Item=AssetMap_Item->NextSiblingElement()) { //AssetList if (!strcmp(AssetMap_Item->Value(), (NameSpace+"AssetList").c_str())) { for (XMLElement* AssetList_Item=AssetMap_Item->FirstChildElement(); AssetList_Item; AssetList_Item=AssetList_Item->NextSiblingElement()) { //Asset if (!strcmp(AssetList_Item->Value(), (NameSpace+"Asset").c_str())) { File__ReferenceFilesHelper::reference ReferenceFile; bool IsCPL=false; for (XMLElement* Asset_Item=AssetList_Item->FirstChildElement(); Asset_Item; Asset_Item=Asset_Item->NextSiblingElement()) { //Id if (!strcmp(Asset_Item->Value(), (NameSpace+"Id").c_str())) ReferenceFile.Infos["UniqueID"].From_UTF8(Asset_Item->GetText()); //ChunkList if (!strcmp(Asset_Item->Value(), (NameSpace+"ChunkList").c_str())) { for (XMLElement* ChunkList_Item=Asset_Item->FirstChildElement(); ChunkList_Item; ChunkList_Item=ChunkList_Item->NextSiblingElement()) { //Chunk if (!strcmp(ChunkList_Item->Value(), (NameSpace+"Chunk").c_str())) { for (XMLElement* Chunk_Item=ChunkList_Item->FirstChildElement(); Chunk_Item; Chunk_Item=Chunk_Item->NextSiblingElement()) { //Path if (!strcmp(Chunk_Item->Value(), (NameSpace+"Path").c_str())) { ReferenceFile.FileNames.push_back(Ztring().From_UTF8(Chunk_Item->GetText())); string Text=Chunk_Item->GetText(); if (Text.size()>=8 && (Text.find("_cpl.xml")==Text.size()-8) || (Text.find("CPL_")==0 && Text.find(".xml")==Text.size()-4)) IsCPL=true; } } } } } } if (IsCPL) { for (size_t Pos=0; Pos<ReferenceFile.FileNames.size(); Pos++) { if (CPL_FileName.empty()) CPL_FileName=ReferenceFile.FileNames[Pos]; //Using only the first CPL file meet } } ReferenceFile.StreamID=ReferenceFiles->References.size()+1; ReferenceFiles->References.push_back(ReferenceFile); } } } //Creator if (!strcmp(AssetMap_Item->Value(), (NameSpace+"Creator").c_str())) Fill(Stream_General, 0, General_Encoded_Library, AssetMap_Item->GetText()); //IssueDate if (!strcmp(AssetMap_Item->Value(), (NameSpace+"IssueDate").c_str())) Fill(Stream_General, 0, General_Encoded_Date, AssetMap_Item->GetText()); //Issuer if (!strcmp(AssetMap_Item->Value(), (NameSpace+"Issuer").c_str())) Fill(Stream_General, 0, General_EncodedBy, AssetMap_Item->GetText()); } Element_Offset=File_Size; //Getting links between files if (!CPL_FileName.empty() && !Config->File_IsReferenced_Get()) { FileName Directory(File_Name); if (CPL_FileName.find(__T("file://"))==0 && CPL_FileName.find(__T("file:///"))==string::npos) CPL_FileName.erase(0, 7); //TODO: better handling of relative and absolute file naes MediaInfo_Internal MI; MI.Option(__T("File_KeepInfo"), __T("1")); Ztring ParseSpeed_Save=MI.Option(__T("ParseSpeed_Get"), __T("")); Ztring Demux_Save=MI.Option(__T("Demux_Get"), __T("")); MI.Option(__T("ParseSpeed"), __T("0")); MI.Option(__T("Demux"), Ztring()); MI.Option(__T("File_IsReferenced"), __T("1")); size_t MiOpenResult=MI.Open(Directory.Path_Get()+PathSeparator+CPL_FileName); MI.Option(__T("ParseSpeed"), ParseSpeed_Save); //This is a global value, need to reset it. TODO: local value MI.Option(__T("Demux"), Demux_Save); //This is a global value, need to reset it. TODO: local value if (MiOpenResult && ((IsDcp && MI.Get(Stream_General, 0, General_Format)==__T("DCP CPL")) || (IsImf && MI.Get(Stream_General, 0, General_Format)==__T("IMF CPL")))) { DcpCpl_MergeFromPkl(((File_DcpCpl*)MI.Info)->ReferenceFiles, ReferenceFiles); ReferenceFiles->References=((File_DcpCpl*)MI.Info)->ReferenceFiles->References; } } ReferenceFiles->FilesForStorage=true; //All should be OK... return true; }
//--------------------------------------------------------------------------- bool File_DcpCpl::FileHeader_Begin() { XMLDocument document; if (!FileHeader_Begin_XML(document)) return false; bool IsDcp=false, IsImf=false; XMLElement* Root=document.FirstChildElement("CompositionPlaylist"); if (!Root) { Reject("DcpCpl"); return false; } const char* Attribute=Root->Attribute("xmlns"); if (!Attribute) { Reject("DcpCpl"); return false; } if (!strcmp(Attribute, "http://www.digicine.com/PROTO-ASDCP-CPL-20040511#")) IsDcp=true; if (!strcmp(Attribute, "http://www.smpte-ra.org/schemas/2067-3/XXXX") //Some muxers use XXXX instead of year || !strcmp(Attribute, "http://www.smpte-ra.org/schemas/2067-3/2013")) IsImf=true; if (!IsDcp && !IsImf) { Reject("DcpCpl"); return false; } Accept("DcpCpl"); Fill(Stream_General, 0, General_Format, IsDcp?"DCP CPL":"IMF CPL"); Config->File_ID_OnlyRoot_Set(false); ReferenceFiles=new File__ReferenceFilesHelper(this, Config); //Parsing main elements for (XMLElement* Root_Item=Root->FirstChildElement(); Root_Item; Root_Item=Root_Item->NextSiblingElement()) { //ReelList / SegmentList if ((IsDcp && !strcmp(Root_Item->Value(), "ReelList")) || (IsImf && !strcmp(Root_Item->Value(), "SegmentList"))) { for (XMLElement* ReelList_Item=Root_Item->FirstChildElement(); ReelList_Item; ReelList_Item=ReelList_Item->NextSiblingElement()) { //Reel if ((IsDcp && !strcmp(ReelList_Item->Value(), "Reel")) || (IsImf && !strcmp(ReelList_Item->Value(), "Segment"))) { for (XMLElement* Reel_Item=ReelList_Item->FirstChildElement(); Reel_Item; Reel_Item=Reel_Item->NextSiblingElement()) { //AssetList if ((IsDcp && !strcmp(Reel_Item->Value(), "AssetList")) || (IsImf && !strcmp(Reel_Item->Value(), "SequenceList"))) { for (XMLElement* AssetList_Item=Reel_Item->FirstChildElement(); AssetList_Item; AssetList_Item=AssetList_Item->NextSiblingElement()) { //File //if ((IsDcp && (!strcmp(AssetList_Item->Value(), "MainPicture") || !strcmp(AssetList_Item->Value(), "MainSound"))) // || (IsImf && (!strcmp(AssetList_Item->Value(), "cc:MainImageSequence") || !strcmp(AssetList_Item->Value(), "cc:MainImage")))) { File__ReferenceFilesHelper::reference ReferenceFile; Ztring Asset_Id; if ((IsDcp && !strcmp(AssetList_Item->Value(), "MainPicture")) || (IsImf && !strcmp(AssetList_Item->Value(), "cc:MainImageSequence"))) ReferenceFile.StreamKind=Stream_Video; if ((IsDcp && !strcmp(AssetList_Item->Value(), "MainSound")) || (IsImf && !strcmp(AssetList_Item->Value(), "cc:MainAudioSequence"))) ReferenceFile.StreamKind=Stream_Audio; for (XMLElement* File_Item=AssetList_Item->FirstChildElement(); File_Item; File_Item=File_Item->NextSiblingElement()) { //Id if (!strcmp(File_Item->Value(), "Id") && Asset_Id.empty()) Asset_Id.From_UTF8(File_Item->GetText()); //ResourceList if (IsImf && !strcmp(File_Item->Value(), "ResourceList")) { for (XMLElement* ResourceList_Item=File_Item->FirstChildElement(); ResourceList_Item; ResourceList_Item=ResourceList_Item->NextSiblingElement()) { //Resource if (!strcmp(ResourceList_Item->Value(), "Resource")) { Ztring Resource_Id; File__ReferenceFilesHelper::reference::completeduration Resource; for (XMLElement* Resource_Item=ResourceList_Item->FirstChildElement(); Resource_Item; Resource_Item=Resource_Item->NextSiblingElement()) { //EditRate if (!strcmp(Resource_Item->Value(), "EditRate")) { const char* EditRate=Resource_Item->GetText(); Resource.IgnoreFramesRate=atof(EditRate); const char* EditRate2=strchr(EditRate, ' '); if (EditRate2!=NULL) { float64 EditRate2f=atof(EditRate2); if (EditRate2f) Resource.IgnoreFramesRate/=EditRate2f; } } //EntryPoint if (!strcmp(Resource_Item->Value(), "EntryPoint")) Resource.IgnoreFramesBefore=atoi(Resource_Item->GetText()); //Id if (!strcmp(File_Item->Value(), "Id") && Resource_Id.empty()) Resource_Id.From_UTF8(File_Item->GetText()); //SourceDuration if (!strcmp(Resource_Item->Value(), "SourceDuration")) Resource.IgnoreFramesAfterDuration=atoi(Resource_Item->GetText()); //TrackFileId if (!strcmp(Resource_Item->Value(), "TrackFileId")) Resource.FileName.From_UTF8(Resource_Item->GetText()); } if (Resource.FileName.empty()) Resource.FileName=Resource_Id; ReferenceFile.CompleteDuration.push_back(Resource); } } } } if (ReferenceFile.CompleteDuration.empty()) { File__ReferenceFilesHelper::reference::completeduration Resource; Resource.FileName=Asset_Id; ReferenceFile.CompleteDuration.push_back(Resource); } ReferenceFile.StreamID=ReferenceFiles->References.size()+1; ReferenceFiles->References.push_back(ReferenceFile); } } } } } } } } Element_Offset=File_Size; //Getting files names if (!Config->File_IsReferenced_Get()) { FileName Directory(File_Name); ZtringList List; if (IsImf) List=Dir::GetAllFileNames(Directory.Path_Get()+PathSeparator+__T("PKL_*.xml"), Dir::Include_Files); if (IsDcp || List.empty()) List=Dir::GetAllFileNames(Directory.Path_Get()+PathSeparator+__T("*_pkl.xml"), Dir::Include_Files); for (size_t Pos=0; Pos<List.size(); Pos++) { MediaInfo_Internal MI; MI.Option(__T("File_KeepInfo"), __T("1")); Ztring ParseSpeed_Save=MI.Option(__T("ParseSpeed_Get"), __T("")); Ztring Demux_Save=MI.Option(__T("Demux_Get"), __T("")); MI.Option(__T("ParseSpeed"), __T("0")); MI.Option(__T("Demux"), Ztring()); MI.Option(__T("File_IsReferenced"), __T("1")); size_t MiOpenResult=MI.Open(List[Pos]); MI.Option(__T("ParseSpeed"), ParseSpeed_Save); //This is a global value, need to reset it. TODO: local value MI.Option(__T("Demux"), Demux_Save); //This is a global value, need to reset it. TODO: local value if (MiOpenResult && ((IsDcp && MI.Get(Stream_General, 0, General_Format)==__T("DCP PKL")) || (IsImf && MI.Get(Stream_General, 0, General_Format)==__T("IMF PKL")))) { DcpCpl_MergeFromPkl(ReferenceFiles, ((File_DcpCpl*)MI.Info)->ReferenceFiles); } } } ReferenceFiles->FilesForStorage=true; //All should be OK... return true; }
//--------------------------------------------------------------------------- bool File_Ism::FileHeader_Begin() { XMLDocument document; if (!FileHeader_Begin_XML(document)) return false; { XMLElement* Root=document.FirstChildElement("smil"); if (Root) { Accept("ISM"); Fill(Stream_General, 0, General_Format, "ISM"); ReferenceFiles=new File__ReferenceFilesHelper(this, Config); std::set<Ztring> FileNames; XMLElement* Body=Root->FirstChildElement(); while (Body) { if (string(Body->Value())=="body") { XMLElement* Switch=Body->FirstChildElement(); while (Switch) { if (string(Switch->Value())=="switch") { XMLElement* Stream=Switch->FirstChildElement(); while (Stream) { if (string(Stream->Value())=="video" || string(Stream->Value())=="audio") { File__ReferenceFilesHelper::reference ReferenceFile; if (string(Stream->Value())=="video") ReferenceFile.StreamKind=Stream_Video; if (string(Stream->Value())=="audio") ReferenceFile.StreamKind=Stream_Audio; const char* Attribute=Stream->Attribute("src"); if (Attribute) ReferenceFile.FileNames.push_back(Ztring().From_UTF8(Attribute)); XMLElement* Param=Stream->FirstChildElement(); while (Param) { if (string(Param->Value())=="param") { Attribute=Param->Attribute("name"); if (Attribute && Ztring().From_UTF8(Attribute)==__T("trackID")) { Attribute=Param->Attribute("value"); if (Attribute) ReferenceFile.StreamID=Ztring().From_UTF8(Attribute).To_int64u(); } } Param=Param->NextSiblingElement(); } if (!ReferenceFile.FileNames.empty() && !ReferenceFile.FileNames[0].empty() && FileNames.find(ReferenceFile.FileNames[0])==FileNames.end()) { ReferenceFiles->References.push_back(ReferenceFile); FileNames.insert(ReferenceFile.FileNames[0]); } } Stream=Stream->NextSiblingElement(); } } Switch=Switch->NextSiblingElement(); } } Body=Body->NextSiblingElement(); } } else { Reject("ISM"); return false; } } Element_Offset=File_Size; //All should be OK... return true; }
//--------------------------------------------------------------------------- bool File_DcpPkl::FileHeader_Begin() { XMLDocument document; if (!FileHeader_Begin_XML(document)) return false; XMLElement* PackingList=document.FirstChildElement("PackingList"); if (!PackingList) { Reject("DcpPkl"); return false; } const char* Attribute=PackingList->Attribute("xmlns"); if (!Attribute) { Reject("DcpPkl"); return false; } if (strcmp(Attribute, "http://www.digicine.com/PROTO-ASDCP-PKL-20040311#") && strcmp(Attribute, "http://www.smpte-ra.org/schemas/429-8/2007/PKL")) { Reject("DcpPkl"); return false; } Accept("DcpPkl"); Fill(Stream_General, 0, General_Format, "DCP PKL"); Config->File_ID_OnlyRoot_Set(false); //Parsing main elements for (XMLElement* PackingList_Item=PackingList->FirstChildElement(); PackingList_Item; PackingList_Item=PackingList_Item->NextSiblingElement()) { //AssetList if (!strcmp(PackingList_Item->Value(), "AssetList")) { for (XMLElement* AssetList_Item=PackingList_Item->FirstChildElement(); AssetList_Item; AssetList_Item=AssetList_Item->NextSiblingElement()) { //Asset if (!strcmp(AssetList_Item->Value(), "Asset")) { stream Stream; for (XMLElement* File_Item=AssetList_Item->FirstChildElement(); File_Item; File_Item=File_Item->NextSiblingElement()) { //AnnotationText if (!strcmp(File_Item->Value(), "AnnotationText")) Stream.AnnotationText=File_Item->GetText(); //Id if (!strcmp(File_Item->Value(), "Id")) Stream.Id=File_Item->GetText(); //OriginalFileName if (!strcmp(File_Item->Value(), "OriginalFileName")) Stream.OriginalFileName=File_Item->GetText(); //Type if (!strcmp(File_Item->Value(), "Type")) { if (!strcmp(File_Item->GetText(), "application/x-smpte-mxf;asdcpKind=Picture")) Stream.StreamKind=Stream_Video; else if (!strcmp(File_Item->GetText(), "application/x-smpte-mxf;asdcpKind=Sound")) Stream.StreamKind=Stream_Audio; else if (!strcmp(File_Item->GetText(), "text/xml") || !strcmp(File_Item->GetText(), "text/xml;asdcpKind=CPL")) Stream.StreamKind=(stream_t)(Stream_Max+1); // Means CPL else Stream.StreamKind=Stream_Other; } } Streams.push_back(Stream); } } } } Element_Offset=File_Size; //Merging with Assetmap if (!Config->File_IsReferenced_Get()) { FileName Directory(File_Name); Ztring Assetmap_FileName=Directory.Path_Get()+PathSeparator+__T("ASSETMAP.xml"); bool IsOk=false; if (File::Exists(Assetmap_FileName)) IsOk=true; else { Assetmap_FileName.resize(Assetmap_FileName.size()-4); //Old fashion, without ".xml" if (File::Exists(Assetmap_FileName)) IsOk=true; } if (IsOk) { MediaInfo_Internal MI; MI.Option(__T("File_KeepInfo"), __T("1")); Ztring ParseSpeed_Save=MI.Option(__T("ParseSpeed_Get"), __T("")); Ztring Demux_Save=MI.Option(__T("Demux_Get"), __T("")); MI.Option(__T("ParseSpeed"), __T("0")); MI.Option(__T("Demux"), Ztring()); MI.Option(__T("File_IsReferenced"), __T("1")); size_t MiOpenResult=MI.Open(Assetmap_FileName); MI.Option(__T("ParseSpeed"), ParseSpeed_Save); //This is a global value, need to reset it. TODO: local value MI.Option(__T("Demux"), Demux_Save); //This is a global value, need to reset it. TODO: local value if (MiOpenResult && (MI.Get(Stream_General, 0, General_Format)==__T("DCP AM") || MI.Get(Stream_General, 0, General_Format)==__T("IMF AM"))) { MergeFromAm(((File_DcpPkl*)MI.Info)->Streams); } } } //Creating the playlist if (!Config->File_IsReferenced_Get()) { ReferenceFiles=new File__ReferenceFilesHelper(this, Config); for (File_DcpPkl::streams::iterator Stream=Streams.begin(); Stream!=Streams.end(); ++Stream) if (Stream->StreamKind==(stream_t)(Stream_Max+1) && Stream->ChunkList.size()==1) // Means CPL { sequence* Sequence=new sequence; Sequence->FileNames.push_back(Ztring().From_UTF8(Stream->ChunkList[0].Path)); Sequence->StreamID=ReferenceFiles->Sequences_Size()+1; ReferenceFiles->AddSequence(Sequence); } ReferenceFiles->FilesForStorage=true; } //All should be OK... return true; }
//--------------------------------------------------------------------------- bool File_Ism::FileHeader_Begin() { XMLDocument document; if (!FileHeader_Begin_XML(document)) return false; { XMLElement* Root=document.FirstChildElement("smil"); if (Root) { #if defined(MEDIAINFO_REFERENCES_YES) std::set<Ztring> FileNames; #endif //MEDIAINFO_REFERENCES_YES XMLElement* Body=Root->FirstChildElement(); while (Body) { if (string(Body->Value())=="body") { XMLElement* Switch=Body->FirstChildElement(); while (Switch) { if (string(Switch->Value())=="switch") { Accept("ISM"); #if defined(MEDIAINFO_REFERENCES_YES) XMLElement* Stream=Switch->FirstChildElement(); while (Stream) { string Value(Stream->Value()); if (Value=="video" || Value=="videostream" || Value=="audio" || Value=="audiostream" || Value=="text" || Value=="textstream") { sequence* Sequence=new sequence; if (Value=="video" || Value=="videostream") Sequence->StreamKind=Stream_Video; if (Value=="audio" || Value=="audiostream") Sequence->StreamKind=Stream_Audio; if (Value=="text" || Value=="textstream" ) Sequence->StreamKind=Stream_Text; const char* Attribute=Stream->Attribute("src"); if (Attribute) Sequence->AddFileName(Ztring().From_UTF8(Attribute)); XMLElement* Param=Stream->FirstChildElement(); while (Param) { if (string(Param->Value())=="param") { Attribute=Param->Attribute("name"); if (Attribute && Ztring().From_UTF8(Attribute)==__T("trackID")) { Attribute=Param->Attribute("value"); if (Attribute) Sequence->StreamID=Ztring().From_UTF8(Attribute).To_int64u(); } } Param=Param->NextSiblingElement(); } if (!Sequence->FileNames.empty() && !Sequence->FileNames[0].empty() && FileNames.find(Sequence->FileNames[0])==FileNames.end()) { ReferenceFiles->AddSequence(Sequence); FileNames.insert(Sequence->FileNames[0]); } } Stream=Stream->NextSiblingElement(); } #endif //MEDIAINFO_REFERENCES_YES } Switch=Switch->NextSiblingElement(); } } Body=Body->NextSiblingElement(); } } else { Reject("ISM"); return false; } } Element_Offset=File_Size; //All should be OK... return true; }
//--------------------------------------------------------------------------- bool File_Dxw::FileHeader_Begin() { XMLDocument document; if (!FileHeader_Begin_XML(document)) return false; { XMLElement* Root=document.FirstChildElement("indexFile"); if (Root) { const char* Attribute=Root->Attribute("xmlns"); if (Attribute==NULL || Ztring().From_UTF8(Attribute)!=__T("urn:digimetrics-xml-wrapper")) { Reject("DXW"); return false; } Accept("DXW"); Fill(Stream_General, 0, General_Format, "DXW"); ReferenceFiles=new File__ReferenceFilesHelper(this, Config); XMLElement* Track=Root->FirstChildElement(); while (Track) { if (string(Track->Value())=="clip") { File__ReferenceFilesHelper::reference ReferenceFile; Attribute=Track->Attribute("file"); if (Attribute) { ReferenceFile.FileNames.push_back(Ztring().From_UTF8(Attribute)); Attribute=Track->Attribute("type"); if (Attribute) { Ztring StreamKind; StreamKind.From_UTF8(Attribute); if (StreamKind==__T("video")) ReferenceFile.StreamKind=Stream_Video; if (StreamKind==__T("audio")) ReferenceFile.StreamKind=Stream_Audio; if (StreamKind==__T("data")) ReferenceFile.StreamKind=Stream_Text; //Not sure this is a right mapping, but this is only used when file is missing } ReferenceFile.StreamID=ReferenceFiles->References.size()+1; } Attribute=Track->Attribute("framerate"); if (Attribute) { ReferenceFile.FrameRate=Ztring().From_UTF8(Attribute).To_float64(); Attribute=Track->Attribute("type"); if (Attribute) { Ztring StreamKind; StreamKind.From_UTF8(Attribute); if (StreamKind==__T("video")) ReferenceFile.StreamKind=Stream_Video; if (StreamKind==__T("audio")) ReferenceFile.StreamKind=Stream_Audio; if (StreamKind==__T("data")) ReferenceFile.StreamKind=Stream_Text; //Not sure this is a right mapping, but this is only used when file is missing } XMLElement* Frame=Track->FirstChildElement(); while (Frame) { if (string(Frame->Value())=="frame") { Attribute=Frame->Attribute("file"); if (Attribute) ReferenceFile.FileNames.push_back(Ztring().From_UTF8(Attribute)); } Frame=Frame->NextSiblingElement(); } } ReferenceFile.StreamID=ReferenceFiles->References.size()+1; ReferenceFiles->References.push_back(ReferenceFile); } Track=Track->NextSiblingElement(); } } else { Reject("DXW"); return false; } } //All should be OK... return true; }
//--------------------------------------------------------------------------- bool File_DcpCpl::FileHeader_Begin() { XMLDocument document; if (!FileHeader_Begin_XML(document)) return false; XMLElement* Root=document.FirstChildElement(); const char *NameSpace; if (!Root || strcmp(LocalName(Root, NameSpace), "CompositionPlaylist")) { Reject("DcpCpl"); return false; } bool IsDcp=false, IsImf=false; if (!strcmp(NameSpace, "http://www.digicine.com/PROTO-ASDCP-CPL-20040511#") || !strcmp(NameSpace, "http://www.smpte-ra.org/schemas/429-7/2006/CPL")) { IsDcp=true; } else if (IsSmpteSt2067_3(NameSpace)) { IsImf=true; } else { Reject("DcpCpl"); return false; } Accept("DcpCpl"); Fill(Stream_General, 0, General_Format, IsDcp?"DCP CPL":"IMF CPL"); Config->File_ID_OnlyRoot_Set(false); ReferenceFiles=new File__ReferenceFilesHelper(this, Config); //Parsing main elements for (XMLElement* CompositionPlaylist_Item=Root->FirstChildElement(); CompositionPlaylist_Item; CompositionPlaylist_Item=CompositionPlaylist_Item->NextSiblingElement()) { //CompositionTimecode if (IsImf && MatchQName(CompositionPlaylist_Item, "CompositionTimecode", NameSpace)) { sequence* Sequence=new sequence; Sequence->StreamKind=Stream_Other; Sequence->Infos["Type"]=__T("Time code"); Sequence->Infos["Format"]=__T("CPL TC"); Sequence->Infos["TimeCode_Striped"]=__T("Yes"); bool IsDropFrame=false; for (XMLElement* CompositionTimecode_Item=CompositionPlaylist_Item->FirstChildElement(); CompositionTimecode_Item; CompositionTimecode_Item=CompositionTimecode_Item->NextSiblingElement()) { const char* Text=CompositionTimecode_Item->GetText(); if (!Text) continue; const char *CtItemNs, *CtItemName = LocalName(CompositionTimecode_Item, CtItemNs); if (!CtItemNs || strcmp(CtItemNs, NameSpace)) continue; // item has wrong namespace //TimecodeDropFrame if (!strcmp(CtItemName, "TimecodeDropFrame")) { if (strcmp(Text, "") && strcmp(Text, "0")) IsDropFrame=true; } //TimecodeRate if (!strcmp(CtItemName, "TimecodeRate")) Sequence->Infos["FrameRate"].From_UTF8(Text); //TimecodeStartAddress if (!strcmp(CtItemName, "TimecodeStartAddress")) Sequence->Infos["TimeCode_FirstFrame"].From_UTF8(Text); } //Adaptation if (IsDropFrame) { std::map<string, Ztring>::iterator Info=Sequence->Infos.find("TimeCode_FirstFrame"); if (Info!=Sequence->Infos.end() && Info->second.size()>=11 && Info->second[8]!=__T(';')) Info->second[8]=__T(';'); } Sequence->StreamID=ReferenceFiles->Sequences_Size()+1; ReferenceFiles->AddSequence(Sequence); Stream_Prepare(Stream_Other); Fill(Stream_Other, StreamPos_Last, Other_ID, Sequence->StreamID); for (std::map<string, Ztring>::iterator Info=Sequence->Infos.begin(); Info!=Sequence->Infos.end(); ++Info) Fill(Stream_Other, StreamPos_Last, Info->first.c_str(), Info->second); } //ReelList / SegmentList if (MatchQName(CompositionPlaylist_Item, IsDcp?"ReelList":"SegmentList", NameSpace)) { for (XMLElement* ReelList_Item=CompositionPlaylist_Item->FirstChildElement(); ReelList_Item; ReelList_Item=ReelList_Item->NextSiblingElement()) { //Reel if (MatchQName(ReelList_Item, IsDcp?"Reel":"Segment", NameSpace)) { for (XMLElement* Reel_Item=ReelList_Item->FirstChildElement(); Reel_Item; Reel_Item=Reel_Item->NextSiblingElement()) { //AssetList if (MatchQName(Reel_Item, IsDcp?"AssetList":"SequenceList", NameSpace)) { for (XMLElement* AssetList_Item=Reel_Item->FirstChildElement(); AssetList_Item; AssetList_Item=AssetList_Item->NextSiblingElement()) { const char *AlItemNs, *AlItemName = LocalName(AssetList_Item, AlItemNs); if (!AlItemNs) continue; //File //if ((IsDcp && (!strcmp(AssetList_Item->Value(), "MainPicture") || !strcmp(AssetList_Item->Value(), "MainSound"))) // || (IsImf && (!strcmp(AssetList_Item->Value(), "cc:MainImageSequence") || !strcmp(AssetList_Item->Value(), "cc:MainImage")))) if (strcmp(AlItemName, "MarkerSequence")) //Ignoring MarkerSequence for the moment. TODO: check what to do with MarkerSequence { sequence* Sequence=new sequence; Ztring Asset_Id; if (IsDcp && !strcmp(NameSpace, AlItemNs)) { if (!strcmp(AlItemName, "MainPicture")) Sequence->StreamKind=Stream_Video; else if (!strcmp(AlItemName, "MainSound")) Sequence->StreamKind=Stream_Audio; } else if (IsImf && IsSmpteSt2067_2(AlItemNs)) { if (!strcmp(AlItemName, "MainImageSequence")) Sequence->StreamKind=Stream_Video; else if (!strcmp(AlItemName, "MainAudioSequence")) Sequence->StreamKind=Stream_Audio; } for (XMLElement* File_Item=AssetList_Item->FirstChildElement(); File_Item; File_Item=File_Item->NextSiblingElement()) { //Id if (MatchQName(File_Item, "Id", NameSpace) && Asset_Id.empty()) Asset_Id.From_UTF8(File_Item->GetText()); //ResourceList if (IsImf && MatchQName(File_Item, "ResourceList", NameSpace)) { for (XMLElement* ResourceList_Item=File_Item->FirstChildElement(); ResourceList_Item; ResourceList_Item=ResourceList_Item->NextSiblingElement()) { //Resource if (MatchQName(ResourceList_Item, "Resource", NameSpace)) { Ztring Resource_Id; resource* Resource=new resource; for (XMLElement* Resource_Item=ResourceList_Item->FirstChildElement(); Resource_Item; Resource_Item=Resource_Item->NextSiblingElement()) { const char* ResText=Resource_Item->GetText(); if (!ResText) continue; const char *ResItemNs, *ResItemName = LocalName(Resource_Item, ResItemNs); if (!ResItemNs || strcmp(ResItemNs, NameSpace)) continue; // item has wrong namespace //EditRate if (!strcmp(ResItemName, "EditRate")) { Resource->EditRate=atof(ResText); const char* EditRate2=strchr(ResText, ' '); if (EditRate2!=NULL) { float64 EditRate2f=atof(EditRate2); if (EditRate2f) Resource->EditRate/=EditRate2f; } } //EntryPoint if (!strcmp(ResItemName, "EntryPoint")) { Resource->IgnoreEditsBefore=atoi(ResText); if (Resource->IgnoreEditsAfter!=(int64u)-1) Resource->IgnoreEditsAfter+=Resource->IgnoreEditsBefore; } //Id if (!strcmp(ResItemName, "Id") && Resource_Id.empty()) Resource_Id.From_UTF8(ResText); //SourceDuration if (!strcmp(ResItemName, "SourceDuration")) Resource->IgnoreEditsAfter=Resource->IgnoreEditsBefore+atoi(ResText); //TrackFileId if (!strcmp(ResItemName, "TrackFileId")) Resource->FileNames.push_back(Ztring().From_UTF8(ResText)); } if (Resource->FileNames.empty()) Resource->FileNames.push_back(Resource_Id); Sequence->AddResource(Resource); } } } } if (Sequence->Resources.empty()) { resource* Resource=new resource; Resource->FileNames.push_back(Asset_Id); Sequence->AddResource(Resource); } Sequence->StreamID=ReferenceFiles->Sequences_Size()+1; ReferenceFiles->AddSequence(Sequence); } } } } } } } } Element_Offset=File_Size; //Getting files names FileName Directory(File_Name); Ztring DirPath = Directory.Path_Get(); if (!DirPath.empty()) DirPath += PathSeparator; Ztring Assetmap_FileName=DirPath+__T("ASSETMAP.xml"); bool IsOk=false; if (File::Exists(Assetmap_FileName)) IsOk=true; else { Assetmap_FileName.resize(Assetmap_FileName.size()-4); //Old fashion, without ".xml" if (File::Exists(Assetmap_FileName)) IsOk=true; } if (IsOk) { MediaInfo_Internal MI; MI.Option(__T("File_KeepInfo"), __T("1")); Ztring ParseSpeed_Save=MI.Option(__T("ParseSpeed_Get"), __T("")); Ztring Demux_Save=MI.Option(__T("Demux_Get"), __T("")); MI.Option(__T("ParseSpeed"), __T("0")); MI.Option(__T("Demux"), Ztring()); MI.Option(__T("File_IsReferenced"), __T("1")); size_t MiOpenResult=MI.Open(Assetmap_FileName); MI.Option(__T("ParseSpeed"), ParseSpeed_Save); //This is a global value, need to reset it. TODO: local value MI.Option(__T("Demux"), Demux_Save); //This is a global value, need to reset it. TODO: local value if (MiOpenResult && (MI.Get(Stream_General, 0, General_Format)==__T("DCP AM") || MI.Get(Stream_General, 0, General_Format)==__T("IMF AM"))) { MergeFromAm(((File_DcpAm*)MI.Info)->Streams); } } ReferenceFiles->FilesForStorage=true; //All should be OK... return true; }
//--------------------------------------------------------------------------- bool File_Dxw::FileHeader_Begin() { XMLDocument document; if (!FileHeader_Begin_XML(document)) return false; { XMLElement* Root=document.FirstChildElement("indexFile"); if (Root) { const char* Attribute=Root->Attribute("xmlns"); if (Attribute==NULL || Ztring().From_UTF8(Attribute)!=__T("urn:digimetrics-xml-wrapper")) { Reject("DXW"); return false; } Accept("DXW"); Fill(Stream_General, 0, General_Format, "DXW"); ReferenceFiles_Accept(this, Config); #if defined(MEDIAINFO_REFERENCES_YES) XMLElement* Track=Root->FirstChildElement(); while (Track) { if (string(Track->Value())=="clip") { sequence* Sequence=new sequence; Attribute=Track->Attribute("file"); if (Attribute) { Sequence->AddFileName(Ztring().From_UTF8(Attribute)); Attribute=Track->Attribute("type"); if (Attribute) { Ztring StreamKind; StreamKind.From_UTF8(Attribute); if (StreamKind==__T("video")) Sequence->StreamKind=Stream_Video; if (StreamKind==__T("audio")) Sequence->StreamKind=Stream_Audio; if (StreamKind==__T("data")) Sequence->StreamKind=Stream_Text; //Not sure this is a right mapping, but this is only used when file is missing } Attribute=Track->Attribute("source"); if (Attribute) { Ztring StreamKind; StreamKind.From_UTF8(Attribute); if (StreamKind==__T("main")) Sequence->IsMain=true; } Attribute=Track->Attribute("default_timecode"); if (Attribute) { Sequence->Config["File_DefaultTimeCode"].From_UTF8(Attribute); } Sequence->StreamID=ReferenceFiles->Sequences_Size()+1; } Attribute=Track->Attribute("framerate"); if (Attribute) { Sequence->FrameRate_Set(Ztring().From_UTF8(Attribute).To_float64()); Attribute=Track->Attribute("type"); if (Attribute) { Ztring StreamKind; StreamKind.From_UTF8(Attribute); if (StreamKind==__T("video")) Sequence->StreamKind=Stream_Video; if (StreamKind==__T("audio")) Sequence->StreamKind=Stream_Audio; if (StreamKind==__T("data")) Sequence->StreamKind=Stream_Text; //Not sure this is a right mapping, but this is only used when file is missing } XMLElement* Frame=Track->FirstChildElement(); while (Frame) { if (string(Frame->Value())=="frame") { Attribute=Frame->Attribute("file"); if (Attribute) Sequence->AddFileName(Ztring().From_UTF8(Attribute)); } Frame=Frame->NextSiblingElement(); } } Sequence->StreamID=ReferenceFiles->Sequences_Size()+1; ReferenceFiles->AddSequence(Sequence); } Track=Track->NextSiblingElement(); } #endif //MEDIAINFO_REFERENCES_YES } else { Reject("DXW"); return false; } } Element_Offset=File_Size; //All should be OK... return true; }