]> git.sesse.net Git - kdenlive/commitdiff
Fix crash in thumbnails when deleting a clip
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Sun, 4 Dec 2011 20:41:03 +0000 (21:41 +0100)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Sun, 4 Dec 2011 20:42:13 +0000 (21:42 +0100)
src/clipitem.cpp
src/clipitem.h
src/clipmanager.cpp
src/clipmanager.h
src/customtrackview.cpp
src/docclipbase.cpp
src/kthumb.cpp
src/kthumb.h
src/renderer.cpp

index 086aa7c6108a32d9a310d974bd30ea54808ce195..2c5fd7b9ab97087182d57b38f07efa3590e63a3b 100644 (file)
@@ -124,6 +124,8 @@ ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, double fps, double speed, i
 ClipItem::~ClipItem()
 {
     blockSignals(true);
+    m_endThumbTimer.stop();
+    m_startThumbTimer.stop();
     if (scene()) scene()->removeItem(this);
     if (m_clipType == VIDEO || m_clipType == AV || m_clipType == SLIDESHOW || m_clipType == PLAYLIST) {
         //disconnect(m_clip->thumbProducer(), SIGNAL(thumbReady(int, QImage)), this, SLOT(slotThumbReady(int, QImage)));
@@ -576,6 +578,13 @@ void ClipItem::slotFetchThumbs()
     if (!frames.isEmpty()) m_clip->slotExtractImage(frames);
 }
 
+void ClipItem::stopThumbs()
+{
+    // Clip is about to be deleted, make sure we don't request thumbnails
+    disconnect(&m_startThumbTimer, SIGNAL(timeout()), this, SLOT(slotGetStartThumb()));
+    disconnect(&m_endThumbTimer, SIGNAL(timeout()), this, SLOT(slotGetEndThumb()));
+}
+
 void ClipItem::slotGetStartThumb()
 {
     m_startThumbRequested = true;
index c5323905b182dc98a4dcaa76506a1c5de938f7a9..5629743fee8b328384b946f714a5a8d157c63a15 100644 (file)
@@ -173,6 +173,8 @@ public:
      * Which producer is returned depends on the type of this clip (audioonly, videoonly, normal) */
     Mlt::Producer *getProducer(int track, bool trackSpecific = true);
     void resetFrameWidth(int width);
+    /** @brief Clip is about to be deleted, block thumbs. */
+    void stopThumbs();
 
 protected:
     //virtual void mouseMoveEvent(QGraphicsSceneMouseEvent * event);
index 43aa3227ac7e84d11edf7af7040e20747675785c..dcd935a2de4650b97b6ef9d5a82be31e10cce060 100644 (file)
@@ -127,8 +127,7 @@ void ClipManager::requestThumbs(const QString id, QList <int> frames)
 
 void ClipManager::stopThumbs(const QString &id)
 {
-    if (m_closing || (m_requestedThumbs.isEmpty() && m_audioThumbsQueue.isEmpty() && m_processingAudioThumbId != id)) return;
-    
+    if (m_closing || (m_requestedThumbs.isEmpty() && m_processingThumbId != id && m_audioThumbsQueue.isEmpty() && m_processingAudioThumbId != id)) return;
     // Abort video thumbs for this clip
     m_abortThumb = true;
     m_thumbsThread.waitForFinished();
@@ -162,12 +161,12 @@ void ClipManager::slotGetThumbs()
     while (!m_requestedThumbs.isEmpty() && !m_abortThumb) {
         m_thumbsMutex.lock();
         i = m_requestedThumbs.constBegin();
-        QString producerId = i.key();
-        QList<int> values = m_requestedThumbs.values(producerId);
-        m_requestedThumbs.remove(producerId);
+        m_processingThumbId = i.key();
+        QList<int> values = m_requestedThumbs.values(m_processingThumbId);
+        m_requestedThumbs.remove(m_processingThumbId);
         m_thumbsMutex.unlock();
         qSort(values);
-        DocClipBase *clip = getClipById(producerId);
+        DocClipBase *clip = getClipById(m_processingThumbId);
         if (!clip) continue;
         max = m_requestedThumbs.size() + values.count();
         while (!values.isEmpty() && clip->thumbProducer() && !m_abortThumb) {
@@ -176,6 +175,7 @@ void ClipManager::slotGetThumbs()
             if (max > 3) emit displayMessage(i18n("Loading thumbnails"), 100 * done / max);
         }
     }
+    m_processingThumbId.clear();
     emit displayMessage(QString(), -1);
 }
 
index 169341a065e0d3e31c8ce728dcc026bbb6b9dfde..c7741b8f8f0b875f7df866209e3fa115b1c28b2c 100644 (file)
@@ -149,6 +149,8 @@ private:   // Private attributes
     QMap <QString, int> m_requestedThumbs;
     QMutex m_thumbsMutex;
     QFuture<void> m_thumbsThread;
+    /** @brief The id of currently processed clip for thumbs creation. */
+    QString m_processingThumbId;
     /** @brief If true, abort processing of clip thumbs before removing a clip. */
     bool m_abortThumb;
     /** @brief We are about to delete the clip producer, stop processing thumbs. */
index 844b1d6ecc028106d0088a52f56580833070ef95..2f56b5bf1034b25e8517082165ade88e2c4d66c9 100644 (file)
@@ -3776,10 +3776,10 @@ void CustomTrackView::deleteClip(ItemInfo info, bool refresh)
         emit displayMessage(i18n("Error removing clip at %1 on track %2", m_document->timecode().getTimecodeFromFrames(info.startPos.frames(m_document->fps())), info.track), ErrorMessage);
         kDebug()<<"CANNOT REMOVE: "<<info.startPos.frames(m_document->fps())<<", TK: "<<info.track;
         //m_document->renderer()->saveSceneList(QString("/tmp/error%1.mlt").arg(m_ct), QDomElement());
-        exit(1);
         return;
     }
     m_waitingThumbs.removeAll(item);
+    item->stopThumbs();
     if (item->isSelected()) emit clipItemSelected(NULL);
     item->baseClip()->removeReference();
     m_document->updateClip(item->baseClip()->getId());
@@ -4104,9 +4104,10 @@ void CustomTrackView::addClip(QDomElement xml, const QString &clipId, ItemInfo i
         emit displayMessage(i18n("Waiting for clip..."), InformationMessage);
         emit forceClipProcessing(clipId);
         qApp->processEvents();
-        for (int i = 0; i < 3; i++) {
+        for (int i = 0; i < 10; i++) {
             if (baseclip->getProducer() == NULL) {
-                m_producerNotReady.wait(&m_mutex, 500 + 500 * i);
+                qApp->processEvents();
+                m_producerNotReady.wait(&m_mutex, 200);
             } else break;
         }
         if (baseclip->getProducer() == NULL) {
index d5fc2db969d1c1b53f61f53bbc286c5f1470ad6b..96241c952f51b025845b259b69cf9693e69c693f 100644 (file)
@@ -99,6 +99,7 @@ DocClipBase::~DocClipBase()
 {
     m_audioTimer.stop();
     delete m_thumbProd;
+    m_thumbProd = NULL;
     qDeleteAll(m_toDeleteProducers);
     m_toDeleteProducers.clear();
     qDeleteAll(m_baseTrackProducers);
index 3ca94c6b05116e31b494b0365d1d3a4b86300598..a87f654d6ac8cf6c741218f3c390ebf9b5f62815 100644 (file)
@@ -40,7 +40,7 @@
 #include <QtConcurrentRun>
 #include <QVarLengthArray>
 
-KThumb::KThumb(ClipManager *clipManager, KUrl url, const QString &id, const QString &hash, QObject * parent, const char */*name*/) :
+KThumb::KThumb(ClipManager *clipManager, KUrl url, const QString &id, const QString &hash, QObject * parent) :
     QObject(parent),
     m_url(url),
     m_thumbFile(),
@@ -56,6 +56,7 @@ KThumb::KThumb(ClipManager *clipManager, KUrl url, const QString &id, const QStr
 KThumb::~KThumb()
 {
     if (m_producer) m_clipManager->stopThumbs(m_id);
+    m_producer = NULL;
     m_intraFramesQueue.clear();
     m_intra.waitForFinished();
 }
index b85e0779555aa873f6f32f2de0d434d9c9cb66e5..142bff41c693970eb6afc086ef0a66febc2db89b 100644 (file)
@@ -56,7 +56,7 @@ class KThumb: public QObject
 Q_OBJECT public:
 
 
-    KThumb(ClipManager *clipManager, KUrl url, const QString &id, const QString &hash, QObject * parent = 0, const char *name = 0);
+    KThumb(ClipManager *clipManager, KUrl url, const QString &id, const QString &hash, QObject * parent = 0);
     ~KThumb();
     void setProducer(Mlt::Producer *producer);
     bool hasProducer() const;
index 272acaf5ce5e7b55f04b95a38ffb360dc1198f89..72b8f46e428cb2f6a44103a9a933d83646c8d085 100644 (file)
@@ -590,6 +590,7 @@ void Render::getFileProperties(const QDomElement &xml, const QString &clipId, in
 
 void Render::forceProcessing(const QString &id)
 {
+    if (m_processingClipId == id) return;
     m_infoMutex.lock();
     for (int i = 0; i < m_requestList.count(); i++) {
         requestClipInfo info = m_requestList.at(i);