]> git.sesse.net Git - kdenlive/commitdiff
Fix crash on scene cut analysis: http://kdenlive.org/mantis/view.php?id=2873
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Sun, 16 Dec 2012 16:58:53 +0000 (17:58 +0100)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Sun, 16 Dec 2012 17:19:53 +0000 (18:19 +0100)
src/projectlist.cpp
src/projecttree/abstractclipjob.cpp
src/projecttree/abstractclipjob.h
src/projecttree/cutclipjob.cpp
src/projecttree/meltjob.cpp
src/projecttree/meltjob.h
src/projecttree/proxyclipjob.cpp

index a8e11723a0268c490bf32bb98f9d0421f39d5f07..6f9038dee99013608057b583e4357e824314cdb0 100644 (file)
@@ -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"<<filterInfo<<"\n--------------\n"<<results;
+    //kDebug()<<"// FILTER RES:\n"<<filterInfo<<"\n--------------\n"<<results;
     ProjectItem *clip = getItemById(id);
     if (!clip) return;
     // Check for return value
index b1721f80784176c3f24fbfcbb92bd8a15731f639..adf26a151673d9d846575f3a46f11bd5c6361f81 100644 (file)
@@ -30,7 +30,7 @@ AbstractClipJob::AbstractClipJob(JOBTYPE type, CLIPTYPE cType, const QString &id
         QObject(),
         clipType(cType),
         jobType(type),
-        jobStatus(NOJOB),
+        m_jobStatus(NOJOB),
         replaceClip(false),
         m_clipId(id),
         m_addClipToProject(false),
@@ -55,7 +55,12 @@ void AbstractClipJob::setAddClipToProject(bool add)
 
 void AbstractClipJob::setStatus(CLIPJOBSTATUS status)
 {
-    jobStatus = status;
+    m_jobStatus = status;
+}
+
+CLIPJOBSTATUS AbstractClipJob::status()
+{
+    return m_jobStatus;
 }
 
 const QString AbstractClipJob::clipId() const
@@ -101,3 +106,4 @@ bool AbstractClipJob::isExclusive()
     return true;
 }
 
+
index ccd862e99e26c219da79f72eef4c5c5af3ebe164..55d263a23ea8fe5030bc8a470835f826cc41ce79 100644 (file)
@@ -36,13 +36,13 @@ public:
     AbstractClipJob(JOBTYPE type, CLIPTYPE cType, const QString &id, QStringList parameters);    virtual ~ AbstractClipJob();
     CLIPTYPE clipType;
     JOBTYPE jobType;
-    CLIPJOBSTATUS jobStatus;
     QString description;
     bool replaceClip;
     const QString clipId() const;
     const QString errorMessage() const;
     const QString logDetails() const;
-    void setStatus(CLIPJOBSTATUS status);
+    CLIPJOBSTATUS status();
+    virtual void setStatus(CLIPJOBSTATUS status);
     virtual const QString destination() const;
     virtual void startJob();
     virtual stringMap cancelProperties();
@@ -54,6 +54,7 @@ public:
     void setAddClipToProject(bool add);
     
 protected:
+    CLIPJOBSTATUS m_jobStatus;
     QString m_clipId;
     QString m_errorMessage;
     QString m_logDetails;
index 9a0e624300acfe634e38b8fd8b0247f6898c623f..1635721ea541b9293577531c4514c7e7258516ed 100644 (file)
@@ -27,7 +27,7 @@
 
 CutClipJob::CutClipJob(CLIPTYPE cType, const QString &id, QStringList parameters) : AbstractClipJob(CUTJOB, cType, id, parameters)
 {
-    jobStatus = JOBWAITING;
+    m_jobStatus = JOBWAITING;
     m_dest = parameters.at(0);
     m_src = parameters.at(1);
     m_start = parameters.at(2);
@@ -66,7 +66,7 @@ void CutClipJob::startJob()
         m_jobProcess->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");
index ca49d8bfc400fd231347ee82a2b530c4cbcee335..0500bf5ea5551980dac68fc213a5272922f9b5d9 100644 (file)
 #include <mlt++/Mlt.h>
 
 
-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 <QString, QString>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 == "<playlist>" || m_url == "<tractor>" || m_url == "<producer>")
        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 <QString, QString> 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();
+}
 
 
index 41671a6bf978f88a2825b84b3bfaf6700fa884c8..abd231dd08d303c7ee499a6f87581f73b06c9757 100644 (file)
@@ -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;
index c56c367a47ecd1da5acb5d80fe29808e77c9f486..e75fd9569ed90fac0a9a2dcffbfce1fd37214aab 100644 (file)
@@ -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;