예제 #1
0
//---------------------------------------------------------------------------
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);
}
예제 #2
0
//---------------------------------------------------------------------------
// 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;
}
예제 #3
0
//---------------------------------------------------------------------------
// 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;
    }
}
예제 #4
0
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");
}
예제 #5
0
//---------------------------------------------------------------------------
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();
}
예제 #7
0
//---------------------------------------------------------------------------
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;
}
예제 #8
0
//---------------------------------------------------------------------------
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();
}
예제 #9
0
//---------------------------------------------------------------------------
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;
}