From: Jean-Baptiste Mardelle Date: Sun, 16 Dec 2012 16:58:53 +0000 (+0100) Subject: Fix crash on scene cut analysis: http://kdenlive.org/mantis/view.php?id=2873 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=512e333f83d31269142b49992a05d1aa3dec0603;p=kdenlive Fix crash on scene cut analysis: http://kdenlive.org/mantis/view.php?id=2873 --- diff --git a/src/projectlist.cpp b/src/projectlist.cpp index a8e11723..6f9038de 100644 --- a/src/projectlist.cpp +++ b/src/projectlist.cpp @@ -2947,12 +2947,12 @@ void ProjectList::slotCheckJobProcess() int count = 0; m_jobMutex.lock(); for (int i = 0; i < m_jobList.count(); i++) { - if (m_jobList.at(i)->jobStatus == JOBWORKING || m_jobList.at(i)->jobStatus == JOBWAITING) + if (m_jobList.at(i)->status() == JOBWORKING || m_jobList.at(i)->status() == JOBWAITING) count ++; else { // remove finished jobs AbstractClipJob *job = m_jobList.takeAt(i); - delete job; + job->deleteLater(); i--; } } @@ -2982,14 +2982,14 @@ void ProjectList::slotProcessJobs() int count = 0; m_jobMutex.lock(); for (int i = 0; i < m_jobList.count(); i++) { - if (m_jobList.at(i)->jobStatus == JOBWAITING) { + if (m_jobList.at(i)->status() == JOBWAITING) { if (job == NULL) { - m_jobList.at(i)->jobStatus = JOBWORKING; + m_jobList.at(i)->setStatus(JOBWORKING); job = m_jobList.at(i); } count++; } - else if (m_jobList.at(i)->jobStatus == JOBWORKING) + else if (m_jobList.at(i)->status() == JOBWORKING) count ++; } // Set jobs count @@ -3033,15 +3033,15 @@ void ProjectList::slotProcessJobs() connect(job, SIGNAL(gotFilterJobResults(QString,int, int, stringMap,stringMap)), this, SIGNAL(gotFilterJobResults(QString,int, int,stringMap,stringMap))); } job->startJob(); - if (job->jobStatus == JOBDONE) { + if (job->status() == JOBDONE) { emit updateJobStatus(job->clipId(), job->jobType, JOBDONE); //TODO: replace with more generic clip replacement framework if (job->jobType == PROXYJOB) emit gotProxy(job->clipId()); if (job->addClipToProject()) { emit addClip(destination, QString(), QString()); } - } else if (job->jobStatus == JOBCRASHED || job->jobStatus == JOBABORTED) { - emit updateJobStatus(job->clipId(), job->jobType, job->jobStatus, job->errorMessage(), QString(), job->logDetails()); + } else if (job->status() == JOBCRASHED || job->status() == JOBABORTED) { + emit updateJobStatus(job->clipId(), job->jobType, job->status(), job->errorMessage(), QString(), job->logDetails()); } } // Thread finished, cleanup & update count @@ -3345,7 +3345,7 @@ bool ProjectList::hasPendingJob(ProjectItem *item, JOBTYPE type) for (int i = 0; i < m_jobList.count(); i++) { if (m_abortAllJobs) break; job = m_jobList.at(i); - if (job->clipId() == item->clipId() && job->jobType == type && (job->jobStatus == JOBWAITING || job->jobStatus == JOBWORKING)) return true; + if (job->clipId() == item->clipId() && job->jobType == type && (job->status() == JOBWAITING || job->status() == JOBWORKING)) return true; } return false; @@ -3437,7 +3437,7 @@ QStringList ProjectList::getPendingJobs(const QString &id) QStringList result; QMutexLocker lock(&m_jobMutex); for (int i = 0; i < m_jobList.count(); i++) { - if (m_jobList.at(i)->clipId() == id && (m_jobList.at(i)->jobStatus == JOBWAITING || m_jobList.at(i)->jobStatus == JOBWORKING)) { + if (m_jobList.at(i)->clipId() == id && (m_jobList.at(i)->status() == JOBWAITING || m_jobList.at(i)->status() == JOBWORKING)) { // discard this job result << m_jobList.at(i)->description; } @@ -3652,7 +3652,7 @@ void ProjectList::slotClosePopup() void ProjectList::slotGotFilterJobResults(QString id, int , int , stringMap results, stringMap filterInfo) { // Currently, only the first value of results is used - kDebug()<<"// FILTER RES:\n"<waitForStarted(); while (m_jobProcess->state() != QProcess::NotRunning) { processLogInfo(); - if (jobStatus == JOBABORTED) { + if (m_jobStatus == JOBABORTED) { m_jobProcess->close(); m_jobProcess->waitForFinished(); QFile::remove(m_dest); @@ -74,7 +74,7 @@ void CutClipJob::startJob() m_jobProcess->waitForFinished(400); } - if (jobStatus != JOBABORTED) { + if (m_jobStatus != JOBABORTED) { int result = m_jobProcess->exitStatus(); if (result == QProcess::NormalExit) { if (QFileInfo(m_dest).size() == 0) { @@ -102,7 +102,7 @@ void CutClipJob::startJob() void CutClipJob::processLogInfo() { - if (!m_jobProcess || m_jobDuration == 0 || jobStatus == JOBABORTED) return; + if (!m_jobProcess || m_jobDuration == 0 || m_jobStatus == JOBABORTED) return; QString log = m_jobProcess->readAll(); if (!log.isEmpty()) m_logDetails.append(log + '\n'); int progress; @@ -140,7 +140,7 @@ stringMap CutClipJob::cancelProperties() const QString CutClipJob::statusMessage() { QString statusInfo; - switch (jobStatus) { + switch (m_jobStatus) { case JOBWORKING: if (m_start.isEmpty()) statusInfo = i18n("Transcoding clip"); else statusInfo = i18n("Extracting clip cut"); diff --git a/src/projecttree/meltjob.cpp b/src/projecttree/meltjob.cpp index ca49d8bf..0500bf5e 100644 --- a/src/projecttree/meltjob.cpp +++ b/src/projecttree/meltjob.cpp @@ -29,22 +29,20 @@ #include -static void consumer_frame_render(mlt_consumer, MeltJob * self, mlt_frame /*frame_ptr*/) +static void consumer_frame_render(mlt_consumer, MeltJob * self, mlt_frame frame_ptr) { // detect if the producer has finished playing. Is there a better way to do it? - self->emitFrameNumber(); + Mlt::Frame frame(frame_ptr); + self->emitFrameNumber((int) frame.get_position()); } MeltJob::MeltJob(CLIPTYPE cType, const QString &id, QStringList parameters, QMap extraParams) : AbstractClipJob(MLTJOB, cType, id, parameters), addClipToProject(0), - m_producer(NULL), - m_profile(NULL), m_consumer(NULL), - m_showFrameEvent(NULL), m_length(0), m_extra(extraParams) { - jobStatus = JOBWAITING; + m_jobStatus = JOBWAITING; m_params = parameters; description = i18n("Process clip"); QString consum = m_params.at(5); @@ -53,15 +51,14 @@ MeltJob::MeltJob(CLIPTYPE cType, const QString &id, QStringList parameters, QMa void MeltJob::setProducer(Mlt::Producer *producer, KUrl url) { - m_producer = producer; - m_url = QString::fromUtf8(m_producer->get("resource")); + m_url = QString::fromUtf8(producer->get("resource")); if (m_url == "" || m_url == "" || m_url == "") m_url == url.path(); } void MeltJob::startJob() { - if (!m_producer) { + if (m_url.isEmpty()) { m_errorMessage.append(i18n("No producer for this clip.")); setStatus(JOBCRASHED); return; @@ -168,26 +165,27 @@ void MeltJob::startJob() prod->set_speed(0); prod->seek(0); prod->attach(mltFilter); - m_showFrameEvent = m_consumer->listen("consumer-frame-show", this, (mlt_listener) consumer_frame_render); - m_consumer->start(); + Mlt::Event *showFrameEvent = m_consumer->listen("consumer-frame-show", this, (mlt_listener) consumer_frame_render); prod->set_speed(1); - while (jobStatus != JOBABORTED && !m_consumer->is_stopped()) { - - } - m_consumer->stop(); + + m_consumer->run(); QMap jobResults; - if (m_extra.contains("key")) - jobResults.insert(m_extra.value("key"), mltFilter.get(m_extra.value("key").toUtf8().constData())); - if (!jobResults.isEmpty() && jobStatus != JOBABORTED) emit gotFilterJobResults(m_clipId, startPos, track, jobResults, m_extra); + if (m_jobStatus != JOBABORTED && m_extra.contains("key")) { + QString result = mltFilter.get(m_extra.value("key").toUtf8().constData()); + jobResults.insert(m_extra.value("key"), result); + } setStatus(JOBDONE); - delete m_consumer; delete prod; + delete showFrameEvent; + if (!jobResults.isEmpty() && m_jobStatus != JOBABORTED) emit gotFilterJobResults(m_clipId, startPos, track, jobResults, m_extra); return; } MeltJob::~MeltJob() { + delete m_consumer; + delete m_profile; } const QString MeltJob::destination() const @@ -204,7 +202,7 @@ stringMap MeltJob::cancelProperties() const QString MeltJob::statusMessage() { QString statusInfo; - switch (jobStatus) { + switch (m_jobStatus) { case JOBWORKING: statusInfo = description; break; @@ -217,10 +215,10 @@ const QString MeltJob::statusMessage() return statusInfo; } -void MeltJob::emitFrameNumber() +void MeltJob::emitFrameNumber(int pos) { - if (m_consumer && m_length > 0) { - emit jobProgress(m_clipId, (int) (100 * m_consumer->position() / m_length), jobType); + if (m_length > 0) { + emit jobProgress(m_clipId, (int) (100 * pos / m_length), jobType); } } @@ -229,5 +227,10 @@ bool MeltJob::isProjectFilter() const return m_extra.contains("projecttreefilter"); } +void MeltJob::setStatus(CLIPJOBSTATUS status) +{ + m_jobStatus = status; + if (status == JOBABORTED && m_consumer) m_consumer->stop(); +} diff --git a/src/projecttree/meltjob.h b/src/projecttree/meltjob.h index 41671a6b..abd231dd 100644 --- a/src/projecttree/meltjob.h +++ b/src/projecttree/meltjob.h @@ -48,16 +48,15 @@ public: stringMap cancelProperties(); bool addClipToProject; const QString statusMessage(); + void setStatus(CLIPJOBSTATUS status); void setProducer(Mlt::Producer *producer, KUrl url); - void emitFrameNumber(); + void emitFrameNumber(int pos); /** Make the job work on a project tree clip. */ bool isProjectFilter() const; private: - Mlt::Producer *m_producer; - Mlt::Profile *m_profile; Mlt::Consumer *m_consumer; - Mlt::Event *m_showFrameEvent; + Mlt::Profile *m_profile; QStringList m_params; QString m_dest; QString m_url; diff --git a/src/projecttree/proxyclipjob.cpp b/src/projecttree/proxyclipjob.cpp index c56c367a..e75fd956 100644 --- a/src/projecttree/proxyclipjob.cpp +++ b/src/projecttree/proxyclipjob.cpp @@ -29,7 +29,7 @@ ProxyJob::ProxyJob(CLIPTYPE cType, const QString &id, QStringList parameters) : m_jobDuration(0), m_isFfmpegJob(true) { - jobStatus = JOBWAITING; + m_jobStatus = JOBWAITING; description = i18n("proxy"); m_dest = parameters.at(0); m_src = parameters.at(1); @@ -145,7 +145,7 @@ void ProxyJob::startJob() } while (m_jobProcess->state() != QProcess::NotRunning) { processLogInfo(); - if (jobStatus == JOBABORTED) { + if (m_jobStatus == JOBABORTED) { emit cancelRunningJob(m_clipId, cancelProperties()); m_jobProcess->close(); m_jobProcess->waitForFinished(); @@ -154,7 +154,7 @@ void ProxyJob::startJob() m_jobProcess->waitForFinished(400); } - if (jobStatus != JOBABORTED) { + if (m_jobStatus != JOBABORTED) { int result = m_jobProcess->exitStatus(); if (result == QProcess::NormalExit) { if (QFileInfo(m_dest).size() == 0) { @@ -178,7 +178,7 @@ void ProxyJob::startJob() void ProxyJob::processLogInfo() { - if (!m_jobProcess || jobStatus == JOBABORTED) return; + if (!m_jobProcess || m_jobStatus == JOBABORTED) return; QString log = m_jobProcess->readAll(); if (!log.isEmpty()) m_logDetails.append(log + '\n'); else return; @@ -230,7 +230,7 @@ stringMap ProxyJob::cancelProperties() const QString ProxyJob::statusMessage() { QString statusInfo; - switch (jobStatus) { + switch (m_jobStatus) { case JOBWORKING: statusInfo = i18n("Creating proxy"); break;