X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fprojecttree%2Fproxyclipjob.cpp;h=ca565051694cdbfdc46f6fcf1fcbab26c12d70aa;hb=d679fbf19a2511b181570418dc7fa7c815728bcb;hp=31a67bbf681252f522b13ae660f52306e2983c31;hpb=dd604e8fc559277a2fc42a161feb0de91d3515a5;p=kdenlive diff --git a/src/projecttree/proxyclipjob.cpp b/src/projecttree/proxyclipjob.cpp index 31a67bbf..ca565051 100644 --- a/src/projecttree/proxyclipjob.cpp +++ b/src/projecttree/proxyclipjob.cpp @@ -21,14 +21,18 @@ #include "proxyclipjob.h" #include "kdenlivesettings.h" #include "kdenlivedoc.h" +#include + #include -#include +#include -ProxyJob::ProxyJob(CLIPTYPE cType, const QString &id, QStringList parameters) : AbstractClipJob(PROXYJOB, cType, id, parameters), - m_jobDuration(0), - m_isFfmpegJob(true) +ProxyJob::ProxyJob(CLIPTYPE cType, const QString &id, const 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); @@ -36,9 +40,10 @@ ProxyJob::ProxyJob(CLIPTYPE cType, const QString &id, QStringList parameters) : 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; @@ -46,45 +51,47 @@ QProcess *ProxyJob::startJob(bool *ok) // 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); - - foreach(QString s, params) { - s = s.simplified(); - if (s.count(' ') == 0) { - s.append("=1"); - } - else s.replace(' ', '='); - mltParameters << s; - } + mltParameters << m_src; + mltParameters << "-consumer" << "avformat:" + m_dest; + QStringList params = m_proxyParams.split('-', QString::SkipEmptyParts); + + 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())); - - //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); - - // Ask for progress reporting - mltParameters << "progress=1"; - - m_jobProcess = new QProcess; - m_jobProcess->setProcessChannelMode(QProcess::MergedChannels); - m_jobProcess->start(KdenliveSettings::rendererpath(), mltParameters); - m_jobProcess->waitForStarted(); - return m_jobProcess; + 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; + if (m_src.startsWith("consumer:")) display_ratio = KdenliveDoc::getDisplayRatio(m_src.section(":", 1)); + else display_ratio = KdenliveDoc::getDisplayRatio(m_src); + mltParameters << "aspect=" + QLocale().toString(display_ratio); + + // Ask for progress reporting + mltParameters << "progress=1"; + + 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; - // Images are scaled to profile size. + // Images are scaled to profile size. //TODO: Make it be configurable? if (i.width() > i.height()) proxy = i.scaledToWidth(m_renderWidth); else proxy = i.scaledToHeight(m_renderHeight); @@ -94,40 +101,40 @@ QProcess *ProxyJob::startJob(bool *ok) QMatrix matrix; switch ( m_exif ) { - case 2: - matrix.scale( -1, 1 ); - break; - case 3: - matrix.rotate( 180 ); - break; - case 4: - matrix.scale( 1, -1 ); - break; - case 5: - matrix.rotate( 270 ); - matrix.scale( -1, 1 ); - break; - case 6: - matrix.rotate( 90 ); - break; - case 7: - matrix.rotate( 90 ); - matrix.scale( -1, 1 ); - break; - case 8: - matrix.rotate( 270 ); - break; + case 2: + matrix.scale( -1, 1 ); + break; + case 3: + matrix.rotate( 180 ); + break; + case 4: + matrix.scale( 1, -1 ); + break; + case 5: + matrix.rotate( 270 ); + matrix.scale( -1, 1 ); + break; + case 6: + matrix.rotate( 90 ); + break; + case 7: + matrix.rotate( 90 ); + matrix.scale( -1, 1 ); + break; + case 8: + matrix.rotate( 270 ); + break; } processed = proxy.transformed( matrix ); processed.save(m_dest); + } else { + proxy.save(m_dest); } - else proxy.save(m_dest); - *ok = true; - return NULL; - } - else { + setStatus(JOBDONE); + return; + } else { m_isFfmpegJob = true; - QStringList parameters; + QStringList parameters; parameters << "-i" << m_src; QString params = m_proxyParams; foreach(const QString &s, params.split(' ')) @@ -138,19 +145,51 @@ QProcess *ProxyJob::startJob(bool *ok) parameters << m_dest; m_jobProcess = new QProcess; m_jobProcess->setProcessChannelMode(QProcess::MergedChannels); - m_jobProcess->start("ffmpeg", parameters); + m_jobProcess->start(KdenliveSettings::ffmpegpath(), parameters, QIODevice::ReadOnly); m_jobProcess->waitForStarted(); - QString log = m_jobProcess->readAll(); - if (!log.isEmpty()) m_errorMessage.append(log + '\n'); - return m_jobProcess; } + 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; } -int ProxyJob::processLogInfo() +void ProxyJob::processLogInfo() { - if (!m_jobProcess) return -1; + if (!m_jobProcess || m_jobStatus == JOBABORTED) return; QString log = m_jobProcess->readAll(); - if (!log.isEmpty()) m_errorMessage.append(log + '\n'); + if (!log.isEmpty()) + m_logDetails.append(log + '\n'); + else + return; + int progress; if (m_isFfmpegJob) { // Parse FFmpeg output @@ -168,17 +207,16 @@ int ProxyJob::processLogInfo() progress = numbers.at(0).toInt() * 3600 + numbers.at(1).toInt() * 60 + numbers.at(2).toDouble(); } else progress = (int) time.toDouble(); - return (int) (100.0 * progress / m_jobDuration); + emit jobProgress(m_clipId, (int) (100.0 * progress / m_jobDuration), jobType); } } else { // Parse MLT output if (log.contains("percentage:")) { - progress = log.section(':', -1).simplified().toInt(); - return progress; + progress = log.section("percentage:", 1).simplified().section(' ', 0, 0).toInt(); + emit jobProgress(m_clipId, progress, jobType); } } - return -1; } ProxyJob::~ProxyJob() @@ -197,4 +235,21 @@ 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; +} + +#include "proxyclipjob.moc"