Ejemplo n.º 1
0
//---------------------------------------------------------------------------
void FileInformation::Export_XmlGz (const QString &ExportFileName, const activefilters& filters)
{
    stringstream Data;

    // Header
    Data<<"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
    Data<<"<!-- Created by QCTools " << Version << " -->\n";
    Data<<"<ffprobe:ffprobe xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ffprobe='http://www.ffmpeg.org/schema/ffprobe' xsi:schemaLocation='http://www.ffmpeg.org/schema/ffprobe ffprobe.xsd'>\n";
    Data<<"    <program_version version=\"" << FFmpeg_Glue::FFmpeg_Version() << "\" copyright=\"Copyright (c) 2007-" << FFmpeg_Glue::FFmpeg_Year() << " the FFmpeg developers\" build_date=\"" __DATE__ "\" build_time=\"" __TIME__ "\" compiler_ident=\"" << FFmpeg_Glue::FFmpeg_Compiler() << "\" configuration=\"" << FFmpeg_Glue::FFmpeg_Configuration() << "\"/>\n";
    Data<<"\n";
    Data<<"    <library_versions>\n";
    Data<<FFmpeg_Glue::FFmpeg_LibsVersion();
    Data<<"    </library_versions>\n";

    Data<<"    <frames>\n";

    // From stats
    for (size_t Pos=0; Pos<Stats.size(); Pos++)
    {
        if (Stats[Pos])
        {
            if(Stats[Pos]->Type_Get() == Type_Video && Glue)
            {
                auto videoStats = static_cast<VideoStats*>(Stats[Pos]);
                videoStats->setWidth(Glue->Width_Get());
                videoStats->setHeight(Glue->Height_Get());
            }
            Data<<Stats[Pos]->StatsToXML(filters);
        }
    }

    // Footer
    Data<<"    </frames>";

    QString streamsAndFormats;
    QXmlStreamWriter writer(&streamsAndFormats);
    writer.setAutoFormatting(true);
    writer.setAutoFormattingIndent(4);

    if(streamsStats)
        streamsStats->writeToXML(&writer);

    if(formatStats)
        formatStats->writeToXML(&writer);

    // add indentation
    QStringList splitted = streamsAndFormats.split("\n");
    for(size_t i = 0; i < splitted.length(); ++i)
        splitted[i] = QString(qAbs(writer.autoFormattingIndent()), writer.autoFormattingIndent() > 0 ? ' ' : '\t') + splitted[i];
    streamsAndFormats = splitted.join("\n");

    Data<<streamsAndFormats.toStdString() << "\n\n";

    Data<<"</ffprobe:ffprobe>";

    SharedFile file;
    QString name;

    if(ExportFileName.isEmpty())
    {
        file = SharedFile(new QTemporaryFile());
        QFileInfo info(fileName() + ".qctools.xml.gz");
        name = info.fileName();
    } else {
        file = SharedFile(new QFile(ExportFileName));
        QFileInfo info(ExportFileName);
        name = info.fileName();
    }

    string DataS=Data.str();
    uLongf Buffer_Size=65536;

    if(file->open(QIODevice::ReadWrite))
    {
        if(name.endsWith(".qctools.xml"))
        {
            auto bytesLeft = Data.str().size();
            auto writePtr = DataS.c_str();
            auto totalBytesWritten = 0;

            while(bytesLeft) {
                auto bytesToWrite = std::min(size_t(Buffer_Size), bytesLeft);
                auto bytesWritten = file->write(writePtr, bytesToWrite);
                totalBytesWritten += bytesWritten;

                Q_EMIT statsFileGenerationProgress(totalBytesWritten, DataS.size());

                writePtr += bytesToWrite;
                bytesLeft -= bytesWritten;

                if(bytesWritten != bytesToWrite)
                    break;
            }
        } else {
            char* Buffer=new char[Buffer_Size];
            z_stream strm;
            strm.next_in = (Bytef *) DataS.c_str();
            strm.avail_in = DataS.size() ;
            strm.total_out = 0;
            strm.zalloc = Z_NULL;
            strm.zfree = Z_NULL;
            if (deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15 + 16, 8, Z_DEFAULT_STRATEGY)>=0) // 15 + 16 are magic values for gzip
            {
                do
                {
                    strm.next_out = (unsigned char*) Buffer;
                    strm.avail_out = Buffer_Size;
                    if (deflate(&strm, Z_FINISH)<0)
                        break;
                    file->write(Buffer, Buffer_Size-strm.avail_out);

                    Q_EMIT statsFileGenerationProgress((char*) strm.next_in - DataS.c_str(), DataS.size());
                }
                while (strm.avail_out == 0);
                deflateEnd (&strm);
            }
            delete[] Buffer;
        }

        file->flush();
        file->seek(0);
    }

    Q_EMIT statsFileGenerated(file, name);
    m_commentsUpdated = false;
}