X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fprojecttree%2Fproxyclipjob.cpp;h=dc228eb59bb2637d32f862edab340ff7fbc18258;hb=56cc4b662e44027d74be5d31c32b4eb2432fab99;hp=dd0171a4d071983180c22b5cb2ce5226a6974e7d;hpb=94ef97850a20b048dc536b1a3b40057504452b47;p=kdenlive diff --git a/src/projecttree/proxyclipjob.cpp b/src/projecttree/proxyclipjob.cpp index dd0171a4..dc228eb5 100644 --- a/src/projecttree/proxyclipjob.cpp +++ b/src/projecttree/proxyclipjob.cpp @@ -25,8 +25,11 @@ #include #include -ProxyJob::ProxyJob(JOBTYPE type, CLIPTYPE cType, const QString &id, QStringList parameters) : AbstractClipJob(type, cType, id, parameters) +ProxyJob::ProxyJob(CLIPTYPE cType, const QString &id, QStringList parameters) : AbstractClipJob(PROXYJOB, cType, id, parameters), + m_jobDuration(0), + m_isFfmpegJob(true) { + m_jobStatus = JOBWAITING; description = i18n("proxy"); m_dest = parameters.at(0); m_src = parameters.at(1); @@ -34,45 +37,54 @@ ProxyJob::ProxyJob(JOBTYPE type, CLIPTYPE cType, const QString &id, QStringList m_proxyParams = parameters.at(3); m_renderWidth = parameters.at(4).toInt(); m_renderHeight = parameters.at(5).toInt(); + replaceClip = true; } -QProcess *ProxyJob::startJob(bool *ok) +void ProxyJob::startJob() { // Special case: playlist clips (.mlt or .kdenlive project files) + m_jobDuration = 0; if (clipType == PLAYLIST) { // change FFmpeg params to MLT format + m_isFfmpegJob = false; QStringList mltParameters; - mltParameters << m_src; - mltParameters << "-consumer" << "avformat:" + m_dest; - QStringList params = m_proxyParams.split('-', QString::SkipEmptyParts); + mltParameters << m_src; + mltParameters << "-consumer" << "avformat:" + m_dest; + QStringList params = m_proxyParams.split('-', QString::SkipEmptyParts); - foreach(QString s, params) { - s = s.simplified(); - if (s.count(' ') == 0) { - s.append("=1"); - } - else s.replace(' ', '='); - mltParameters << s; - } + foreach(const QString &s, params) { + QString t = s.simplified(); + if (t.count(' ') == 0) { + t.append("=1"); + } + else t.replace(' ', '='); + mltParameters << t; + } - mltParameters.append(QString("real_time=-%1").arg(KdenliveSettings::mltthreads())); + mltParameters.append(QString("real_time=-%1").arg(KdenliveSettings::mltthreads())); - //TODO: currently, when rendering an xml file through melt, the display ration is lost, so we enforce it manualy - double display_ratio = KdenliveDoc::getDisplayRatio(m_src); - mltParameters << "aspect=" + QString::number(display_ratio); + //TODO: currently, when rendering an xml file through melt, the display ration is lost, so we enforce it manualy + double display_ratio; + if (m_src.startsWith("consumer:")) display_ratio = KdenliveDoc::getDisplayRatio(m_src.section(":", 1)); + else display_ratio = KdenliveDoc::getDisplayRatio(m_src); + mltParameters << "aspect=" + QString::number(display_ratio); + + // Ask for progress reporting + mltParameters << "progress=1"; - QProcess *myProcess = new QProcess; - myProcess->setProcessChannelMode(QProcess::MergedChannels); - myProcess->start(KdenliveSettings::rendererpath(), mltParameters); - myProcess->waitForStarted(); - return myProcess; + m_jobProcess = new QProcess; + m_jobProcess->setProcessChannelMode(QProcess::MergedChannels); + m_jobProcess->start(KdenliveSettings::rendererpath(), mltParameters); + m_jobProcess->waitForStarted(); } else if (clipType == IMAGE) { + m_isFfmpegJob = false; // Image proxy QImage i(m_src); if (i.isNull()) { - *ok = false; - return NULL; + m_errorMessage.append(i18n("Cannot load image %1.", m_src)); + setStatus(JOBCRASHED); + return; } QImage proxy; @@ -114,24 +126,90 @@ QProcess *ProxyJob::startJob(bool *ok) processed.save(m_dest); } else proxy.save(m_dest); - *ok = true; - return NULL; + setStatus(JOBDONE); + return; } else { + m_isFfmpegJob = true; QStringList parameters; parameters << "-i" << m_src; QString params = m_proxyParams; - foreach(QString s, params.split(' ')) - parameters << s; + foreach(const QString &s, params.split(' ')) + parameters << s; // Make sure we don't block when proxy file already exists parameters << "-y"; parameters << m_dest; - QProcess *myProcess = new QProcess; - myProcess->setProcessChannelMode(QProcess::MergedChannels); - myProcess->start("ffmpeg", parameters); - myProcess->waitForStarted(); - return myProcess; + m_jobProcess = new QProcess; + m_jobProcess->setProcessChannelMode(QProcess::MergedChannels); + m_jobProcess->start(KdenliveSettings::ffmpegpath(), parameters, QIODevice::ReadOnly); + m_jobProcess->waitForStarted(); + } + while (m_jobProcess->state() != QProcess::NotRunning) { + processLogInfo(); + if (m_jobStatus == JOBABORTED) { + emit cancelRunningJob(m_clipId, cancelProperties()); + m_jobProcess->close(); + m_jobProcess->waitForFinished(); + QFile::remove(m_dest); + } + m_jobProcess->waitForFinished(400); + } + + if (m_jobStatus != JOBABORTED) { + int result = m_jobProcess->exitStatus(); + if (result == QProcess::NormalExit) { + if (QFileInfo(m_dest).size() == 0) { + // File was not created + processLogInfo(); + m_errorMessage.append(i18n("Failed to create proxy clip.")); + setStatus(JOBCRASHED); + } + else setStatus(JOBDONE); + } + else if (result == QProcess::CrashExit) { + // Proxy process crashed + QFile::remove(m_dest); + setStatus(JOBCRASHED); + } + } + + delete m_jobProcess; + return; +} + +void ProxyJob::processLogInfo() +{ + if (!m_jobProcess || m_jobStatus == JOBABORTED) return; + QString log = m_jobProcess->readAll(); + if (!log.isEmpty()) m_logDetails.append(log + '\n'); + else return; + int progress; + if (m_isFfmpegJob) { + // Parse FFmpeg output + if (m_jobDuration == 0) { + if (log.contains("Duration:")) { + QString data = log.section("Duration:", 1, 1).section(',', 0, 0).simplified(); + QStringList numbers = data.split(':'); + m_jobDuration = (int) (numbers.at(0).toInt() * 3600 + numbers.at(1).toInt() * 60 + numbers.at(2).toDouble()); + } + } + else if (log.contains("time=")) { + QString time = log.section("time=", 1, 1).simplified().section(' ', 0, 0); + if (time.contains(':')) { + QStringList numbers = time.split(':'); + progress = numbers.at(0).toInt() * 3600 + numbers.at(1).toInt() * 60 + numbers.at(2).toDouble(); + } + else progress = (int) time.toDouble(); + emit jobProgress(m_clipId, (int) (100.0 * progress / m_jobDuration), jobType); + } + } + else { + // Parse MLT output + if (log.contains("percentage:")) { + progress = log.section("percentage:", 1).simplified().section(' ', 0, 0).toInt(); + emit jobProgress(m_clipId, progress, jobType); + } } } @@ -151,4 +229,19 @@ stringMap ProxyJob::cancelProperties() return props; } +const QString ProxyJob::statusMessage() +{ + QString statusInfo; + switch (m_jobStatus) { + case JOBWORKING: + statusInfo = i18n("Creating proxy"); + break; + case JOBWAITING: + statusInfo = i18n("Waiting - proxy"); + break; + default: + break; + } + return statusInfo; +}