//--------------------------------------------------------------------------- size_t Reader_libcurl::Format_Test_PerParser(MediaInfo_Internal* MI, const String &File_Name) { #if defined MEDIAINFO_LIBCURL_DLL_RUNTIME if (libcurl_Module_Count==0) return 0; //No libcurl library #endif //defined MEDIAINFO_LIBCURL_DLL_RUNTIME Curl_Data=new curl_data(); Curl_Data->Curl=curl_easy_init(); if (Curl_Data->Curl==NULL) return 0; #if MEDIAINFO_NEXTPACKET if (MI->Config.NextPacket_Get()) { Curl_Data->CurlM=curl_multi_init( ); if (Curl_Data->CurlM==NULL) return 0; CURLMcode CodeM=curl_multi_add_handle(Curl_Data->CurlM, Curl_Data->Curl); if (CodeM!=CURLM_OK) return 0; Curl_Data->NextPacket=true; } #endif //MEDIAINFO_NEXTPACKET Curl_Data->MI=MI; Curl_Data->File_Name=File_Name; string FileName_String=Ztring(Curl_Data->File_Name).To_Local(); if (MI->Config.File_TimeToLive_Get()) Curl_Data->Time_Max=time(0)+(time_t)MI->Config.File_TimeToLive_Get(); if (!MI->Config.File_Curl_Get(_T("UserAgent")).empty()) curl_easy_setopt(Curl_Data->Curl, CURLOPT_USERAGENT, MI->Config.File_Curl_Get(_T("UserAgent")).To_Local().c_str()); if (!MI->Config.File_Curl_Get(_T("Proxy")).empty()) curl_easy_setopt(Curl_Data->Curl, CURLOPT_PROXY, MI->Config.File_Curl_Get(_T("Proxy")).To_Local().c_str()); if (!MI->Config.File_Curl_Get(_T("HttpHeader")).empty()) { ZtringList HttpHeaderStrings; HttpHeaderStrings.Separator_Set(0, EOL); //End of line is set depending of the platform: \n on Linux, \r on Mac, or \r\n on Windows HttpHeaderStrings.Write(MI->Config.File_Curl_Get(_T("HttpHeader"))); for (size_t Pos=0; Pos<HttpHeaderStrings.size(); Pos++) curl_slist_append(Curl_Data->HttpHeader, HttpHeaderStrings[Pos].To_Local().c_str()); curl_easy_setopt(Curl_Data->Curl, CURLOPT_HTTPHEADER, Curl_Data->HttpHeader); } curl_easy_setopt(Curl_Data->Curl, CURLOPT_URL, FileName_String.c_str()); curl_easy_setopt(Curl_Data->Curl, CURLOPT_FOLLOWLOCATION, 1); curl_easy_setopt(Curl_Data->Curl, CURLOPT_MAXREDIRS, 3); curl_easy_setopt(Curl_Data->Curl, CURLOPT_WRITEFUNCTION, &libcurl_WriteData_CallBack); curl_easy_setopt(Curl_Data->Curl, CURLOPT_WRITEDATA, Curl_Data); //Test the format with buffer return Format_Test_PerParser_Continue(MI); }
//--------------------------------------------------------------------------- // Chargement CFG bool ZtringListListF::CFG_Charger () { //Read file File F(Name); int8u* Buffer=new int8u[(size_t)F.Size_Get()+1]; size_t BytesCount=F.Read(Buffer, (size_t)F.Size_Get()); F.Close(); if (BytesCount==Error) { delete[] Buffer; //Buffer=NULL; return false; } Buffer[(int32u)BytesCount]=(int8u)'\0'; //Convert File --> ZtringList ZtringList List; List.Separator_Set(0, EOL); Ztring Z1; Z1.From_UTF8((char*)Buffer, 0, BytesCount); List.Write(Z1); Ztring SeparatorT=Separator[1]; Separator[1]=__T(";"); Ztring Propriete, Valeur, Commentaire; for (size_t Pos=0; Pos<List.size(); Pos++) { Ztring &Lu=List(Pos); if (Lu.find(__T("="))>0) { //Obtention du Name Propriete=Lu.SubString(Ztring(), __T("=")); NettoyerEspaces(Propriete); //Obtention de la valeur Valeur=Lu.SubString(__T("="), __T(";"), 0, Ztring_AddLastItem); NettoyerEspaces(Valeur); } //Obtention du commentaire Commentaire=Lu.SubString(__T(";"), Ztring(), 0, Ztring_AddLastItem); NettoyerEspaces(Commentaire); //Ecriture push_back((Propriete+__T(";")+Valeur+__T(";")+Commentaire).c_str()); //Visual C++ 6 is old... } Separator[1]=SeparatorT; delete[] Buffer; //Buffer=NULL; return true; }
//--------------------------------------------------------------------------- // Set void InfoMap::Write(const Ztring &NewInfoMap) { clear(); if (NewInfoMap.empty()) return; size_t Pos1=0, Pos2_EOL=0, Pos2_Separator=0; while (Pos2_EOL!=(size_t)-1) { Pos2_EOL=NewInfoMap.find(__T('\n'), Pos1); Pos2_Separator=NewInfoMap.find(__T(';'), Pos1); if (Pos2_Separator<Pos2_EOL) { ZtringList List; List.Write(NewInfoMap.substr(Pos1, Pos2_EOL-Pos1)); insert (pair<Ztring, ZtringList>(NewInfoMap.substr(Pos1, Pos2_Separator-Pos1), List)); } Pos1=Pos2_EOL+1; } }
void File_OtherText::Read_Buffer_Continue() { if (Buffer_Size<0x200) { Element_WaitForMoreData(); return; } Element_Offset=File_Size-(File_Offset+Buffer_Offset); Ztring Format, FormatMore, Codec; Ztring File; ZtringList Lines; //Feed File and Lines File.From_UTF8((const char*)Buffer, Buffer_Size>65536?65536:Buffer_Size); if (File.empty()) File.From_Local((const char*)Buffer, Buffer_Size>65536?65536:Buffer_Size); // Trying from local code page if (File.size()<0x100) { File.From_Unicode((wchar_t*)Buffer, 0, Buffer_Size/sizeof(wchar_t)); //Unicode with BOM //TODO: Order of bytes (big or Little endian) if (File.size()<0x100) { Reject("Other text"); return; } } if (File.size()>0x1000) File.resize(0x1000); //Do not work on too big File.FindAndReplace(__T("\r\n"), __T("\n"), 0, Ztring_Recursive); File.FindAndReplace(__T("\r"), __T("\n"), 0, Ztring_Recursive); Lines.Separator_Set(0, __T("\n")); Lines.Write(File); Lines.resize(0x20); if (Lines[0]==__T("[Script Info]") && (Lines.Find(__T("ScriptType: v4.00"))!=Error || Lines.Find(__T("Script Type: V4.00"))!=Error) && Lines.Find(__T("[V4 Styles]"))!=Error ) { Format=__T("SSA"); FormatMore=__T("SubStation Alpha"); Codec=__T("SSA"); } else if (Lines[0]==__T("[Script Info]") && (Lines.Find(__T("ScriptType: v4.00+"))!=Error || Lines.Find(__T("Script Type: V4.00+"))!=Error) && Lines.Find(__T("[V4+ Styles]"))!=Error ) { Format=__T("ASS"); FormatMore=__T("Advanced SubStation Alpha"); Codec=__T("ASS"); } else if (Lines[0].size()>24 && Lines[0][ 0]==__T('0') && Lines[0][ 1]==__T('0') && Lines[0][ 2]==__T(':') && Lines[0][ 5]==__T(':') && Lines[0][ 8]==__T(':') && Lines[0][11]==__T(' ') && Lines[0][12]==__T('0') && Lines[0][13]==__T('0') && Lines[0][14]==__T(':') && Lines[0][17]==__T(':') && Lines[0][20]==__T(':') && Lines[0][23]==__T(' ') ) { Format=__T("Adobe encore DVD"); Codec=__T("Adobe"); } else if (Lines[0].size()==11 && Lines[0][0]==__T('-') && Lines[0][1]==__T('-') && Lines[0][2]==__T('>') && Lines[0][3]==__T('>') && Lines[0][4]==__T(' ') && Lines[0][5]==__T('0') && Lines[1].empty()!=true ) { Format=__T("AQTitle"); Codec=__T("AQTitle"); } else if (Lines[0].size()>28 && Lines[0][ 0]==__T('0') && Lines[0][ 1]==__T('0') && Lines[0][ 2]==__T(':') && Lines[0][ 5]==__T(':') && Lines[0][ 8]==__T(':') && Lines[0][11]==__T(' ') && Lines[0][12]==__T(',') && Lines[0][13]==__T(' ') && Lines[0][14]==__T('0') && Lines[0][15]==__T('0') && Lines[0][16]==__T(':') && Lines[0][19]==__T(':') && Lines[0][22]==__T(':') && Lines[0][25]==__T(' ') && Lines[0][16]==__T(',') && Lines[0][27]==__T(' ') ) { Format=__T("Captions 32"); Codec=__T("Caption 32"); } else if (Lines[0].size()==23 && Lines[0]==__T("*Timecode type: PAL/EBU") && Lines[1].empty() && Lines[2].size()==23 && Lines[2][ 0]==__T('0') && Lines[2][ 1]==__T('0') && Lines[2][ 2]==__T(':') && Lines[2][ 5]==__T(':') && Lines[2][ 8]==__T(':') && Lines[2][11]==__T(' ') && Lines[2][12]==__T('0') && Lines[2][13]==__T('0') && Lines[2][14]==__T(':') && Lines[2][17]==__T(':') && Lines[2][20]==__T(':') && Lines[2].size()>0 ) { Format=__T("Captions Inc"); Codec=__T("Captions inc"); } else if (Lines[0].size()>1 && Lines[0][0]==__T('*') && Lines.Find(__T("** Caption Number 1"))!=Error ) { Format=__T("Cheeta"); } else if (Lines[0].size()>10 && Lines[0][0]==__T('~') && Lines[0][1]==__T('C') && Lines[0][2]==__T('P') && Lines[0][3]==__T('C') && Lines[0][9]==__T('~') && Lines[1][ 0]==__T('0') && Lines[1][ 1]==__T('0') && Lines[1][ 2]==__T(':') && Lines[1][ 5]==__T(':') && Lines[1][ 8]==__T(':') ) { Format=__T("CPC Captioning"); Codec=__T("CPC Captioning"); } else if (Lines[0].find(__T("<SAMI>"))==0) { Format=__T("SAMI"); } else return; if (Format.empty()) return; Accept("Other text"); if (!IsSub) { Fill(Stream_General, 0, General_Format, Format); Fill(Stream_General, 0, General_Format_Info, FormatMore, true); } Stream_Prepare(Stream_Text); Fill(Stream_Text, 0, Text_Format, Format); Fill(Stream_Text, 0, Text_Codec, Codec); //No more need data Element_Begin1(Format); Element_End0(); Finish("Other text"); }
//--------------------------------------------------------------------------- bool File_Hls::FileHeader_Begin() { //Element_Size if (File_Size>1024*1024 || File_Size<10) { Reject("HLS"); return false; //HLS files are not big } if (Buffer_Size<File_Size) return false; //Wait for complete file Ztring Document; Document.From_UTF8((char*)Buffer, Buffer_Size); ZtringList Lines; size_t LinesSeparator_Pos=Document.find_first_of(__T("\r\n")); if (LinesSeparator_Pos>File_Size-1) { Reject("HLS"); return false; } Ztring LinesSeparator; if (Document[LinesSeparator_Pos]==__T('\r') && LinesSeparator_Pos+1<Document.size() && Document[LinesSeparator_Pos+1]==__T('\n')) LinesSeparator=__T("\r\n"); else if (Document[LinesSeparator_Pos]==__T('\r')) LinesSeparator=__T("\r"); else if (Document[LinesSeparator_Pos]==__T('\n')) LinesSeparator=__T("\n"); else { Reject("HLS"); return false; } Lines.Separator_Set(0, LinesSeparator); Lines.Write(Document); if (Lines(0)!=__T("#EXTM3U")) { Reject("HLS"); return false; } Accept("HLS"); Fill(Stream_General, 0, General_Format, "HLS"); ReferenceFiles=new File__ReferenceFilesHelper(this, Config); if (!IsSub) ReferenceFiles->ContainerHasNoId=true; File__ReferenceFilesHelper::reference ReferenceFile; bool IsGroup=false; for (size_t Line=0; Line<Lines.size(); Line++) { if (!Lines[Line].empty()) { if (Lines[Line].find(__T("#EXT-X-STREAM-INF"))==0) IsGroup=true; else if (Lines[Line][0]==__T('#')) ; else { if (IsGroup) { File__ReferenceFilesHelper::reference ReferenceStream; ReferenceStream.FileNames.push_back(Lines[Line]); ReferenceStream.StreamID=ReferenceFiles->References.size()+1; ReferenceFiles->References.push_back(ReferenceStream); IsGroup=false; #if MEDIAINFO_EVENTS ParserIDs[0]=MediaInfo_Parser_HlsIndex; StreamIDs_Width[0]=sizeof(size_t)*2; #endif //MEDIAINFO_EVENTS } else ReferenceFile.FileNames.push_back(Lines[Line]); } } } if (ReferenceFiles->References.empty()) { ReferenceFiles->References.push_back(ReferenceFile); ReferenceFiles->TestContinuousFileNames=true; } Element_Offset=File_Size; //All should be OK... return true; }
//--------------------------------------------------------------------------- void GUI_Main_Core_Table::contextMenuEvent (QContextMenuEvent* Event) { //Retrieving data QTableWidgetItem* Item=itemAt(Event->pos()); if (Item==NULL) return; string FileName=FileName_Before+item(Item->row(), 0)->text().toLocal8Bit().data(); string Field=horizontalHeaderItem(Item->column())->text().toLocal8Bit().data(); ZtringList History; History.Write(C->History(FileName, Field)); Ztring Date; if (Field=="OriginationDate" || Field=="OriginationTime" || Field=="ICRD") { Date=C->FileDate_Get(FileName); if (Date.size()>=10+1+8) { if (Date.size()>=10+1+8) Date.resize(10+1+8); if (Field=="ICRD") Date.insert(0, "&Set ICRD to file creation timestamp ("); //If you change this, change at the end of method too else Date.insert(0, "&Set originationDate and Time to file creation timestamp ("); //If you change this, change at the end of method too Date.append(")"); } else Date.clear(); } //Creating menu QMenu menu(this); //Handling AllFiles display { menu.addAction(new QAction("Fill all open files with this field value", this)); //If you change this, change the test text too menu.addSeparator(); } //Handling Clear display if (!item(Item->row(), Item->column())->text().isEmpty() && C->IsValid(FileName, Field, string())) { menu.addAction(new QAction("Clear this value", this)); //If you change this, change the test text too menu.addSeparator(); } //Handling date display if (!Date.empty()) { menu.addAction(new QAction(QString().fromUtf8(Date.To_Local().c_str()), this)); menu.addSeparator(); } //Handling history display size_t Pos=History.size(); if (!History.empty()) do { Pos--; QString Text=QString().fromUtf8(History[Pos].To_Local().c_str()); if (!Text.isEmpty()) { QAction* Action=new QAction(Text, this); menu.addAction(Action); } } while (Pos>0); //Displaying QAction* Action=menu.exec(Event->globalPos()); if (Action==NULL) return; //Retrieving data QString Text=Action->text(); //Special cases if (Text=="Fill all open files with this field value") //If you change this, change the creation text too { for (int Row=0; Row<rowCount(); Row++) { item(Row, Item->column())->setText(QString().fromUtf8(Ztring(C->Get(FileName, Field)).To_Local().c_str())); dataChanged(indexFromItem(item(Row, Item->column())), indexFromItem(item(Row, Item->column()))); //Special cases if (Field=="UMID" || Field=="LoudnessValue" || Field=="LoudnessRange" || Field=="MaxTruePeakLevel" || Field=="MaxMomentaryLoudness" || Field=="MaxShortTermLoudness") { //Changing BextVersion Enabled value SetText (*Item, "BextVersion"); SetEnabled(*Item, "BextVersion"); } } return; } if (Text=="Clear this value") //If you change this, change the creation text too Text.clear(); //Filling if (Text.contains("&Set ")) //If you change this, change the creation text too { Text=Text.remove("&Set ICRD to file creation timestamp ("); //If you change this, change the creation text too Text=Text.remove("&Set originationDate and Time to file creation timestamp ("); //If you change this, change the creation text too Text=Text.remove(")"); //If you change this, change the creation text too if (horizontalHeaderItem(Item->column())->text()==QString().fromUtf8("ICRD")) { item(Item->row(), Item->column())->setText(Text); dataChanged(indexFromItem(item(Item->row(), Item->column())), indexFromItem(item(Item->row(), Item->column()))); } else { QString Date=Text; Date.remove(10, 1+12); QString Time=Text; Time.remove(0, 10+1); Time.remove(8, 4); int Date_Pos=Item->column()+(horizontalHeaderItem(Item->column())->text()==QString().fromUtf8("OriginationDate")?0:-1); int Time_Pos=Item->column()+(horizontalHeaderItem(Item->column())->text()==QString().fromUtf8("OriginationTime")?0:1); item(Item->row(), Date_Pos)->setText(Date); dataChanged(indexFromItem(item(Item->row(), Date_Pos)), indexFromItem(item(Item->row(), Date_Pos))); item(Item->row(), Time_Pos)->setText(Time); dataChanged(indexFromItem(item(Item->row(), Time_Pos)), indexFromItem(item(Item->row(), Time_Pos))); } } else { item(Item->row(), Item->column())->setText(Text); dataChanged(indexFromItem(item(Item->row(), Item->column())), indexFromItem(item(Item->row(), Item->column()))); } //Menu Main->Menu_Update(); }
//--------------------------------------------------------------------------- size_t Reader_libcurl::Format_Test(MediaInfo_Internal* MI, const String &File_Name) { #if defined MEDIAINFO_LIBCURL_DLL_RUNTIME if (libcurl_Module_Count==0) return 0; //No libcurl library #endif //defined MEDIAINFO_LIBCURL_DLL_RUNTIME //Configuring curl_data Curl_Data; Curl_Data.Curl=curl_easy_init(); Curl_Data.MI=MI; Curl_Data.File_Name=File_Name; string FileName_String=Ztring(Curl_Data.File_Name).To_Local(); if (MI->Config.File_TimeToLive_Get()) Curl_Data.Time_Max=time(0)+(time_t)MI->Config.File_TimeToLive_Get(); if (!MI->Config.File_Curl_Get(_T("UserAgent")).empty()) curl_easy_setopt(Curl_Data.Curl, CURLOPT_USERAGENT, MI->Config.File_Curl_Get(_T("UserAgent")).To_Local().c_str()); if (!MI->Config.File_Curl_Get(_T("Proxy")).empty()) curl_easy_setopt(Curl_Data.Curl, CURLOPT_PROXY, MI->Config.File_Curl_Get(_T("Proxy")).To_Local().c_str()); struct curl_slist* HttpHeader=NULL; if (!MI->Config.File_Curl_Get(_T("HttpHeader")).empty()) { ZtringList HttpHeaderStrings; HttpHeaderStrings.Separator_Set(0, EOL); //End of line is set depending of the platform: \n on Linux, \r on Mac, or \r\n on Windows HttpHeaderStrings.Write(MI->Config.File_Curl_Get(_T("HttpHeader"))); for (size_t Pos=0; Pos<HttpHeaderStrings.size(); Pos++) curl_slist_append(HttpHeader, HttpHeaderStrings[Pos].To_Local().c_str()); curl_easy_setopt(Curl_Data.Curl, CURLOPT_HTTPHEADER, HttpHeader); } curl_easy_setopt(Curl_Data.Curl, CURLOPT_URL, FileName_String.c_str()); curl_easy_setopt(Curl_Data.Curl, CURLOPT_FOLLOWLOCATION, 1); curl_easy_setopt(Curl_Data.Curl, CURLOPT_MAXREDIRS, 3); curl_easy_setopt(Curl_Data.Curl, CURLOPT_WRITEFUNCTION, &libcurl_WriteData_CallBack); curl_easy_setopt(Curl_Data.Curl, CURLOPT_WRITEDATA, &Curl_Data); //Parsing CURLcode Result; do { //GoTo if (Curl_Data.File_GoTo!=(int64u)-1) { #ifdef MEDIAINFO_DEBUG std::cout<<std::hex<<Curl_Data.File_Offset-Curl_Data.Debug_BytesRead<<" - "<<Curl_Data.File_Offset<<" : "<<std::dec<<Curl_Data.Debug_BytesRead<<" bytes"<<std::endl; Curl_Data.Debug_BytesRead=0; Curl_Data.Debug_Count++; #endif //MEDIAINFO_DEBUG Curl_Data.File_Offset=Curl_Data.File_GoTo; if (Curl_Data.File_GoTo<0x80000000) { //We do NOT use large version if we can, because some version (tested: 7.15 linux) do NOT like large version (error code 18) long File_GoTo_Long=(long)Curl_Data.File_GoTo; curl_easy_setopt(Curl_Data.Curl, CURLOPT_RESUME_FROM, File_GoTo_Long); } else { curl_off_t File_GoTo_Off=(curl_off_t)Curl_Data.File_GoTo; curl_easy_setopt(Curl_Data.Curl, CURLOPT_RESUME_FROM_LARGE, File_GoTo_Off); } MI->Open_Buffer_Init((int64u)-1, Curl_Data.File_GoTo); Curl_Data.File_GoTo=(int64u)-1; } //Parsing Result=curl_easy_perform(Curl_Data.Curl); } while (Result==CURLE_WRITE_ERROR && Curl_Data.File_GoTo!=(int64u)-1); #ifdef MEDIAINFO_DEBUG std::cout<<std::hex<<Curl_Data.File_Offset-Curl_Data.Debug_BytesRead<<" - "<<Curl_Data.File_Offset<<" : "<<std::dec<<Curl_Data.Debug_BytesRead<<" bytes"<<std::endl; std::cout<<"Total: "<<std::dec<<Curl_Data.Debug_BytesRead_Total<<" bytes in "<<Curl_Data.Debug_Count<<" blocks"<<std::endl; #endif //MEDIAINFO_DEBUG MI->Open_Buffer_Finalize(); //Cleanup if (HttpHeader) curl_slist_free_all(HttpHeader); curl_easy_cleanup(Curl_Data.Curl); return 1; }
//--------------------------------------------------------------------------- void File_Y4m::FileHeader_Parse() { //Parsing Ztring Header; Get_Local(HeaderEnd, Header, "Data"); ZtringList List; List.Separator_Set(0, " "); List.Write(Header); int64u Width=0, Height=0, Multiplier=0, Divisor=1; float64 FrameRate=0; for (size_t Pos=1; Pos<List.size(); Pos++) { if (!List[Pos].empty()) { switch (List[Pos][0]) { case 'A' : //Pixel aspect ratio { ZtringList Value; Value.Separator_Set(0, ":"); Value.Write(List[Pos].substr(1)); if (Value.size()==2) { float64 x=Value[0].To_float64(); float64 y=Value[1].To_float64(); if (x && y) Fill(Stream_Video, 0, Video_PixelAspectRatio, x/y, 3); } } break; case 'C' : //Color space if (List[Pos]==__T("C420jpeg") || List[Pos]==__T("C420paldv") || List[Pos]==__T("C420")) { Fill(Stream_Video, 0, Video_ChromaSubsampling, "4:2:0"); Multiplier=3; Divisor=2; } if (List[Pos]==__T("C422")) { Fill(Stream_Video, 0, Video_ChromaSubsampling, "4:2:2"); Multiplier=2; } if (List[Pos]==__T("C444")) { Fill(Stream_Video, 0, Video_ChromaSubsampling, "4:4:4"); Multiplier=3; } break; case 'F' : //Frame rate { ZtringList Value; Value.Separator_Set(0, ":"); Value.Write(List[Pos].substr(1)); if (Value.size()==2) { float64 N=Value[0].To_float64(); float64 D=Value[1].To_float64(); if (N && D) { FrameRate=N/D; Fill(Stream_Video, 0, Video_FrameRate, FrameRate, 3); } } } break; case 'H' : //Height { Ztring Value=List[Pos].substr(1); Height=Value.To_int64u(); Fill(Stream_Video, 0, Video_Height, Height); break; } break; case 'I' : //Interlacing if (List[Pos].size()==2) switch (List[Pos][1]) { case 'p' : Fill(Stream_Video, 0, Video_ScanType, "Progressive"); break; case 't' : Fill(Stream_Video, 0, Video_ScanType, "Progressive"); Fill(Stream_Video, 0, Video_ScanOrder, "TFF"); break; case 'b' : Fill(Stream_Video, 0, Video_ScanType, "Progressive"); Fill(Stream_Video, 0, Video_ScanOrder, "BFF"); break; case 'm' : Fill(Stream_Video, 0, Video_ScanType, "Mixed"); break; default : ; } break; case 'W' : //Width { Ztring Value=List[Pos].substr(1); Width=Value.To_int64u(); Fill(Stream_Video, 0, Video_Width, Width); break; } break; default : ; } } } //Duration (we expect no meta per frame) if (Width && Height && Multiplier) { int64u Frame_ByteSize=6+Width*Height*Multiplier/Divisor; //5 for "FRAME\0" Fill(Stream_Video, 0, Video_FrameCount, File_Size/Frame_ByteSize); if (FrameRate) Fill(Stream_Video, 0, Video_BitRate, Width*Height*Multiplier/Divisor*8*FrameRate); } Finish(); }
//--------------------------------------------------------------------------- bool File_Hls::FileHeader_Begin() { //Element_Size if (File_Size>1024*1024 || File_Size<10) { Reject("HLS"); return false; //HLS files are not big } if (Buffer_Size<File_Size) return false; //Wait for complete file Ztring Document; Document.From_UTF8((char*)Buffer, Buffer_Size); ZtringList Lines; size_t LinesSeparator_Pos=Document.find_first_of(__T("\r\n")); if (LinesSeparator_Pos>File_Size-1) { Reject("HLS"); return false; } Ztring LinesSeparator; if (Document[LinesSeparator_Pos]==__T('\r') && LinesSeparator_Pos+1<Document.size() && Document[LinesSeparator_Pos+1]==__T('\n')) LinesSeparator=__T("\r\n"); else if (Document[LinesSeparator_Pos]==__T('\r')) LinesSeparator=__T("\r"); else if (Document[LinesSeparator_Pos]==__T('\n')) LinesSeparator=__T("\n"); else { Reject("HLS"); return false; } Lines.Separator_Set(0, LinesSeparator); Lines.Write(Document); if (Lines(0)!=__T("#EXTM3U")) { Reject("HLS"); return false; } Accept("HLS"); Fill(Stream_General, 0, General_Format, "HLS"); ReferenceFiles=new File__ReferenceFilesHelper(this, Config); if (!IsSub) ReferenceFiles->ContainerHasNoId=true; File__ReferenceFilesHelper::reference ReferenceFile; bool IsGroup=false; for (size_t Line=0; Line<Lines.size(); Line++) { if (!Lines[Line].empty()) { if (Lines[Line].find(__T("#EXT-X-KEY:"))==0) { ZtringListList List; List.Separator_Set(0, __T(",")); List.Separator_Set(1, __T("=")); List.Write(Lines[Line].substr(11, string::npos)); for (size_t Pos=0; Pos<List.size(); ++Pos) { if (List[Pos](0)==__T("METHOD")) { if (List[Pos](1).find(__T("AES-128"))==0) { Fill(Stream_General, 0, General_Encryption_Format, "AES"); Fill(Stream_General, 0, General_Encryption_Length, "128"); Fill(Stream_General, 0, General_Encryption_Method, "Segment"); Fill(Stream_General, 0, General_Encryption_Mode, "CBC"); Fill(Stream_General, 0, General_Encryption_Padding, "PKCS7"); Fill(Stream_General, 0, General_Encryption_InitializationVector, "Sequence number"); #if MEDIAINFO_AES //Trying to get the key from FileName.FileExt.key if (Config->Encryption_Key_Get().empty()) { File KeyFile; if (KeyFile.Open(File_Name+__T(".key"))) { if (KeyFile.Size_Get()==16) { int8u Key[16]; if (KeyFile.Read(Key, 16)==16) Config->Encryption_Key_Set(Key, 16); } else Fill(Stream_General, 0, "Encryption_Key_Problem", KeyFile.Size_Get()); } } #endif } Fill(Stream_General, 0, General_Encryption, List[Pos](1)); } } } else if (Lines[Line].find(__T("#EXT-X-STREAM-INF:"))==0) { IsGroup=true; } else if (Lines[Line][0]==__T('#')) ; else { if (IsGroup) { ReferenceFile.FileNames.push_back(Lines[Line]); ReferenceFile.StreamID=ReferenceFiles->References.size()+1; ReferenceFiles->References.push_back(ReferenceFile); IsGroup=false; ReferenceFile=File__ReferenceFilesHelper::reference(); #if MEDIAINFO_EVENTS ParserIDs[0]=MediaInfo_Parser_HlsIndex; StreamIDs_Width[0]=sizeof(size_t); #endif //MEDIAINFO_EVENTS } else ReferenceFile.FileNames.push_back(Lines[Line]); } } } if (!ReferenceFile.FileNames.empty()) { ReferenceFiles->References.push_back(ReferenceFile); Fill(Stream_General, 0, General_Format_Profile, "Media"); } else { Fill(Stream_General, 0, General_Format_Profile, "Master"); } Element_Offset=File_Size; //All should be OK... return true; }